/* queue the xml command in root from the given device to each * interested client, except notme */ static void send2Clients (ClInfo *notme, XMLEle *root, char *dev) { ClInfo *cp; Msg *mp; /* build a new message */ mp = (Msg *) mymalloc (sizeof(Msg)); mp->ep = root; mp->count = 0; /* lock access to client info */ pthread_mutex_lock (&client_m); /* queue message to each interested client */ for (cp = clinfo; cp < &clinfo[nclinfo]; cp++) { int isblob; /* cp ok? notme? valid dev? blob? */ if (!cp->active || cp == notme) continue; if (findClDevice (cp, dev) < 0) continue; isblob = !strcmp (tagXMLEle(root), "setBLOBVector"); if ((isblob && cp->blob==B_NEVER) || (!isblob && cp->blob==B_ONLY)) continue; /* ok: queue message to given client */ mp->count++; pushFQ (cp->msgq, mp); } /* wake up client write threads, the last of which will free the Msg */ if (mp->count > 0) pthread_cond_broadcast(&client_c); else { if (verbose > 2) fprintf (stderr, "no clients want %s\n", xmlLog(root)); freeMsg (mp); /* no interested clients, free Msg now */ } /* finished with client info */ pthread_mutex_unlock (&client_m); }
/* add the given device and property to the devs[] list of client if new. */ void addClDevice (ClInfo *cp, const char *dev, const char *name, int isblob) { Property *pp; //char *ip; int i=0; if (isblob) { for (i = 0; i < cp->nprops; i++) { Property *pp = &cp->props[i]; if (!strcmp (pp->dev, dev) && (name==NULL || !strcmp(pp->name, name))) return; } } /* no dups */ else if (!findClDevice (cp, dev, name)) return; /* add */ cp->props = (Property *) realloc (cp->props, (cp->nprops+1)*sizeof(Property)); pp = &cp->props[cp->nprops++]; /*ip = pp->dev; strncpy (ip, dev, MAXINDIDEVICE-1); ip[MAXINDIDEVICE-1] = '\0'; ip = pp->name; strncpy (ip, name, MAXINDINAME-1); ip[MAXINDINAME-1] = '\0';*/ strncpy (pp->dev, dev, MAXINDIDEVICE); strncpy (pp->name, name, MAXINDINAME); pp->blob = B_NEVER; }
/* put Msg mp on queue of each client interested in dev/name, except notme. * if BLOB always honor current mode. * return -1 if had to shut down any clients, else 0. */ int q2Clients (ClInfo *notme, int isblob, const char *dev, const char *name, Msg *mp, XMLEle *root) { int shutany = 0; ClInfo *cp; int ql,i=0; /* queue message to each interested client */ for (cp = clinfo; cp < &clinfo[nclinfo]; cp++) { /* cp in use? notme? want this dev/name? blob? */ if (!cp->active || cp == notme) continue; if (findClDevice (cp, dev, name) < 0) continue; //if ((isblob && cp->blob==B_NEVER) || (!isblob && cp->blob==B_ONLY)) if (!isblob && cp->blob==B_ONLY) continue; if (isblob) { if (cp->nprops > 0) { Property *pp = NULL; int blob_found=0; for (i = 0; i < cp->nprops; i++) { pp = &cp->props[i]; if (!strcmp (pp->dev, dev) && (!strcmp(pp->name, name))) { blob_found = 1; break; } } if ( (blob_found && pp->blob == B_NEVER) || (blob_found==0 && cp->blob == B_NEVER) ) continue; } else if (cp->blob == B_NEVER) continue; } /* shut down this client if its q is already too large */ ql = msgQSize(cp->msgq); if (ql > maxqsiz) { if (verbose) fprintf (stderr, "%s: Client %d: %d bytes behind, shutting down\n", indi_tstamp(NULL), cp->s, ql); shutdownClient (cp); shutany++; continue; } /* ok: queue message to this client */ mp->count++; pushFQ (cp->msgq, mp); if (verbose > 1) fprintf (stderr, "%s: Client %d: queuing <%s device='%s' name='%s'>\n", indi_tstamp(NULL), cp->s, tagXMLEle(root), findXMLAttValu (root, "device"), findXMLAttValu (root, "name")); } return (shutany ? -1 : 0); }