static void* mevent_start_base_entry(void *arg) { int rv; struct timespec ts; struct queue_entry *q; struct event_entry *e = (struct event_entry*)arg; int *mypos = _tls_get_mypos(); *mypos = e->cur_thread; mtc_dbg("I'm %s %dnd thread", e->name, *mypos); for (;;) { /* Condition waits are specified with absolute timeouts, see * pthread_cond_timedwait()'s SUSv3 specification for more * information. We need to calculate it each time. * We sleep for 1 sec. There's no real need for it to be too * fast (it's only used so that stop detection doesn't take * long), but we don't want it to be too slow either. */ mutil_utc_time(&ts); ts.tv_sec += 1; rv = 0; queue_lock(e->op_queue[*mypos]); while (queue_isempty(e->op_queue[*mypos]) && rv == 0) { rv = queue_timedwait(e->op_queue[*mypos], &ts); } if (rv != 0 && rv != ETIMEDOUT) { errlog("Error in queue_timedwait()"); /* When the timedwait fails the lock is released, so * we need to properly annotate this case. */ __release(e->op_queue[*mypos]->lock); continue; } q = queue_get(e->op_queue[*mypos]); queue_unlock(e->op_queue[*mypos]); if (q == NULL) { if (e->loop_should_stop) { break; } else { continue; } } mtc_dbg("%s %d process", e->name, *mypos); e->process_driver(e, q, *mypos); /* Free the entry that was allocated when tipc queued the * operation. This also frees it's components. */ queue_entry_free(q); } return NULL; }
/* Create a queue entry structure based on the parameters passed. Memory * allocated here will be free()'d in queue_entry_free(). It's not the * cleanest way, but the alternatives are even messier. */ static struct queue_entry *make_queue_long_entry(const struct req_info *req, uint32_t operation, const unsigned char *key, size_t ksize, const unsigned char *val, size_t vsize, const unsigned char *newval, size_t nvsize) { struct queue_entry *e; unsigned char *kcopy, *vcopy, *nvcopy; e = queue_entry_create(); if (e == NULL) { return NULL; } kcopy = vcopy = nvcopy = NULL; if (key != NULL) { kcopy = malloc(ksize); if (kcopy == NULL) goto error; memcpy(kcopy, key, ksize); } if (val != NULL) { vcopy = malloc(vsize); if (vcopy == NULL) goto error; memcpy(vcopy, val, vsize); } if (newval != NULL) { nvcopy = malloc(nvsize); if (nvcopy == NULL) goto error; memcpy(nvcopy, newval, nvsize); } e->operation = operation; e->key = kcopy; e->ksize = ksize; e->val = vcopy; e->vsize = vsize; e->newval = nvcopy; e->nvsize = nvsize; /* Create a copy of req, including clisa */ e->req = malloc(sizeof(struct req_info)); if (e->req == NULL) { queue_entry_free(e); return NULL; } memcpy(e->req, req, sizeof(struct req_info)); e->req->clisa = malloc(req->clilen); if (e->req->clisa == NULL) { queue_entry_free(e); return NULL; } memcpy(e->req->clisa, req->clisa, req->clilen); /* clear out unused fields */ e->req->payload = NULL; e->req->psize = 0; return e; error: queue_entry_free(e); free(kcopy); free(vcopy); free(nvcopy); return NULL; }