struct evcenter * event_init(int size) { int status, ep; struct kevent *event; struct fired_event *fired_events; struct evcenter *center; center = nc_zalloc(sizeof(struct evcenter)); if (center == NULL) { log_error("center create failed: %s", strerror(errno)); return NULL; } ep = kqueue(); if (ep < 0) { nc_free(center); log_error("kqueue create failed: %s", strerror(errno)); return NULL; } event = nc_calloc(size, sizeof(struct kevent)); fired_events = nc_calloc(size, sizeof(struct fired_event)); if (event == NULL || fired_events == NULL) { status = close(ep); nc_free(center); if (event != NULL) nc_free(event); if (fired_events != NULL) nc_free(fired_events); if (status < 0) { log_error("close e %d failed, ignored: %s", ep, strerror(errno)); } return NULL; } center->ep = ep; center->event = event; center->nevent = size; center->fired_events = fired_events; log_debug(LOG_INFO, "e %d with nevent %d", center->ep, center->nevent); return center; }
/* * read the comment in proto/nc_redis.c */ static rstatus_t memcache_fragment_retrieval(struct msg *r, uint32_t ncontinuum, struct msg_tqh *frag_msgq, uint32_t key_step) { struct mbuf *mbuf; struct msg **sub_msgs; uint32_t i; rstatus_t status; sub_msgs = nc_zalloc(ncontinuum * sizeof(*sub_msgs)); if (sub_msgs == NULL) { return NC_ENOMEM; } ASSERT(r->frag_seq == NULL); r->frag_seq = nc_alloc(array_n(r->keys) * sizeof(*r->frag_seq)); if (r->frag_seq == NULL) { nc_free(sub_msgs); return NC_ENOMEM; } mbuf = STAILQ_FIRST(&r->mhdr); mbuf->pos = mbuf->start; /* * This code is based on the assumption that 'gets ' is located * in a contiguous location. * This is always true because we have capped our MBUF_MIN_SIZE at 512 and * whenever we have multiple messages, we copy the tail message into a new mbuf */ for (; *(mbuf->pos) != ' ';) { /* eat get/gets */ mbuf->pos++; } mbuf->pos++; r->frag_id = msg_gen_frag_id(); r->nfrag = 0; r->frag_owner = r; for (i = 0; i < array_n(r->keys); i++) { /* for each key */ struct msg *sub_msg; struct keypos *kpos = array_get(r->keys, i); uint32_t idx = msg_backend_idx(r, kpos->start, kpos->end - kpos->start); if (sub_msgs[idx] == NULL) { sub_msgs[idx] = msg_get(r->owner, r->request, r->redis); if (sub_msgs[idx] == NULL) { nc_free(sub_msgs); return NC_ENOMEM; } } r->frag_seq[i] = sub_msg = sub_msgs[idx]; sub_msg->narg++; status = memcache_append_key(sub_msg, kpos->start, kpos->end - kpos->start); if (status != NC_OK) { nc_free(sub_msgs); return status; } } for (i = 0; i < ncontinuum; i++) { /* prepend mget header, and forward it */ struct msg *sub_msg = sub_msgs[i]; if (sub_msg == NULL) { continue; } /* prepend get/gets */ if (r->type == MSG_REQ_MC_GET) { status = msg_prepend(sub_msg, (uint8_t *)"get ", 4); } else if (r->type == MSG_REQ_MC_GETS) { status = msg_prepend(sub_msg, (uint8_t *)"gets ", 5); } if (status != NC_OK) { nc_free(sub_msgs); return status; } /* append \r\n */ status = msg_append(sub_msg, (uint8_t *)CRLF, CRLF_LEN); if (status != NC_OK) { nc_free(sub_msgs); return status; } sub_msg->type = r->type; sub_msg->frag_id = r->frag_id; sub_msg->frag_owner = r->frag_owner; TAILQ_INSERT_TAIL(frag_msgq, sub_msg, m_tqe); r->nfrag++; } nc_free(sub_msgs); return NC_OK; }