static void msg_handler(grn_ctx *ctx, grn_obj *msg) { uint32_t etime; struct timeval tv; grn_msg *m = (grn_msg *)msg; grn_com *com = ((grn_msg *)msg)->peer; session *s = com->opaque; s->stat = 3; gettimeofday(&tv, NULL); etime = (tv.tv_sec - s->tv.tv_sec) * 1000000 + (tv.tv_usec - s->tv.tv_usec); if (etime > etime_max) { etime_max = etime; } if (etime < etime_min) { etime_min = etime; } if (ctx->rc) { m->header.proto = 0; } switch (m->header.proto) { case GRN_COM_PROTO_GQTP : if (GRN_BULK_VSIZE(msg) == 2) { etime_amount += etime; } else { if (verbose) { GRN_TEXT_PUTC(ctx, msg, '\0'); lprint(ctx, "%8d(%4d) %8d : %s", s->query_id, s->n_sessions, etime, GRN_BULK_HEAD(msg)); } } if ((m->header.flags & GRN_CTX_TAIL)) { grn_com_queue_enque(ctx, &fsessions, (grn_com_queue_entry *)s); nrecv++; } break; case GRN_COM_PROTO_HTTP : nrecv++; /* lprint(ctx, "recv: %d, %d", (int)GRN_BULK_VSIZE(msg), nrecv); */ grn_com_close_(ctx, com); grn_com_queue_enque(ctx, &fsessions, (grn_com_queue_entry *)s); break; default : grn_com_close_(ctx, com); grn_com_queue_enque(ctx, &fsessions, (grn_com_queue_entry *)s); break; } grn_msg_close(ctx, msg); }
grn_rc grn_msg_close(grn_ctx *ctx, grn_obj *obj) { grn_msg *msg = (grn_msg *)obj; if (ctx == msg->ctx) { return grn_obj_close(ctx, obj); } return grn_com_queue_enque(ctx, msg->old, (grn_com_queue_entry *)msg); }
grn_rc grn_msg_send(grn_ctx *ctx, grn_obj *msg, int flags) { grn_rc rc; grn_msg *m = (grn_msg *)msg; grn_com *peer = m->u.peer; grn_com_header *header = &m->header; if (GRN_COM_QUEUE_EMPTYP(&peer->new_)) { switch (header->proto) { case GRN_COM_PROTO_HTTP : { ssize_t ret; ret = send(peer->fd, GRN_BULK_HEAD(msg), GRN_BULK_VSIZE(msg), MSG_NOSIGNAL); if (ret == -1) { SOERR("send"); } if (ctx->rc != GRN_OPERATION_WOULD_BLOCK) { grn_com_queue_enque(ctx, m->old, (grn_com_queue_entry *)msg); return ctx->rc; } } break; case GRN_COM_PROTO_GQTP : { if ((flags & GRN_CTX_MORE)) { flags |= GRN_CTX_QUIET; } if (ctx->stat == GRN_CTX_QUIT) { flags |= GRN_CTX_QUIT; } header->qtype = (uint8_t) ctx->impl->output.type; header->keylen = 0; header->level = 0; header->flags = flags; header->status = htons((uint16_t)ctx->rc); header->opaque = 0; header->cas = 0; //todo : MSG_DONTWAIT rc = grn_com_send(ctx, peer, header, GRN_BULK_HEAD(msg), GRN_BULK_VSIZE(msg), 0); if (rc != GRN_OPERATION_WOULD_BLOCK) { grn_com_queue_enque(ctx, m->old, (grn_com_queue_entry *)msg); return rc; } } break; case GRN_COM_PROTO_MBREQ : return GRN_FUNCTION_NOT_IMPLEMENTED; case GRN_COM_PROTO_MBRES : rc = grn_com_send(ctx, peer, header, GRN_BULK_HEAD(msg), GRN_BULK_VSIZE(msg), (flags & GRN_CTX_MORE) ? MSG_MORE :0); if (rc != GRN_OPERATION_WOULD_BLOCK) { grn_com_queue_enque(ctx, m->old, (grn_com_queue_entry *)msg); return rc; } break; default : return GRN_INVALID_ARGUMENT; } } MUTEX_LOCK(peer->ev->mutex); rc = grn_com_queue_enque(ctx, &peer->new_, (grn_com_queue_entry *)msg); COND_SIGNAL(peer->ev->cond); MUTEX_UNLOCK(peer->ev->mutex); return rc; }