From 08453374b2c58813201739bf4e69383235804a29 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 10 Apr 2015 16:05:38 -0700 Subject: Introduce ahead-of-time registration of (method,host) pairs --- src/core/surface/channel.c | 81 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c index e764a3b9af..adc339d479 100644 --- a/src/core/surface/channel.c +++ b/src/core/surface/channel.c @@ -43,6 +43,12 @@ #include #include +typedef struct registered_call { + grpc_mdelem *path; + grpc_mdelem *authority; + struct registered_call *next; +} registered_call; + struct grpc_channel { int is_client; gpr_refcount refs; @@ -51,6 +57,9 @@ struct grpc_channel { grpc_mdstr *grpc_message_string; grpc_mdstr *path_string; grpc_mdstr *authority_string; + + gpr_mu registered_call_mu; + registered_call *registered_calls; }; #define CHANNEL_STACK_FROM_CHANNEL(c) ((grpc_channel_stack *)((c)+1)) @@ -75,18 +84,17 @@ grpc_channel *grpc_channel_create_from_filters( channel->authority_string = grpc_mdstr_from_string(mdctx, ":authority"); grpc_channel_stack_init(filters, num_filters, args, channel->metadata_context, CHANNEL_STACK_FROM_CHANNEL(channel)); + gpr_mu_init(&channel->registered_call_mu); + channel->registered_calls = NULL; return channel; } static void do_nothing(void *ignored, grpc_op_error error) {} -grpc_call *grpc_channel_create_call(grpc_channel *channel, - grpc_completion_queue *cq, - const char *method, const char *host, - gpr_timespec absolute_deadline) { +static grpc_call *grpc_channel_create_call_internal( + grpc_channel *channel, grpc_completion_queue *cq, + grpc_mdelem *path_mdelem, grpc_mdelem *authority_mdelem, gpr_timespec deadline) { grpc_call *call; - grpc_mdelem *path_mdelem; - grpc_mdelem *authority_mdelem; grpc_call_op op; if (!channel->is_client) { @@ -97,11 +105,6 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel, call = grpc_call_create(channel, cq, NULL); /* Add :path and :authority headers. */ - /* TODO(klempner): Consider optimizing this by stashing mdelems for common - values of method and host. */ - path_mdelem = grpc_mdelem_from_metadata_strings( - channel->metadata_context, grpc_mdstr_ref(channel->path_string), - grpc_mdstr_from_string(channel->metadata_context, method)); op.type = GRPC_SEND_METADATA; op.dir = GRPC_CALL_DOWN; op.flags = 0; @@ -110,18 +113,14 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel, op.user_data = NULL; grpc_call_execute_op(call, &op); - grpc_mdstr_ref(channel->authority_string); - authority_mdelem = grpc_mdelem_from_metadata_strings( - channel->metadata_context, channel->authority_string, - grpc_mdstr_from_string(channel->metadata_context, host)); op.data.metadata = authority_mdelem; grpc_call_execute_op(call, &op); - if (0 != gpr_time_cmp(absolute_deadline, gpr_inf_future)) { + if (0 != gpr_time_cmp(deadline, gpr_inf_future)) { op.type = GRPC_SEND_DEADLINE; op.dir = GRPC_CALL_DOWN; op.flags = 0; - op.data.deadline = absolute_deadline; + op.data.deadline = deadline; op.done_cb = do_nothing; op.user_data = NULL; grpc_call_execute_op(call, &op); @@ -130,6 +129,22 @@ grpc_call *grpc_channel_create_call(grpc_channel *channel, return call; } +grpc_call *grpc_channel_create_call(grpc_channel *channel, + grpc_completion_queue *cq, + const char *method, const char *host, + gpr_timespec deadline) { + return grpc_channel_create_call_internal( + channel, + cq, + grpc_mdelem_from_metadata_strings( + channel->metadata_context, grpc_mdstr_ref(channel->path_string), + grpc_mdstr_from_string(channel->metadata_context, method)), + grpc_mdelem_from_metadata_strings( + channel->metadata_context, grpc_mdstr_ref(channel->authority_string), + grpc_mdstr_from_string(channel->metadata_context, host)), + deadline); +} + grpc_call *grpc_channel_create_call_old(grpc_channel *channel, const char *method, const char *host, gpr_timespec absolute_deadline) { @@ -137,6 +152,30 @@ grpc_call *grpc_channel_create_call_old(grpc_channel *channel, absolute_deadline); } +void *grpc_channel_register_call(grpc_channel *channel, const char *method, + const char *host) { + registered_call *rc = gpr_malloc(sizeof(registered_call)); + rc->path = grpc_mdelem_from_metadata_strings( + channel->metadata_context, grpc_mdstr_ref(channel->path_string), + grpc_mdstr_from_string(channel->metadata_context, method)); + rc->authority = grpc_mdelem_from_metadata_strings( + channel->metadata_context, grpc_mdstr_ref(channel->authority_string), + grpc_mdstr_from_string(channel->metadata_context, host)); + gpr_mu_lock(&channel->registered_call_mu); + rc->next = channel->registered_calls; + channel->registered_calls = rc; + gpr_mu_unlock(&channel->registered_call_mu); + return rc; +} + +grpc_call *grpc_channel_create_registered_call(grpc_channel *channel, + grpc_completion_queue *completion_queue, + void *registered_call_handle, + gpr_timespec deadline) { + registered_call *rc = registered_call_handle; + return grpc_channel_create_call_internal(channel, completion_queue, grpc_mdelem_ref(rc->path), grpc_mdelem_ref(rc->authority), deadline); +} + void grpc_channel_internal_ref(grpc_channel *channel) { gpr_ref(&channel->refs); } @@ -148,7 +187,15 @@ static void destroy_channel(void *p, int ok) { grpc_mdstr_unref(channel->grpc_message_string); grpc_mdstr_unref(channel->path_string); grpc_mdstr_unref(channel->authority_string); + while (channel->registered_calls) { + registered_call *rc = channel->registered_calls; + channel->registered_calls = rc->next; + grpc_mdelem_unref(rc->path); + grpc_mdelem_unref(rc->authority); + gpr_free(rc); + } grpc_mdctx_unref(channel->metadata_context); + gpr_mu_destroy(&channel->registered_call_mu); gpr_free(channel); } -- cgit v1.2.3