예제 #1
0
/* close down the given client */
void
shutdownClient (ClInfo *cp)
{
	Msg *mp;

	/* close connection */
	shutdown (cp->s, SHUT_RDWR);
	close (cp->s);

	/* free memory */
	delLilXML (cp->lp);
	free (cp->props);

	/* decrement and possibly free any unsent messages for this client */
	while ((mp = (Msg*) popFQ(cp->msgq)) != NULL)
	    if (--mp->count == 0)
		freeMsg (mp);
	delFQ (cp->msgq);

	/* ok now to recycle */
	cp->active = 0;

	if (verbose > 0)
	    fprintf (stderr, "%s: Client %d: shut down complete - bye!\n",
							indi_tstamp(NULL), cp->s);
#ifdef OSX_EMBEDED_MODE
  int active = 0;
  for (int i = 0; i < nclinfo; i++)
    if (clinfo[i].active)
      active++;
  fprintf(stderr, "CLIENTS %d\n", active); fflush(stderr);
#endif
}
예제 #2
0
/* write the next chunk of the current message in the queue to the given
 * driver. pop message from queue when complete and free the message if we are
 * the last one to use it. restart this driver if touble.
 * N.B. we assume we will never be called with dp->msgq empty.
 * return 0 if ok else -1 if had to shut down.
 */
int
sendDriverMsg (DvrInfo *dp)
{
	ssize_t nsend, nw;
	Msg *mp;

	/* get current message */
	mp = (Msg *) peekFQ (dp->msgq);

	/* send next chunk, never more than MAXWSIZ to reduce blocking */
	nsend = mp->cl - dp->nsent;
	if (nsend > MAXWSIZ)
	    nsend = MAXWSIZ;
	nw = write (dp->wfd, &mp->cp[dp->nsent], nsend);

	/* restart if trouble */
	if (nw <= 0) {
	    if (nw == 0)
		fprintf (stderr, "%s: Driver %s: write returned 0\n",
						    indi_tstamp(NULL), dp->name);
	    else
		fprintf (stderr, "%s: Driver %s: write: %s\n", indi_tstamp(NULL),
						    dp->name, strerror(errno));
            shutdownDvr (dp, 1);
	    return (-1);
	}

	/* trace */
	if (verbose > 2) {
	    fprintf(stderr, "%s: Driver %s: sending msg copy %d nq %d:\n%.*s\n",
			    indi_tstamp(NULL), dp->name, mp->count, nFQ(dp->msgq),
			    (int)nw, &mp->cp[dp->nsent]);
	} else if (verbose > 1) {
	    fprintf(stderr, "%s: Driver %s: sending %.50s\n", indi_tstamp(NULL),
						dp->name, &mp->cp[dp->nsent]);
	}

	/* update amount sent. when complete: free message if we are the last
	 * to use it and pop from our queue.
	 */
	dp->nsent += nw;
	if (dp->nsent == mp->cl) {
	    if (--mp->count == 0)
		freeMsg (mp);
	    popFQ (dp->msgq);
	    dp->nsent = 0;
	}

	return (0);
}
예제 #3
0
/* write the next chunk of the current message in the queue to the given
 * client. pop message from queue when complete and free the message if we are
 * the last one to use it. shut down this client if trouble.
 * N.B. we assume we will never be called with cp->msgq empty.
 * return 0 if ok else -1 if had to shut down.
 */
int
sendClientMsg (ClInfo *cp)
{
	ssize_t nsend, nw;
	Msg *mp;

	/* get current message */
	mp = (Msg *) peekFQ (cp->msgq);

	/* send next chunk, never more than MAXWSIZ to reduce blocking */
	nsend = mp->cl - cp->nsent;
	if (nsend > MAXWSIZ)
	    nsend = MAXWSIZ;
	nw = write (cp->s, &mp->cp[cp->nsent], nsend);

	/* shut down if trouble */
	if (nw <= 0) {
	    if (nw == 0)
		fprintf (stderr, "%s: Client %d: write returned 0\n",
						    indi_tstamp(NULL), cp->s);
	    else
		fprintf (stderr, "%s: Client %d: write: %s\n", indi_tstamp(NULL),
						    cp->s, strerror(errno));
	    shutdownClient (cp);
	    return (-1);
	}

	/* trace */
	if (verbose > 2) {
	    fprintf(stderr, "%s: Client %d: sending msg copy %d nq %d:\n%.*s\n",
				indi_tstamp(NULL), cp->s, mp->count, nFQ(cp->msgq),
				(int)nw, &mp->cp[cp->nsent]);
	} else if (verbose > 1) {
	    fprintf(stderr, "%s: Client %d: sending %.50s\n", indi_tstamp(NULL),
						    cp->s, &mp->cp[cp->nsent]);
	}

	/* update amount sent. when complete: free message if we are the last
	 * to use it and pop from our queue.
	 */
	cp->nsent += nw;
	if (cp->nsent == mp->cl) {
	    if (--mp->count == 0)
		freeMsg (mp);
	    popFQ (cp->msgq);
	    cp->nsent = 0;
	}

	return (0);
}
예제 #4
0
/* close down the given driver and restart */
void
shutdownDvr (DvrInfo *dp, int restart)
{
	Msg *mp;

	/* make sure it's dead, reclaim resources */
	if (dp->pid == REMOTEDVR) {
	    /* socket connection */
	    shutdown (dp->wfd, SHUT_RDWR);
	    close (dp->wfd);	/* same as rfd */
	} else {
	    /* local pipe connection */
            kill (dp->pid, SIGKILL);	/* we've insured there are no zombies */
	    close (dp->wfd);
	    close (dp->rfd);
	    close (dp->efd);
	}

#ifdef OSX_EMBEDED_MODE
  fprintf(stderr, "STOPPED \"%s\"\n", dp->name); fflush(stderr);
#endif

	/* free memory */
	free (dp->sprops);
    free(dp->dev);
	delLilXML (dp->lp);

   /* ok now to recycle */
   dp->active = 0;
   dp->ndev = 0;

	/* decrement and possibly free any unsent messages for this client */
	while ((mp = (Msg*) popFQ(dp->msgq)) != NULL)
	    if (--mp->count == 0)
		freeMsg (mp);
	delFQ (dp->msgq);

        if (restart)
        {
            fprintf (stderr, "%s: Driver %s: restart #%d\n", indi_tstamp(NULL),
                                                    dp->name, ++dp->restarts);
            startDvr (dp);
        }

}
예제 #5
0
/* this function is the thread to perform all writes to client carg.
 * return with client closed when we have problems or when shutdown flag is set.
 * N.B. coordinate all access to clinfo via client_m/c.
 * N.B. clinfo can move (be realloced) when unlocked so beware pointers thereto.
 */
static void *
clientWThread(void *carg)
{
	int c = (int)carg;
	ClInfo *cp;
	Msg *mp;

	/* start off wanting exclusive access to client info */
	pthread_mutex_lock (&client_m);

	/* loop until told to shut down or get write error */
	while (1) {

	    /* check for message or shutdown, unlock while waiting */
	    while (nFQ(clinfo[c].msgq) == 0 && !clinfo[c].shutdown) {
		if (verbose > 2)
		    fprintf (stderr,"Client %d: thread sleeping\n",clinfo[c].s);
		pthread_cond_wait (&client_c, &client_m);
		if (verbose > 2)
		    fprintf (stderr, "Client %d: thread awake\n", clinfo[c].s);
	    }
	    if (clinfo[c].shutdown)
		break;

	    /* get next message for this client */
	    mp = popFQ (clinfo[c].msgq);

	    /* unlock client info while writing */
	    pthread_mutex_unlock (&client_m);
	    prXMLEle (clinfo[c].wfp, mp->ep, 0);
	    pthread_mutex_lock (&client_m);

	    /* trace */
	    cp = &clinfo[c];		/* ok to use pointer while locked */
	    if (verbose > 2) {
		fprintf (stderr, "Client %d: send:\n", cp->s);
		prXMLEle (stderr, mp->ep, 0);
	    } else if (verbose > 1)
		fprintf (stderr, "Client %d: send %s\n", cp->s, xmlLog(mp->ep));

	    /* update message usage count, free if goes to 0 */
	    if (--mp->count == 0)
		freeMsg (mp);

	    /* exit this thread if encountered write errors */
	    if (ferror(cp->wfp)) {
		fprintf (stderr, "Client %d: %s\n", cp->s, strerror(errno));
		break;
	    }
	}

	/* close down this client */
	cp = &clinfo[c];		/* ok to use pointer while locked */
	fclose (cp->wfp);		/* also closes cp->s */
	delLilXML (cp->lp);
	myfree (cp->devs);

	/* decrement and possibly free any unsent messages for this client */
	while ((mp = (Msg*) popFQ(cp->msgq)) != NULL)
	    if (--mp->count == 0)
		freeMsg (mp);
	delFQ (cp->msgq);

	/* this thread is now finished with client info */
	pthread_mutex_unlock (&client_m);

	/* exit thread */
	return (0);
}