Exemplo n.º 1
0
/* return size of all Msqs on the given q */
int
msgQSize (FQ *q)
{
	int i, l = 0;

	for (i = 0; i < nFQ(q); i++) {
	    Msg *mp = (Msg *) peekiFQ(q,i);
	    l += mp->cl;
	}

	return (l);
}
Exemplo n.º 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);
}
Exemplo n.º 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);
}
Exemplo n.º 4
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);
}
Exemplo n.º 5
0
/* service traffic from clients and drivers */
void
indiRun(void)
{
	fd_set rs, ws;
        int maxfd=0;
	int i, s;

	/* init with no writers or readers */
	FD_ZERO(&ws);
	FD_ZERO(&rs);

        if (fifo.name && fifo.fd >=0)
        {
           FD_SET(fifo.fd, &rs);
           maxfd = fifo.fd;
        }

	/* always listen for new clients */
	FD_SET(lsocket, &rs);
        if (lsocket > maxfd)
                maxfd = lsocket;

	/* add all client readers and client writers with work to send */
	for (i = 0; i < nclinfo; i++) {
	    ClInfo *cp = &clinfo[i];
	    if (cp->active) {
		FD_SET(cp->s, &rs);
		if (nFQ(cp->msgq) > 0)
		    FD_SET(cp->s, &ws);
		if (cp->s > maxfd)
		    maxfd = cp->s;
	    }
	}

	/* add all driver readers and driver writers with work to send */
        for (i = 0; i < ndvrinfo; i++)
        {
	    DvrInfo *dp = &dvrinfo[i];
            if (dp->active)
            {
                FD_SET(dp->rfd, &rs);
                if (dp->rfd > maxfd)
                   maxfd = dp->rfd;
                if (dp->pid != REMOTEDVR)
                {
                   FD_SET(dp->efd, &rs);
                   if (dp->efd > maxfd)
                      maxfd = dp->efd;
                }
                if (nFQ(dp->msgq) > 0)
                {
                   FD_SET(dp->wfd, &ws);
                   if (dp->wfd > maxfd)
                       maxfd = dp->wfd;
                }
            }
	}

	/* wait for action */
	s = select (maxfd+1, &rs, &ws, NULL, NULL);
	if (s < 0) {
	    fprintf (stderr, "%s: select(%d): %s\n", indi_tstamp(NULL), maxfd+1,
							    strerror(errno));
	    Bye();
	}


        /* new command from FIFO? */
        if (s > 0 && fifo.fd >= 0 && FD_ISSET(fifo.fd, &rs))
        {
            newFIFO();
            s--;
        }

	/* new client? */
	if (s > 0 && FD_ISSET(lsocket, &rs)) {
	    newClient();
	    s--;
	}

	/* message to/from client? */
	for (i = 0; s > 0 && i < nclinfo; i++) {
	    ClInfo *cp = &clinfo[i];
	    if (cp->active) {
		if (FD_ISSET(cp->s, &rs)) {
		    if (readFromClient(cp) < 0)
			return;	/* fds effected */
		    s--;
		}
		if (s > 0 && FD_ISSET(cp->s, &ws)) {
		    if (sendClientMsg(cp) < 0)
			return;	/* fds effected */
		    s--;
		}
	    }
	}

	/* message to/from driver? */
	for (i = 0; s > 0 && i < ndvrinfo; i++) {
	    DvrInfo *dp = &dvrinfo[i];
	    if (dp->pid != REMOTEDVR && FD_ISSET(dp->efd, &rs)) {
		if (stderrFromDriver(dp) < 0)
		    return;	/* fds effected */
		s--;
	    }
	    if (s > 0 && FD_ISSET(dp->rfd, &rs)) {
        if (readFromDriver(dp) < 0)
            return;	/* fds effected */
		s--;
	    }
	    if (s > 0 && FD_ISSET(dp->wfd, &ws) && nFQ(dp->msgq) > 0) {
        if (sendDriverMsg(dp) < 0)
           return;	/* fds effected */
		s--;
	    }
	}
}