static BOOL SaveState(FILE *fp, QDPLUS_DIGITIZER *digitizer) { QDP_LC *lc; LNKLST_NODE *crnt; /* write out digitizer serial number */ if (fwrite(&digitizer->serialno, sizeof(UINT64), 1, fp) != 1) return FALSE; /* write out each active HLP */ crnt = listFirstNode(digitizer->lcq.lc); while (crnt != NULL) { lc = (QDP_LC *) crnt->payload; if (lc->hlp != NULL && lc->hlp->nsamp != 0) { if (!isiWriteSeqno(fp, &lc->hlp->seqno)) return FALSE; if (fwrite(lc->hlp->chn, QDP_CNAME_LEN+1, 1, fp) != 1) return FALSE; if (fwrite(lc->hlp->loc, QDP_LNAME_LEN+1, 1, fp) != 1) return FALSE; if (fwrite(&lc->hlp->offset, sizeof(INT32), 1, fp) != 1) return FALSE; } crnt = listNextNode(crnt); } /* flag end of list with undefined sequence number */ if (!isiWriteSeqno(fp, &ISI_UNDEFINED_SEQNO)) return FALSE; return TRUE; }
BOOL qdplusSaveState(QDPLUS *handle) { FILE *fp; LNKLST_NODE *crnt; UINT16 dirty = QDPLUS_FLAG_DIRTY; UINT16 clean = QDPLUS_FLAG_CLEAN; QDPLUS_DIGITIZER *digitizer; if ((fp = OpenStateFile(handle, "wb", NULL)) == NULL) return FALSE; if (fwrite(&dirty, sizeof(UINT16), 1, fp) != 1) { fclose(fp); return FALSE; } fflush(fp); crnt = listFirstNode(handle->list.digitizer); while (crnt != NULL) { if (!SaveState(fp, (QDPLUS_DIGITIZER *) crnt->payload)) { fclose(fp); return FALSE; } crnt = listNextNode(crnt); } rewind(fp); if (fwrite(&clean, sizeof(UINT16), 1, fp) != 1) { fclose(fp); return FALSE; } fclose(fp); return TRUE; }
void qdplusPrintState(FILE *fp, QDPLUS *handle) { LNKLST_NODE *crnt; QDPLUS_DIGITIZER *digitizer; if (fp == NULL || handle == NULL) return; if (handle->par.path.state != NULL) { fprintf(fp, "%s\n", handle->par.path.state); } else { fprintf(fp, "qdplusPrintState called with NULL par.path.state!\n"); } if ((crnt = listFirstNode(handle->list.digitizer)) == NULL) { fprintf(fp, "empty file\n"); return; } while (crnt != NULL) { digitizer = (QDPLUS_DIGITIZER *) crnt->payload; fprintf(fp, "S/N %016llX\n", digitizer->serialno); PrintState(fp, digitizer->state); crnt = listNextNode(crnt); } fflush(fp); }
void printttglist() { char msg[101]; LNKLST_NODE *node; printf("\nDATA GAP INFO\n"); node = listFirstNode(messageList); if(node==NULL) { printf("\nNo gaps found\n"); } else { memset(msg,' ', 101);msg[99]='\n';msg[100]=0; memcpy(msg,"Stream",6); memcpy(&msg[40],"Gap",3); memcpy(&msg[80],"Length",6); printf(msg); } while (node != NULL) { printf((char *)node->payload); node = listNextNode(node); } DeleteLists(); }
/* get data for socket / fd being monitored. Create if not found*/ aeSockState *aeGetSockState(void *apistate, int fd) { int sindex; listNode *node; list *socklist; aeSockState *sockState; if (apistate == NULL) return NULL; sindex = aeSocketIndex(fd); socklist = &(((aeApiState *)apistate)->lookup[sindex]); node = listFirst(socklist); while (node != NULL) { sockState = (aeSockState *)listNodeValue(node); if (sockState->fd == fd) { return sockState; } node = listNextNode(node); } // not found. Do lazy create of sockState. sockState = (aeSockState *) zmalloc(sizeof(aeSockState)); if (sockState != NULL) { sockState->fd = fd; sockState->masks = 0; sockState->wreqs = 0; sockState->reqs = NULL; memset(&sockState->wreqlist, 0, sizeof(sockState->wreqlist)); memset(&sockState->remoteAddress, 0, sizeof(sockState->remoteAddress)); if (listAddNodeHead(socklist, sockState) != NULL) { return sockState; } else { zfree(sockState); } } return NULL; }
static void WalkData(QDP_LCQ *lcq) { QDP_LC *lc; LNKLST_NODE *crnt; crnt = listFirstNode(lcq->lc); while (crnt != NULL) { lc = (QDP_LC *) crnt->payload; PrintLC(lcq, lc); crnt = listNextNode(crnt); } }
static void trigger_thread(void *args) { SetThreadName("JSRT Trigger"); for(;;) { list_node_t *node; pthread_mutex_lock(&jsrt_mutex); for(node=listFirstNode(&rt_list); node; node=listNextNode(node)) JS_TriggerAllOperationCallbacks(node->data); pthread_mutex_unlock(&jsrt_mutex); SLEEP(100); } }
// find matching value in list and remove. If found return 1 int removeMatchFromList(list *socklist, void *value) { listNode *node; if (socklist == NULL) return 0; node = listFirst(socklist); while (node != NULL) { if (listNodeValue(node) == value) { listDelNode(socklist, node); return 1; } node = listNextNode(node); } return 0; }
/* Find matching value in list and remove. If found return TRUE */ BOOL removeMatchFromList(list *requestlist, void *value) { listNode *node; if (requestlist == NULL) { return FALSE; } node = listFirst(requestlist); while (node != NULL) { if (listNodeValue(node) == value) { listDelNode(requestlist, node); return TRUE; } node = listNextNode(node); } return FALSE; }
int utilFlushAllBufferedStream() { UINT32 count = 0; LNKLST_NODE *crnt; BufferedStream *p; crnt = listFirstNode(&list); while (crnt != NULL) { p = (BufferedStream *)crnt->payload; utilFlushBuffer(p); crnt = listNextNode(crnt); } return 0; }
static void StateSeqnoLimits(QDPLUS_DIGITIZER *digitizer, ISI_SEQNO *beg, ISI_SEQNO *end) { LNKLST_NODE *crnt; QDPLUS_STATE *state; crnt = listFirstNode(digitizer->state); while (crnt != NULL) { state = (QDPLUS_STATE *) crnt->payload; if (isiIsUndefinedSeqno(beg)) *beg = state->seqno; if (isiIsUndefinedSeqno(end)) *end = state->seqno; if (isiSeqnoLT(&state->seqno, beg)) *beg = state->seqno; if (isiSeqnoGT(&state->seqno, end)) *end = state->seqno; crnt = listNextNode(crnt); } }
static void PrintState(FILE *fp, LNKLST *head) { LNKLST_NODE *crnt; QDPLUS_STATE *state; if (fp == NULL || state == NULL) return; crnt = listFirstNode(head); while (crnt != NULL) { state = (QDPLUS_STATE *) crnt->payload; fprintf(fp, "%3s", state->chn); fprintf(fp, " %2s", state->loc); fprintf(fp, " %08lx%016llx", state->seqno.signature, state->seqno.counter); fprintf(fp, " %ld", state->offset); fprintf(fp, "\n"); crnt = listNextNode(crnt); } }
/* get data for socket / fd being monitored */ aeSockState *aeGetExistingSockState(void *apistate, int fd) { int sindex; listNode *node; list *socklist; aeSockState *sockState; if (apistate == NULL) return NULL; sindex = aeSocketIndex(fd); socklist = &(((aeApiState *)apistate)->lookup[sindex]); node = listFirst(socklist); while (node != NULL) { sockState = (aeSockState *)listNodeValue(node); if (sockState->fd == fd) { return sockState; } node = listNextNode(node); } return NULL; }
BufferedStream *utilOpenBufferedStream(char *pFileName) { int nLen; BufferedStream *p; BufferedStream obf; UINT32 count = 0; LNKLST_NODE *crnt; crnt = listFirstNode(&list); while (crnt != NULL) { p = (BufferedStream *)crnt->payload; if(strcmp(p->cFileName, pFileName)==0) { return p; } crnt = listNextNode(crnt); } nLen = strlen(pFileName); if(nLen<sizeof(obf.cFileName)-1) STRCPY(obf.cFileName, pFileName); else { strncpy(obf.cFileName, pFileName, sizeof(obf.cFileName)-1); obf.cFileName[sizeof(obf.cFileName)-1]=0; } obf.nBytes=0; obf.nTotalBytes=0; if(listAppend(&list, &obf, sizeof(obf))) { crnt = listLastNode(&list); p = (BufferedStream *)crnt->payload; return p; } return NULL; }
int ispSendChnLocMap(int sd, char *buffer, IDA *ida, int to) { LNKLST_NODE *crnt; IDA_CHNLOCMAP *entry; int msglen, status; if (ida == NULL) return ISP_OK; if (ida->chnlocmap == NULL) return ISP_OK; msglen = EncodeChnLocMapName(buffer+4, ida); status = isp_send(sd, ISP_CHNMAP, buffer, msglen, to); if (status != ISP_OK) return status; crnt = listFirstNode(ida->chnlocmap); while (crnt != NULL) { entry = (IDA_CHNLOCMAP *) crnt->payload; status = SendChnLocMapEntry(sd, buffer, entry, to); if (status != ISP_OK) return status; crnt = listNextNode(crnt); } return ISP_OK; }
BOOL qdplusStateSeqnoLimits(QDPLUS *handle, ISI_SEQNO *beg, ISI_SEQNO *end) { LNKLST_NODE *crnt; QDPLUS_DIGITIZER *digitizer; if (handle == NULL || beg == NULL || end == NULL) { errno = EINVAL; return FALSE; } *beg = ISI_UNDEFINED_SEQNO; *end = ISI_UNDEFINED_SEQNO; if ((crnt = listFirstNode(handle->list.digitizer)) == NULL) return TRUE; while (crnt != NULL) { digitizer = (QDPLUS_DIGITIZER *) crnt->payload; StateSeqnoLimits(digitizer, beg, end); crnt = listNextNode(crnt); } return TRUE; }
BOOL qdpBuildHLP(QDP_LCQ *lcq) { QDP_LC *lc; LNKLST_NODE *crnt; static char *fid = "qdpBuildHLP"; if (!lcq->par.rules.valid) { qdpLcqWarn(lcq, "%s: WARNING: unexpected invalid rules! Logic error? (sn=%016llX, addr=%08x)", fid, lcq->meta.combo.fix.sys_num, &lcq->par.rules); return TRUE; } crnt = listFirstNode(lcq->lc); while (crnt != NULL) { lc = (QDP_LC *) crnt->payload; if (lc->hlp == NULL) { qdpLcqError(lcq, "%s: ERROR: unexpected NULL hlp!\n", fid); return FALSE; } if (lc->state == QDP_LC_STATE_FULL && !BuildHLP(lcq, lc)) return FALSE; crnt = listNextNode(crnt); } return TRUE; }
static stream_t *getStream(int nstream) { stream_t stt, *pstt; LNKLST_NODE *node; node = listFirstNode(streamList); while (node != NULL) { pstt = node->payload; if(pstt->nstream==nstream) break; node = listNextNode(node); } if(node==NULL) { stt.t = 0.; stt.nstream = nstream; listAppend(streamList, &stt, sizeof(stt)); node = listLastNode(streamList); } return (stream_t *)node->payload; }
/* return array of sockets that are ready for read or write depending on the mask for each socket */ static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) { aeApiState *state = (aeApiState *)eventLoop->apidata; aeSockState *sockstate; ULONG j; int numevents = 0; ULONG numComplete = 0; int rc; int mswait = (tvp == NULL) ? 100 : (tvp->tv_sec * 1000) + (tvp->tv_usec / 1000); if (pGetQueuedCompletionStatusEx != NULL) { /* first get an array of completion notifications */ rc = pGetQueuedCompletionStatusEx(state->iocp, state->entries, MAX_COMPLETE_PER_POLL, &numComplete, mswait, FALSE); } else { /* need to get one at a time. Use first array element */ rc = GetQueuedCompletionStatus(state->iocp, &state->entries[0].dwNumberOfBytesTransferred, &state->entries[0].lpCompletionKey, &state->entries[0].lpOverlapped, mswait); if (!rc && state->entries[0].lpOverlapped == NULL) { // timeout. Return. return 0; } else { // check if more completions are ready int lrc = 1; rc = 1; numComplete = 1; while (numComplete < MAX_COMPLETE_PER_POLL) { lrc = GetQueuedCompletionStatus(state->iocp, &state->entries[numComplete].dwNumberOfBytesTransferred, &state->entries[numComplete].lpCompletionKey, &state->entries[numComplete].lpOverlapped, 0); if (lrc) { numComplete++; } else { if (state->entries[numComplete].lpOverlapped == NULL) break; } } } } if (rc && numComplete > 0) { LPOVERLAPPED_ENTRY entry = state->entries; for (j = 0; j < numComplete && numevents < state->setsize; j++, entry++) { /* the competion key is the socket */ int rfd = (int)entry->lpCompletionKey; sockstate = aeGetExistingSockState(state, rfd); if (sockstate != NULL) { if ((sockstate->masks & LISTEN_SOCK) && entry->lpOverlapped != NULL) { /* need to set event for listening */ aacceptreq *areq = (aacceptreq *)entry->lpOverlapped; areq->next = sockstate->reqs; sockstate->reqs = areq; sockstate->masks &= ~ACCEPT_PENDING; if (sockstate->masks & AE_READABLE) { eventLoop->fired[numevents].fd = rfd; eventLoop->fired[numevents].mask = AE_READABLE; numevents++; } } else if (sockstate->masks & CONNECT_PENDING) { /* check if connect complete */ if (entry->lpOverlapped == &sockstate->ov_read) { sockstate->masks &= ~CONNECT_PENDING; /* enable read and write events for this connection */ aeApiAddEvent(eventLoop, rfd, sockstate->masks); } } else { int matched = 0; /* check if event is read complete (may be 0 length read) */ if (entry->lpOverlapped == &sockstate->ov_read) { matched = 1; sockstate->masks &= ~READ_QUEUED; if (sockstate->masks & AE_READABLE) { eventLoop->fired[numevents].fd = rfd; eventLoop->fired[numevents].mask = AE_READABLE; numevents++; } } else if (sockstate->wreqs > 0 && entry->lpOverlapped != NULL) { /* should be write complete. Get results */ asendreq *areq = (asendreq *)entry->lpOverlapped; matched = removeMatchFromList(&sockstate->wreqlist, areq); if (matched) { /* call write complete callback so buffers can be freed */ if (areq->proc != NULL) { DWORD written = 0; DWORD flags; WSAGetOverlappedResult(rfd, &areq->ov, &written, FALSE, &flags); areq->proc(areq->eventLoop, rfd, &areq->req, (int)written); } sockstate->wreqs--; zfree(areq); /* if no active write requests, set ready to write */ if (sockstate->wreqs == 0 && sockstate->masks & AE_WRITABLE) { eventLoop->fired[numevents].fd = rfd; eventLoop->fired[numevents].mask = AE_WRITABLE; numevents++; } } } if (matched == 0) { /* redisLog */printf("Sec:%lld Unknown complete (closed) on %d\n", gettimeofdaysecs(NULL), rfd); sockstate = NULL; } } } else { // no match for active connection. // Try the closing list. list *socklist = &(state->closing); listNode *node; node = listFirst(socklist); while (node != NULL) { sockstate = (aeSockState *)listNodeValue(node); if (sockstate->fd == rfd) { if (sockstate->masks & CONNECT_PENDING) { /* check if connect complete */ if (entry->lpOverlapped == &sockstate->ov_read) { sockstate->masks &= ~CONNECT_PENDING; } } else if (entry->lpOverlapped == &sockstate->ov_read) { // read complete sockstate->masks &= ~READ_QUEUED; } else { // check pending writes asendreq *areq = (asendreq *)entry->lpOverlapped; if (removeMatchFromList(&sockstate->wreqlist, areq)) { sockstate->wreqs--; zfree(areq); } } if (sockstate->wreqs == 0 && (sockstate->masks & (CONNECT_PENDING | READ_QUEUED | SOCKET_ATTACHED)) == 0) { if ((sockstate->masks & CLOSE_PENDING) != 0) { close(rfd); sockstate->masks &= ~(CLOSE_PENDING); } // safe to delete sockstate aeDelSockState(state, sockstate); } break; } node = listNextNode(node); } } } } return numevents; }
void sendReplyToClientWritev(aeEventLoop *el, int fd, void *privdata, int mask) { redisClient *c = privdata; int nwritten = 0, totwritten = 0, objlen, willwrite; robj *o; struct iovec iov[REDIS_WRITEV_IOVEC_COUNT]; int offset, ion = 0; REDIS_NOTUSED(el); REDIS_NOTUSED(mask); listNode *node; while (listLength(c->reply)) { offset = c->sentlen; ion = 0; willwrite = 0; /* fill-in the iov[] array */ for(node = listFirst(c->reply); node; node = listNextNode(node)) { o = listNodeValue(node); objlen = sdslen(o->ptr); if (totwritten + objlen - offset > REDIS_MAX_WRITE_PER_EVENT) break; if(ion == REDIS_WRITEV_IOVEC_COUNT) break; /* no more iovecs */ iov[ion].iov_base = ((char*)o->ptr) + offset; iov[ion].iov_len = objlen - offset; willwrite += objlen - offset; offset = 0; /* just for the first item */ ion++; } if(willwrite == 0) break; /* write all collected blocks at once */ if((nwritten = writev(fd, iov, ion)) < 0) { if (errno != EAGAIN) { redisLog(REDIS_VERBOSE, "Error writing to client: %s", strerror(errno)); freeClient(c); return; } break; } totwritten += nwritten; offset = c->sentlen; /* remove written robjs from c->reply */ while (nwritten && listLength(c->reply)) { o = listNodeValue(listFirst(c->reply)); objlen = sdslen(o->ptr); if(nwritten >= objlen - offset) { listDelNode(c->reply, listFirst(c->reply)); nwritten -= objlen - offset; c->sentlen = 0; } else { /* partial write */ c->sentlen += nwritten; break; } offset = 0; } } if (totwritten > 0) c->lastinteraction = time(NULL); if (listLength(c->reply) == 0) { c->sentlen = 0; aeDeleteFileEvent(server.el,c->fd,AE_WRITABLE); } }
/* This command implements SCAN, HSCAN and SSCAN commands. * If object 'o' is passed, then it must be a Hash or Set object, otherwise * if 'o' is NULL the command will operate on the dictionary associated with * the current database. * * When 'o' is not NULL the function assumes that the first argument in * the client arguments vector is a key so it skips it before iterating * in order to parse options. * * In the case of a Hash object the function returns both the field and value * of every element on the Hash. */ void scanGenericCommand(client *c, robj *o, unsigned long cursor) { int i, j; list *keys = listCreate(); listNode *node, *nextnode; long count = 10; sds pat = NULL; int patlen = 0, use_pattern = 0; dict *ht; /* Object must be NULL (to iterate keys names), or the type of the object * must be Set, Sorted Set, or Hash. */ serverAssert(o == NULL || o->type == OBJ_SET || o->type == OBJ_HASH || o->type == OBJ_ZSET); /* Set i to the first option argument. The previous one is the cursor. */ i = (o == NULL) ? 2 : 3; /* Skip the key argument if needed. */ /* Step 1: Parse options. */ while (i < c->argc) { j = c->argc - i; if (!strcasecmp(c->argv[i]->ptr, "count") && j >= 2) { if (getLongFromObjectOrReply(c, c->argv[i+1], &count, NULL) != C_OK) { goto cleanup; } if (count < 1) { addReply(c,shared.syntaxerr); goto cleanup; } i += 2; } else if (!strcasecmp(c->argv[i]->ptr, "match") && j >= 2) { pat = c->argv[i+1]->ptr; patlen = sdslen(pat); /* The pattern always matches if it is exactly "*", so it is * equivalent to disabling it. */ use_pattern = !(pat[0] == '*' && patlen == 1); i += 2; } else { addReply(c,shared.syntaxerr); goto cleanup; } } /* Step 2: Iterate the collection. * * Note that if the object is encoded with a ziplist, intset, or any other * representation that is not a hash table, we are sure that it is also * composed of a small number of elements. So to avoid taking state we * just return everything inside the object in a single call, setting the * cursor to zero to signal the end of the iteration. */ /* Handle the case of a hash table. */ ht = NULL; if (o == NULL) { ht = c->db->dict; } else if (o->type == OBJ_SET && o->encoding == OBJ_ENCODING_HT) { ht = o->ptr; } else if (o->type == OBJ_HASH && o->encoding == OBJ_ENCODING_HT) { ht = o->ptr; count *= 2; /* We return key / value for this type. */ } else if (o->type == OBJ_ZSET && o->encoding == OBJ_ENCODING_SKIPLIST) { zset *zs = o->ptr; ht = zs->dict; count *= 2; /* We return key / value for this type. */ } if (ht) { void *privdata[2]; /* We set the max number of iterations to ten times the specified * COUNT, so if the hash table is in a pathological state (very * sparsely populated) we avoid to block too much time at the cost * of returning no or very few elements. */ long maxiterations = count*10; /* We pass two pointers to the callback: the list to which it will * add new elements, and the object containing the dictionary so that * it is possible to fetch more data in a type-dependent way. */ privdata[0] = keys; privdata[1] = o; do { cursor = dictScan(ht, cursor, scanCallback, privdata); } while (cursor && maxiterations-- && listLength(keys) < (unsigned long)count); } else if (o->type == OBJ_SET) { int pos = 0; int64_t ll; while(intsetGet(o->ptr,pos++,&ll)) listAddNodeTail(keys,createStringObjectFromLongLong(ll)); cursor = 0; } else if (o->type == OBJ_HASH || o->type == OBJ_ZSET) { unsigned char *p = ziplistIndex(o->ptr,0); unsigned char *vstr; unsigned int vlen; long long vll; while(p) { ziplistGet(p,&vstr,&vlen,&vll); listAddNodeTail(keys, (vstr != NULL) ? createStringObject((char*)vstr,vlen) : createStringObjectFromLongLong(vll)); p = ziplistNext(o->ptr,p); } cursor = 0; } else { serverPanic("Not handled encoding in SCAN."); } /* Step 3: Filter elements. */ node = listFirst(keys); while (node) { robj *kobj = listNodeValue(node); nextnode = listNextNode(node); int filter = 0; /* Filter element if it does not match the pattern. */ if (!filter && use_pattern) { if (sdsEncodedObject(kobj)) { if (!stringmatchlen(pat, patlen, kobj->ptr, sdslen(kobj->ptr), 0)) filter = 1; } else { char buf[LONG_STR_SIZE]; int len; serverAssert(kobj->encoding == OBJ_ENCODING_INT); len = ll2string(buf,sizeof(buf),(long)kobj->ptr); if (!stringmatchlen(pat, patlen, buf, len, 0)) filter = 1; } } /* Filter element if it is an expired key. */ if (!filter && o == NULL && expireIfNeeded(c->db, kobj)) filter = 1; /* Remove the element and its associted value if needed. */ if (filter) { decrRefCount(kobj); listDelNode(keys, node); } /* If this is a hash or a sorted set, we have a flat list of * key-value elements, so if this element was filtered, remove the * value, or skip it if it was not filtered: we only match keys. */ if (o && (o->type == OBJ_ZSET || o->type == OBJ_HASH)) { node = nextnode; nextnode = listNextNode(node); if (filter) { kobj = listNodeValue(node); decrRefCount(kobj); listDelNode(keys, node); } } node = nextnode; } /* Step 4: Reply to the client. */ addReplyMultiBulkLen(c, 2); addReplyBulkLongLong(c,cursor); addReplyMultiBulkLen(c, listLength(keys)); while ((node = listFirst(keys)) != NULL) { robj *kobj = listNodeValue(node); addReplyBulk(c, kobj); decrRefCount(kobj); listDelNode(keys, node); } cleanup: listSetFreeMethod(keys,decrRefCountVoid); listRelease(keys); }