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; }
static int do_client() { int rc = -1; char *buf; grn_thread thread; struct timeval tvb, tve; grn_com_header sheader; grn_ctx ctx_, *ctx = &ctx_; grn_ctx_init(ctx, 0); GRN_COM_QUEUE_INIT(&fsessions); sessions = grn_hash_create(ctx, NULL, sizeof(grn_sock), sizeof(session), 0); sheader.proto = GRN_COM_PROTO_GQTP; sheader.qtype = 0; sheader.keylen = 0; sheader.level = 0; sheader.flags = 0; sheader.status = 0; sheader.opaque = 0; sheader.cas = 0; if ((buf = GRN_MALLOC(BUFSIZE))) { if (!grn_com_event_init(ctx, &ev, 1000, sizeof(grn_com))) { ev.msg_handler = msg_handler; if (!THREAD_CREATE(thread, receiver, NULL)) { int cnt = 0; gettimeofday(&tvb, NULL); lprint(ctx, "begin: max_concurrency=%d max_tp=%d", max_con, max_tp); while (fgets(buf, BUFSIZE, stdin)) { uint32_t size = strlen(buf) - 1; session *s = session_alloc(ctx, dests + (cnt++ % dest_cnt)); if (s) { gettimeofday(&s->tv, NULL); s->n_query++; s->query_id = ++nsent; s->n_sessions = (nsent - nrecv); switch (proto) { case 'H' : case 'h' : if (grn_com_send_text(ctx, s->com, buf, size, 0)) { fprintf(stderr, "grn_com_send_text failed\n"); } s->stat = 2; /* lprint(ctx, "sent %04d %04d %d", s->n_query, s->query_id, s->com->fd); */ break; default : if (grn_com_send(ctx, s->com, &sheader, buf, size, 0)) { fprintf(stderr, "grn_com_send failed\n"); } break; } } else { fprintf(stderr, "grn_com_copen failed\n"); } for (;;) { gettimeofday(&tve, NULL); if ((nrecv < max_tp * (tve.tv_sec - tvb.tv_sec)) && (nsent - nrecv) < max_con) { break; } /* lprint(ctx, "s:%d r:%d", nsent, nrecv); */ usleep(1000); } if (!(nsent % 1000)) { lprint(ctx, " : %d", nsent); } } done = 1; pthread_join(thread, NULL); gettimeofday(&tve, NULL); { double qps; uint64_t etime = (tve.tv_sec - tvb.tv_sec); etime *= 1000000; etime += (tve.tv_usec - tvb.tv_usec); qps = (double)nsent * 1000000 / etime; lprint(ctx, "end : n=%d min=%d max=%d avg=%d qps=%f etime=%d.%06d", nsent, etime_min, etime_max, (int)(etime_amount / nsent), qps, etime / 1000000, etime % 1000000); } { session *s; GRN_HASH_EACH(ctx, sessions, id, NULL, NULL, &s, { session_close(ctx, s); }); } rc = 0; } else {