From f5f1712e1fcca1beb555ca9ea783a9c98b9b1a64 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 25 Jun 2015 08:47:26 -0700 Subject: Refactoring progress towards integrating client configs --- src/core/channel/client_channel.c | 134 +++++++++++++++++++++++++++++++------- 1 file changed, 111 insertions(+), 23 deletions(-) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index 726196e996..ea79d539ec 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -36,7 +36,6 @@ #include #include "src/core/channel/channel_args.h" -#include "src/core/channel/child_channel.h" #include "src/core/channel/connected_channel.h" #include "src/core/iomgr/iomgr.h" #include "src/core/iomgr/pollset_set.h" @@ -51,26 +50,25 @@ typedef struct call_data call_data; typedef struct { - /* protects children, child_count, child_capacity, active_child, - transport_setup_initiated - does not protect channel stacks held by children - transport_setup is assumed to be set once during construction */ - gpr_mu mu; - - /* the sending child (may be null) */ - grpc_child_channel *active_child; + /** metadata context for this channel */ grpc_mdctx *mdctx; + /** resolver for this channel */ + grpc_resolver *resolver; + /** channel arguments for this channel + TODO(ctiller): still needed? */ + grpc_channel_args *args; - /* calls waiting for a channel to be ready */ - call_data **waiting_children; - size_t waiting_child_count; - size_t waiting_child_capacity; + /** mutex protecting waiting list */ + gpr_mu mu_waiting; + /** mutex protecting client configuration, resolution state */ + gpr_mu mu_config; - /* transport setup for this channel */ - grpc_transport_setup *transport_setup; - int transport_setup_initiated; + /** currently active load balancer - guarded by mu_config */ + grpc_lb_policy *lb_policy; - grpc_channel_args *args; + /** incoming configuration - set by resolver.next + guarded by mu_config */ + grpc_client_config *incoming_configuration; } channel_data; typedef enum { @@ -84,12 +82,14 @@ struct call_data { /* owning element */ grpc_call_element *elem; + gpr_mu mu_state; + call_state state; gpr_timespec deadline; union { struct { /* our child call stack */ - grpc_child_call *child_call; + grpc_subchannel_call *subchannel_call; } active; grpc_transport_op waiting_op; struct { @@ -99,6 +99,7 @@ struct call_data { } s; }; +#if 0 static int prepare_activate(grpc_call_element *elem, grpc_child_channel *on_child) { call_data *calld = elem->call_data; @@ -150,6 +151,7 @@ static void remove_waiting_child(channel_data *chand, call_data *calld) { new_count == chand->waiting_child_count); chand->waiting_child_count = new_count; } +#endif static void handle_op_after_cancellation(grpc_call_element *elem, grpc_transport_op *op) { @@ -183,15 +185,99 @@ static void handle_op_after_cancellation(grpc_call_element *elem, } } +static void add_to_lb_policy_wait_queue_locked_state_config(channel_data *chand, call_data *calld) { + abort(); +} + +static void pick_target(grpc_lb_policy *lb_policy, call_data *calld) { + abort(); +} + static void cc_start_transport_op(grpc_call_element *elem, grpc_transport_op *op) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; - grpc_call_element *child_elem; + grpc_subchannel_call *subchannel_call; + grpc_lb_policy *lb_policy; grpc_transport_op waiting_op; GPR_ASSERT(elem->filter == &grpc_client_channel_filter); GRPC_CALL_LOG_OP(GPR_INFO, elem, op); + gpr_mu_lock(&calld->mu_state); + switch (calld->state) { + case CALL_ACTIVE: + subchannel_call = calld->s.active.subchannel_call; + grpc_subchannel_call_ref(subchannel_call); + gpr_mu_unlock(&calld->mu_state); + grpc_subchannel_call_process_op(subchannel_call, op); + grpc_subchannel_call_unref(subchannel_call); + break; + case CALL_CANCELLED: + gpr_mu_unlock(&calld->mu_state); + handle_op_after_cancellation(elem, op); + break; + case CALL_CREATED: + if (op->cancel_with_status != GRPC_STATUS_OK) { + calld->state = CALL_CANCELLED; + gpr_mu_unlock(&calld->mu_state); + handle_op_after_cancellation(elem, op); + } else { + calld->state = CALL_WAITING; + calld->s.waiting_op = *op; + + gpr_mu_lock(&chand->mu_config); + lb_policy = chand->lb_policy; + if (lb_policy) { + grpc_lb_policy_ref(lb_policy); + gpr_mu_unlock(&chand->mu_config); + gpr_mu_unlock(&calld->mu_state); + + pick_target(lb_policy, calld); + + grpc_lb_policy_unref(lb_policy); + } else { + add_to_lb_policy_wait_queue_locked_state_config(chand, calld); + gpr_mu_unlock(&chand->mu_config); + gpr_mu_unlock(&calld->mu_state); + } + } + break; + case CALL_WAITING: + if (op->cancel_with_status != GRPC_STATUS_OK) { + waiting_op = calld->s.waiting_op; + calld->state = CALL_CANCELLED; + gpr_mu_unlock(&calld->mu_state); + handle_op_after_cancellation(elem, &waiting_op); + handle_op_after_cancellation(elem, op); + } else { + GPR_ASSERT((calld->s.waiting_op.send_ops == NULL) != + (op->send_ops == NULL)); + GPR_ASSERT((calld->s.waiting_op.recv_ops == NULL) != + (op->recv_ops == NULL)); + if (op->send_ops) { + calld->s.waiting_op.send_ops = op->send_ops; + calld->s.waiting_op.is_last_send = op->is_last_send; + calld->s.waiting_op.on_done_send = op->on_done_send; + calld->s.waiting_op.send_user_data = op->send_user_data; + } + if (op->recv_ops) { + calld->s.waiting_op.recv_ops = op->recv_ops; + calld->s.waiting_op.recv_state = op->recv_state; + calld->s.waiting_op.on_done_recv = op->on_done_recv; + calld->s.waiting_op.recv_user_data = op->recv_user_data; + } + gpr_mu_unlock(&calld->mu_state); + if (op->on_consumed) { + op->on_consumed(op->on_consumed_user_data, 0); + } + } + break; + } + + + + +#if 0 gpr_mu_lock(&chand->mu); switch (calld->state) { case CALL_ACTIVE: @@ -285,6 +371,7 @@ static void cc_start_transport_op(grpc_call_element *elem, handle_op_after_cancellation(elem, op); break; } +#endif } static void channel_op(grpc_channel_element *elem, @@ -536,11 +623,12 @@ grpc_transport_setup_result grpc_client_channel_transport_setup_complete( return result; } -void grpc_client_channel_set_transport_setup(grpc_channel_stack *channel_stack, - grpc_transport_setup *setup) { +void grpc_client_channel_set_resolver(grpc_channel_stack *channel_stack, + grpc_resolver *resolver) { /* post construction initialization: set the transport setup pointer */ grpc_channel_element *elem = grpc_channel_stack_last_element(channel_stack); channel_data *chand = elem->channel_data; - GPR_ASSERT(!chand->transport_setup); - chand->transport_setup = setup; + GPR_ASSERT(!chand->resolver); + chand->resolver = resolver; + grpc_resolver_next(resolver, &chand->incoming_configuration, &chand->on_config_changed); } -- cgit v1.2.3 From b7959a0b362daa951a245632ffa4617df4184a87 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 25 Jun 2015 08:50:54 -0700 Subject: s/grpc_transport_op/grpc_transport_stream_op/g --- src/core/channel/census_filter.c | 14 ++++++++------ src/core/channel/channel_stack.c | 6 +++--- src/core/channel/channel_stack.h | 11 ++++++----- src/core/channel/client_channel.c | 16 ++++++++-------- src/core/channel/connected_channel.c | 4 ++-- src/core/channel/http_client_filter.c | 7 ++++--- src/core/channel/http_server_filter.c | 7 ++++--- src/core/channel/noop_filter.c | 7 ++++--- src/core/client_config/subchannel.h | 7 +++++-- src/core/security/client_auth_filter.c | 12 ++++++------ src/core/security/server_auth_filter.c | 4 ++-- src/core/surface/call.c | 14 +++++++------- src/core/surface/client.c | 4 ++-- src/core/surface/lame_client.c | 6 +++--- src/core/surface/server.c | 7 ++++--- src/core/transport/chttp2_transport.c | 13 ++++++++----- src/core/transport/transport.c | 13 +++++++------ src/core/transport/transport.h | 20 ++++++++++---------- src/core/transport/transport_impl.h | 5 +++-- src/core/transport/transport_op_string.c | 6 +++--- test/core/channel/channel_stack_test.c | 4 ++-- 21 files changed, 101 insertions(+), 86 deletions(-) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/census_filter.c b/src/core/channel/census_filter.c index 7e393a01a6..ea0bece587 100644 --- a/src/core/channel/census_filter.c +++ b/src/core/channel/census_filter.c @@ -84,7 +84,8 @@ static void extract_and_annotate_method_tag(grpc_stream_op_buffer* sopb, } } -static void client_mutate_op(grpc_call_element* elem, grpc_transport_op* op) { +static void client_mutate_op(grpc_call_element* elem, + grpc_transport_stream_op* op) { call_data* calld = elem->call_data; channel_data* chand = elem->channel_data; if (op->send_ops) { @@ -93,7 +94,7 @@ static void client_mutate_op(grpc_call_element* elem, grpc_transport_op* op) { } static void client_start_transport_op(grpc_call_element* elem, - grpc_transport_op* op) { + grpc_transport_stream_op* op) { call_data* calld = elem->call_data; GPR_ASSERT((calld->op_id.upper != 0) || (calld->op_id.lower != 0)); client_mutate_op(elem, op); @@ -110,7 +111,8 @@ static void server_on_done_recv(void* ptr, int success) { calld->on_done_recv(calld->recv_user_data, success); } -static void server_mutate_op(grpc_call_element* elem, grpc_transport_op* op) { +static void server_mutate_op(grpc_call_element* elem, + grpc_transport_stream_op* op) { call_data* calld = elem->call_data; if (op->recv_ops) { /* substitute our callback for the op callback */ @@ -123,7 +125,7 @@ static void server_mutate_op(grpc_call_element* elem, grpc_transport_op* op) { } static void server_start_transport_op(grpc_call_element* elem, - grpc_transport_op* op) { + grpc_transport_stream_op* op) { call_data* calld = elem->call_data; GPR_ASSERT((calld->op_id.upper != 0) || (calld->op_id.lower != 0)); server_mutate_op(elem, op); @@ -145,7 +147,7 @@ static void channel_op(grpc_channel_element* elem, static void client_init_call_elem(grpc_call_element* elem, const void* server_transport_data, - grpc_transport_op* initial_op) { + grpc_transport_stream_op* initial_op) { call_data* d = elem->call_data; GPR_ASSERT(d != NULL); init_rpc_stats(&d->stats); @@ -163,7 +165,7 @@ static void client_destroy_call_elem(grpc_call_element* elem) { static void server_init_call_elem(grpc_call_element* elem, const void* server_transport_data, - grpc_transport_op* initial_op) { + grpc_transport_stream_op* initial_op) { call_data* d = elem->call_data; GPR_ASSERT(d != NULL); init_rpc_stats(&d->stats); diff --git a/src/core/channel/channel_stack.c b/src/core/channel/channel_stack.c index 9eec8163f5..b575367b52 100644 --- a/src/core/channel/channel_stack.c +++ b/src/core/channel/channel_stack.c @@ -148,7 +148,7 @@ void grpc_channel_stack_destroy(grpc_channel_stack *stack) { void grpc_call_stack_init(grpc_channel_stack *channel_stack, const void *transport_server_data, - grpc_transport_op *initial_op, + grpc_transport_stream_op *initial_op, grpc_call_stack *call_stack) { grpc_channel_element *channel_elems = CHANNEL_ELEMS_FROM_STACK(channel_stack); size_t count = channel_stack->count; @@ -184,7 +184,7 @@ void grpc_call_stack_destroy(grpc_call_stack *stack) { } } -void grpc_call_next_op(grpc_call_element *elem, grpc_transport_op *op) { +void grpc_call_next_op(grpc_call_element *elem, grpc_transport_stream_op *op) { grpc_call_element *next_elem = elem + 1; next_elem->filter->start_transport_op(next_elem, op); } @@ -206,7 +206,7 @@ grpc_call_stack *grpc_call_stack_from_top_element(grpc_call_element *elem) { } void grpc_call_element_send_cancel(grpc_call_element *cur_elem) { - grpc_transport_op op; + grpc_transport_stream_op op; memset(&op, 0, sizeof(op)); op.cancel_with_status = GRPC_STATUS_CANCELLED; grpc_call_next_op(cur_elem, &op); diff --git a/src/core/channel/channel_stack.h b/src/core/channel/channel_stack.h index de0e4e4518..873a8ac4d3 100644 --- a/src/core/channel/channel_stack.h +++ b/src/core/channel/channel_stack.h @@ -103,7 +103,8 @@ typedef struct { typedef struct { /* Called to eg. send/receive data on a call. See grpc_call_next_op on how to call the next element in the stack */ - void (*start_transport_op)(grpc_call_element *elem, grpc_transport_op *op); + void (*start_transport_op)(grpc_call_element *elem, + grpc_transport_stream_op *op); /* Called to handle channel level operations - e.g. new calls, or transport closure. See grpc_channel_next_op on how to call the next element in the stack */ @@ -122,7 +123,7 @@ typedef struct { argument.*/ void (*init_call_elem)(grpc_call_element *elem, const void *server_transport_data, - grpc_transport_op *initial_op); + grpc_transport_stream_op *initial_op); /* Destroy per call data. The filter does not need to do any chaining */ void (*destroy_call_elem)(grpc_call_element *elem); @@ -201,13 +202,13 @@ void grpc_channel_stack_destroy(grpc_channel_stack *stack); server. */ void grpc_call_stack_init(grpc_channel_stack *channel_stack, const void *transport_server_data, - grpc_transport_op *initial_op, + grpc_transport_stream_op *initial_op, grpc_call_stack *call_stack); /* Destroy a call stack */ void grpc_call_stack_destroy(grpc_call_stack *stack); /* Call the next operation in a call stack */ -void grpc_call_next_op(grpc_call_element *elem, grpc_transport_op *op); +void grpc_call_next_op(grpc_call_element *elem, grpc_transport_stream_op *op); /* Call the next operation (depending on call directionality) in a channel stack */ void grpc_channel_next_op(grpc_channel_element *elem, grpc_channel_op *op); @@ -219,7 +220,7 @@ grpc_channel_stack *grpc_channel_stack_from_top_element( grpc_call_stack *grpc_call_stack_from_top_element(grpc_call_element *elem); void grpc_call_log_op(char *file, int line, gpr_log_severity severity, - grpc_call_element *elem, grpc_transport_op *op); + grpc_call_element *elem, grpc_transport_stream_op *op); void grpc_call_element_send_cancel(grpc_call_element *cur_elem); diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index ea79d539ec..e171113dbc 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -91,7 +91,7 @@ struct call_data { /* our child call stack */ grpc_subchannel_call *subchannel_call; } active; - grpc_transport_op waiting_op; + grpc_transport_stream_op waiting_op; struct { grpc_linked_mdelem status; grpc_linked_mdelem details; @@ -124,7 +124,7 @@ static int prepare_activate(grpc_call_element *elem, return 1; } -static void complete_activate(grpc_call_element *elem, grpc_transport_op *op) { +static void complete_activate(grpc_call_element *elem, grpc_transport_stream_op *op) { call_data *calld = elem->call_data; grpc_call_element *child_elem = grpc_child_call_get_top_element(calld->s.active.child_call); @@ -154,7 +154,7 @@ static void remove_waiting_child(channel_data *chand, call_data *calld) { #endif static void handle_op_after_cancellation(grpc_call_element *elem, - grpc_transport_op *op) { + grpc_transport_stream_op *op) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; if (op->send_ops) { @@ -194,12 +194,12 @@ static void pick_target(grpc_lb_policy *lb_policy, call_data *calld) { } static void cc_start_transport_op(grpc_call_element *elem, - grpc_transport_op *op) { + grpc_transport_stream_op *op) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; grpc_subchannel_call *subchannel_call; grpc_lb_policy *lb_policy; - grpc_transport_op waiting_op; + grpc_transport_stream_op waiting_op; GPR_ASSERT(elem->filter == &grpc_client_channel_filter); GRPC_CALL_LOG_OP(GPR_INFO, elem, op); @@ -457,7 +457,7 @@ static void channel_op(grpc_channel_element *elem, /* Constructor for call_data */ static void init_call_elem(grpc_call_element *elem, const void *server_transport_data, - grpc_transport_op *initial_op) { + grpc_transport_stream_op *initial_op) { call_data *calld = elem->call_data; /* TODO(ctiller): is there something useful we can do here? */ @@ -555,7 +555,7 @@ grpc_transport_setup_result grpc_client_channel_transport_setup_complete( call_data **waiting_children; size_t waiting_child_count; size_t i; - grpc_transport_op *call_ops; + grpc_transport_stream_op *call_ops; /* build the child filter stack */ child_filters = gpr_malloc(sizeof(grpc_channel_filter *) * num_child_filters); @@ -597,7 +597,7 @@ grpc_transport_setup_result grpc_client_channel_transport_setup_complete( call_ops[i] = waiting_children[i]->s.waiting_op; if (!prepare_activate(waiting_children[i]->elem, chand->active_child)) { waiting_children[i] = NULL; - grpc_transport_op_finish_with_failure(&call_ops[i]); + grpc_transport_stream_op_finish_with_failure(&call_ops[i]); } } diff --git a/src/core/channel/connected_channel.c b/src/core/channel/connected_channel.c index 14dda88698..6fad077c62 100644 --- a/src/core/channel/connected_channel.c +++ b/src/core/channel/connected_channel.c @@ -62,7 +62,7 @@ typedef struct connected_channel_call_data { void *unused; } call_data; /* Intercept a call operation and either push it directly up or translate it into transport stream operations */ static void con_start_transport_op(grpc_call_element *elem, - grpc_transport_op *op) { + grpc_transport_stream_op *op) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; GPR_ASSERT(elem->filter == &grpc_connected_channel_filter); @@ -96,7 +96,7 @@ static void channel_op(grpc_channel_element *elem, /* Constructor for call_data */ static void init_call_elem(grpc_call_element *elem, const void *server_transport_data, - grpc_transport_op *initial_op) { + grpc_transport_stream_op *initial_op) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; int r; diff --git a/src/core/channel/http_client_filter.c b/src/core/channel/http_client_filter.c index 9805f325a6..23f5a9bfe9 100644 --- a/src/core/channel/http_client_filter.c +++ b/src/core/channel/http_client_filter.c @@ -87,7 +87,8 @@ static void hc_on_recv(void *user_data, int success) { calld->on_done_recv(calld->recv_user_data, success); } -static void hc_mutate_op(grpc_call_element *elem, grpc_transport_op *op) { +static void hc_mutate_op(grpc_call_element *elem, + grpc_transport_stream_op *op) { /* grab pointers to our data from the call element */ call_data *calld = elem->call_data; channel_data *channeld = elem->channel_data; @@ -124,7 +125,7 @@ static void hc_mutate_op(grpc_call_element *elem, grpc_transport_op *op) { } static void hc_start_transport_op(grpc_call_element *elem, - grpc_transport_op *op) { + grpc_transport_stream_op *op) { GRPC_CALL_LOG_OP(GPR_INFO, elem, op); hc_mutate_op(elem, op); grpc_call_next_op(elem, op); @@ -150,7 +151,7 @@ static void channel_op(grpc_channel_element *elem, /* Constructor for call_data */ static void init_call_elem(grpc_call_element *elem, const void *server_transport_data, - grpc_transport_op *initial_op) { + grpc_transport_stream_op *initial_op) { call_data *calld = elem->call_data; calld->sent_initial_metadata = 0; calld->got_initial_metadata = 0; diff --git a/src/core/channel/http_server_filter.c b/src/core/channel/http_server_filter.c index 11a53b1e70..d653938ff2 100644 --- a/src/core/channel/http_server_filter.c +++ b/src/core/channel/http_server_filter.c @@ -177,7 +177,8 @@ static void hs_on_recv(void *user_data, int success) { calld->on_done_recv(calld->recv_user_data, success); } -static void hs_mutate_op(grpc_call_element *elem, grpc_transport_op *op) { +static void hs_mutate_op(grpc_call_element *elem, + grpc_transport_stream_op *op) { /* grab pointers to our data from the call element */ call_data *calld = elem->call_data; channel_data *channeld = elem->channel_data; @@ -207,7 +208,7 @@ static void hs_mutate_op(grpc_call_element *elem, grpc_transport_op *op) { } static void hs_start_transport_op(grpc_call_element *elem, - grpc_transport_op *op) { + grpc_transport_stream_op *op) { GRPC_CALL_LOG_OP(GPR_INFO, elem, op); hs_mutate_op(elem, op); grpc_call_next_op(elem, op); @@ -233,7 +234,7 @@ static void channel_op(grpc_channel_element *elem, /* Constructor for call_data */ static void init_call_elem(grpc_call_element *elem, const void *server_transport_data, - grpc_transport_op *initial_op) { + grpc_transport_stream_op *initial_op) { /* grab pointers to our data from the call element */ call_data *calld = elem->call_data; /* initialize members */ diff --git a/src/core/channel/noop_filter.c b/src/core/channel/noop_filter.c index 1d2be716d7..d472b80744 100644 --- a/src/core/channel/noop_filter.c +++ b/src/core/channel/noop_filter.c @@ -45,7 +45,8 @@ typedef struct channel_data { /* used to silence 'variable not used' warnings */ static void ignore_unused(void *ignored) {} -static void noop_mutate_op(grpc_call_element *elem, grpc_transport_op *op) { +static void noop_mutate_op(grpc_call_element *elem, + grpc_transport_stream_op *op) { /* grab pointers to our data from the call element */ call_data *calld = elem->call_data; channel_data *channeld = elem->channel_data; @@ -62,7 +63,7 @@ static void noop_mutate_op(grpc_call_element *elem, grpc_transport_op *op) { op contains type and call direction information, in addition to the data that is being sent or received. */ static void noop_start_transport_op(grpc_call_element *elem, - grpc_transport_op *op) { + grpc_transport_stream_op *op) { noop_mutate_op(elem, op); /* pass control down the stack */ @@ -89,7 +90,7 @@ static void channel_op(grpc_channel_element *elem, /* Constructor for call_data */ static void init_call_elem(grpc_call_element *elem, const void *server_transport_data, - grpc_transport_op *initial_op) { + grpc_transport_stream_op *initial_op) { /* grab pointers to our data from the call element */ call_data *calld = elem->call_data; channel_data *channeld = elem->channel_data; diff --git a/src/core/client_config/subchannel.h b/src/core/client_config/subchannel.h index c87d294d8c..9128aaeda7 100644 --- a/src/core/client_config/subchannel.h +++ b/src/core/client_config/subchannel.h @@ -77,9 +77,12 @@ void grpc_subchannel_notify_on_state_change(grpc_subchannel *channel, grpc_iomgr_closure *notify); /** construct a call */ -grpc_subchannel_call *grpc_subchannel_create_call(grpc_subchannel *subchannel, grpc_call_element *parent, grpc_transport_op *initial_op); +grpc_subchannel_call *grpc_subchannel_create_call( + grpc_subchannel *subchannel, grpc_call_element *parent, + grpc_transport_stream_op *initial_op); /** continue processing a transport op */ -void grpc_subchannel_call_process_op(grpc_subchannel_call *subchannel_call, grpc_transport_op *op); +void grpc_subchannel_call_process_op(grpc_subchannel_call *subchannel_call, + grpc_transport_stream_op *op); #endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_SUBCHANNEL_H */ diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c index e9bd45db68..9ad4723ac5 100644 --- a/src/core/security/client_auth_filter.c +++ b/src/core/security/client_auth_filter.c @@ -58,7 +58,7 @@ typedef struct { so that work can progress when this call wants work to progress */ grpc_pollset *pollset; - grpc_transport_op op; + grpc_transport_stream_op op; size_t op_md_idx; int sent_initial_metadata; grpc_linked_mdelem md_links[MAX_CREDENTIALS_METADATA_COUNT]; @@ -77,7 +77,7 @@ typedef struct { static void bubble_up_error(grpc_call_element *elem, const char *error_msg) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; - grpc_transport_op_add_cancellation( + grpc_transport_stream_op_add_cancellation( &calld->op, GRPC_STATUS_UNAUTHENTICATED, grpc_mdstr_from_string(chand->md_ctx, error_msg)); grpc_call_next_op(elem, &calld->op); @@ -90,7 +90,7 @@ static void on_credentials_metadata(void *user_data, grpc_call_element *elem = (grpc_call_element *)user_data; call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; - grpc_transport_op *op = &calld->op; + grpc_transport_stream_op *op = &calld->op; grpc_metadata_batch *mdb; size_t i; if (status != GRPC_CREDENTIALS_OK) { @@ -131,7 +131,7 @@ static char *build_service_url(const char *url_scheme, call_data *calld) { } static void send_security_metadata(grpc_call_element *elem, - grpc_transport_op *op) { + grpc_transport_stream_op *op) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; grpc_client_security_context *ctx = @@ -193,7 +193,7 @@ static void on_host_checked(void *user_data, grpc_security_status status) { op contains type and call direction information, in addition to the data that is being sent or received. */ static void auth_start_transport_op(grpc_call_element *elem, - grpc_transport_op *op) { + grpc_transport_stream_op *op) { /* grab pointers to our data from the call element */ call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; @@ -263,7 +263,7 @@ static void channel_op(grpc_channel_element *elem, /* Constructor for call_data */ static void init_call_elem(grpc_call_element *elem, const void *server_transport_data, - grpc_transport_op *initial_op) { + grpc_transport_stream_op *initial_op) { call_data *calld = elem->call_data; calld->creds = NULL; calld->host = NULL; diff --git a/src/core/security/server_auth_filter.c b/src/core/security/server_auth_filter.c index b19160b8ed..2cb4bf612d 100644 --- a/src/core/security/server_auth_filter.c +++ b/src/core/security/server_auth_filter.c @@ -51,7 +51,7 @@ typedef struct channel_data { op contains type and call direction information, in addition to the data that is being sent or received. */ static void auth_start_transport_op(grpc_call_element *elem, - grpc_transport_op *op) { + grpc_transport_stream_op *op) { /* TODO(jboeuf): Get the metadata and get a new context from it. */ /* pass control down the stack */ @@ -68,7 +68,7 @@ static void channel_op(grpc_channel_element *elem, /* Constructor for call_data */ static void init_call_elem(grpc_call_element *elem, const void *server_transport_data, - grpc_transport_op *initial_op) { + grpc_transport_stream_op *initial_op) { /* grab pointers to our data from the call element */ call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; diff --git a/src/core/surface/call.c b/src/core/surface/call.c index dd8eaa943e..d96b2d648f 100644 --- a/src/core/surface/call.c +++ b/src/core/surface/call.c @@ -252,8 +252,8 @@ struct grpc_call { static void set_deadline_alarm(grpc_call *call, gpr_timespec deadline); static void call_on_done_recv(void *call, int success); static void call_on_done_send(void *call, int success); -static int fill_send_ops(grpc_call *call, grpc_transport_op *op); -static void execute_op(grpc_call *call, grpc_transport_op *op); +static int fill_send_ops(grpc_call *call, grpc_transport_stream_op *op); +static void execute_op(grpc_call *call, grpc_transport_stream_op *op); static void recv_metadata(grpc_call *call, grpc_metadata_batch *metadata); static void finish_read_ops(grpc_call *call); static grpc_call_error cancel_with_status(grpc_call *c, grpc_status_code status, @@ -268,8 +268,8 @@ grpc_call *grpc_call_create(grpc_channel *channel, grpc_completion_queue *cq, size_t add_initial_metadata_count, gpr_timespec send_deadline) { size_t i; - grpc_transport_op initial_op; - grpc_transport_op *initial_op_ptr = NULL; + grpc_transport_stream_op initial_op; + grpc_transport_stream_op *initial_op_ptr = NULL; grpc_channel_stack *channel_stack = grpc_channel_get_channel_stack(channel); grpc_call *call = gpr_malloc(sizeof(grpc_call) + channel_stack->call_stack_size); @@ -454,7 +454,7 @@ static int need_more_data(grpc_call *call) { } static void unlock(grpc_call *call) { - grpc_transport_op op; + grpc_transport_stream_op op; completed_request completed_requests[GRPC_IOREQ_OP_COUNT]; int completing_requests = 0; int start_op = 0; @@ -868,7 +868,7 @@ static void copy_byte_buffer_to_stream_ops(grpc_byte_buffer *byte_buffer, } } -static int fill_send_ops(grpc_call *call, grpc_transport_op *op) { +static int fill_send_ops(grpc_call *call, grpc_transport_stream_op *op) { grpc_ioreq_data data; gpr_uint32 flags; grpc_metadata_batch mdb; @@ -1115,7 +1115,7 @@ static void finished_loose_op(void *call, int success_ignored) { GRPC_CALL_INTERNAL_UNREF(call, "loose-op", 0); } -static void execute_op(grpc_call *call, grpc_transport_op *op) { +static void execute_op(grpc_call *call, grpc_transport_stream_op *op) { grpc_call_element *elem; GPR_ASSERT(op->on_consumed == NULL); diff --git a/src/core/surface/client.c b/src/core/surface/client.c index 8ac4dd1e0e..9c9cba5771 100644 --- a/src/core/surface/client.c +++ b/src/core/surface/client.c @@ -44,7 +44,7 @@ typedef struct { void *unused; } call_data; typedef struct { void *unused; } channel_data; static void client_start_transport_op(grpc_call_element *elem, - grpc_transport_op *op) { + grpc_transport_stream_op *op) { GRPC_CALL_LOG_OP(GPR_INFO, elem, op); grpc_call_next_op(elem, op); } @@ -69,7 +69,7 @@ static void channel_op(grpc_channel_element *elem, static void init_call_elem(grpc_call_element *elem, const void *transport_server_data, - grpc_transport_op *initial_op) {} + grpc_transport_stream_op *initial_op) {} static void destroy_call_elem(grpc_call_element *elem) {} diff --git a/src/core/surface/lame_client.c b/src/core/surface/lame_client.c index b667128aef..d3fe9fffb7 100644 --- a/src/core/surface/lame_client.c +++ b/src/core/surface/lame_client.c @@ -50,7 +50,7 @@ typedef struct { typedef struct { grpc_mdctx *mdctx; } channel_data; static void lame_start_transport_op(grpc_call_element *elem, - grpc_transport_op *op) { + grpc_transport_stream_op *op) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; GRPC_CALL_LOG_OP(GPR_INFO, elem, op); @@ -98,9 +98,9 @@ static void channel_op(grpc_channel_element *elem, static void init_call_elem(grpc_call_element *elem, const void *transport_server_data, - grpc_transport_op *initial_op) { + grpc_transport_stream_op *initial_op) { if (initial_op) { - grpc_transport_op_finish_with_failure(initial_op); + grpc_transport_stream_op_finish_with_failure(initial_op); } } diff --git a/src/core/surface/server.c b/src/core/surface/server.c index 546b17c1ff..445bd1a103 100644 --- a/src/core/surface/server.c +++ b/src/core/surface/server.c @@ -526,7 +526,8 @@ static void server_on_recv(void *ptr, int success) { calld->on_done_recv(calld->recv_user_data, success); } -static void server_mutate_op(grpc_call_element *elem, grpc_transport_op *op) { +static void server_mutate_op(grpc_call_element *elem, + grpc_transport_stream_op *op) { call_data *calld = elem->call_data; if (op->recv_ops) { @@ -541,7 +542,7 @@ static void server_mutate_op(grpc_call_element *elem, grpc_transport_op *op) { } static void server_start_transport_op(grpc_call_element *elem, - grpc_transport_op *op) { + grpc_transport_stream_op *op) { GRPC_CALL_LOG_OP(GPR_INFO, elem, op); server_mutate_op(elem, op); grpc_call_next_op(elem, op); @@ -625,7 +626,7 @@ static void shutdown_channel(channel_data *chand, int send_goaway, static void init_call_elem(grpc_call_element *elem, const void *server_transport_data, - grpc_transport_op *initial_op) { + grpc_transport_stream_op *initial_op) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; memset(calld, 0, sizeof(call_data)); diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c index 1cd1dc822d..93d7715919 100644 --- a/src/core/transport/chttp2_transport.c +++ b/src/core/transport/chttp2_transport.c @@ -232,7 +232,7 @@ struct transport { gpr_uint8 writing; /** are we calling back (via cb) with a channel-level event */ gpr_uint8 calling_back_channel; - /** are we calling back any grpc_transport_op completion events */ + /** are we calling back any grpc_transport_stream_op completion events */ gpr_uint8 calling_back_ops; gpr_uint8 destroying; gpr_uint8 closed; @@ -399,7 +399,8 @@ static void maybe_finish_read(transport *t, stream *s); static void maybe_join_window_updates(transport *t, stream *s); static void finish_reads(transport *t); static void add_to_pollset_locked(transport *t, grpc_pollset *pollset); -static void perform_op_locked(transport *t, stream *s, grpc_transport_op *op); +static void perform_op_locked(transport *t, stream *s, + grpc_transport_stream_op *op); static void add_metadata_batch(transport *t, stream *s); static void flowctl_trace(transport *t, const char *flow, gpr_int32 window, @@ -644,7 +645,8 @@ static void goaway(grpc_transport *gt, grpc_status_code status, } static int init_stream(grpc_transport *gt, grpc_stream *gs, - const void *server_data, grpc_transport_op *initial_op) { + const void *server_data, + grpc_transport_stream_op *initial_op) { transport *t = (transport *)gt; stream *s = (stream *)gs; @@ -1127,7 +1129,8 @@ static void maybe_start_some_streams(transport *t) { } } -static void perform_op_locked(transport *t, stream *s, grpc_transport_op *op) { +static void perform_op_locked(transport *t, stream *s, + grpc_transport_stream_op *op) { if (op->cancel_with_status != GRPC_STATUS_OK) { cancel_stream( t, s, op->cancel_with_status, @@ -1186,7 +1189,7 @@ static void perform_op_locked(transport *t, stream *s, grpc_transport_op *op) { } static void perform_op(grpc_transport *gt, grpc_stream *gs, - grpc_transport_op *op) { + grpc_transport_stream_op *op) { transport *t = (transport *)gt; stream *s = (stream *)gs; diff --git a/src/core/transport/transport.c b/src/core/transport/transport.c index a9948cd4b2..400c2023a9 100644 --- a/src/core/transport/transport.c +++ b/src/core/transport/transport.c @@ -53,13 +53,13 @@ void grpc_transport_destroy(grpc_transport *transport) { int grpc_transport_init_stream(grpc_transport *transport, grpc_stream *stream, const void *server_data, - grpc_transport_op *initial_op) { + grpc_transport_stream_op *initial_op) { return transport->vtable->init_stream(transport, stream, server_data, initial_op); } void grpc_transport_perform_op(grpc_transport *transport, grpc_stream *stream, - grpc_transport_op *op) { + grpc_transport_stream_op *op) { transport->vtable->perform_op(transport, stream, op); } @@ -96,7 +96,8 @@ void grpc_transport_setup_del_interested_party(grpc_transport_setup *setup, setup->vtable->del_interested_party(setup, pollset); } -void grpc_transport_op_finish_with_failure(grpc_transport_op *op) { +void grpc_transport_stream_op_finish_with_failure( + grpc_transport_stream_op *op) { if (op->send_ops) { op->on_done_send(op->send_user_data, 0); } @@ -108,9 +109,9 @@ void grpc_transport_op_finish_with_failure(grpc_transport_op *op) { } } -void grpc_transport_op_add_cancellation(grpc_transport_op *op, - grpc_status_code status, - grpc_mdstr *message) { +void grpc_transport_stream_op_add_cancellation(grpc_transport_stream_op *op, + grpc_status_code status, + grpc_mdstr *message) { if (op->cancel_with_status == GRPC_STATUS_OK) { op->cancel_with_status = status; op->cancel_message = message; diff --git a/src/core/transport/transport.h b/src/core/transport/transport.h index 7f60fdc037..72bc492d80 100644 --- a/src/core/transport/transport.h +++ b/src/core/transport/transport.h @@ -63,7 +63,7 @@ typedef enum grpc_stream_state { } grpc_stream_state; /* Transport op: a set of operations to perform on a transport */ -typedef struct grpc_transport_op { +typedef struct grpc_transport_stream_op { void (*on_consumed)(void *user_data, int success); void *on_consumed_user_data; @@ -84,7 +84,7 @@ typedef struct grpc_transport_op { /* Indexes correspond to grpc_context_index enum values */ grpc_call_context_element *context; -} grpc_transport_op; +} grpc_transport_stream_op; /* Callbacks made from the transport to the upper layers of grpc. */ struct grpc_transport_callbacks { @@ -126,7 +126,7 @@ size_t grpc_transport_stream_size(grpc_transport *transport); supplied from the accept_stream callback function */ int grpc_transport_init_stream(grpc_transport *transport, grpc_stream *stream, const void *server_data, - grpc_transport_op *initial_op); + grpc_transport_stream_op *initial_op); /* Destroy transport data for a stream. @@ -141,17 +141,17 @@ int grpc_transport_init_stream(grpc_transport *transport, grpc_stream *stream, void grpc_transport_destroy_stream(grpc_transport *transport, grpc_stream *stream); -void grpc_transport_op_finish_with_failure(grpc_transport_op *op); +void grpc_transport_stream_op_finish_with_failure(grpc_transport_stream_op *op); -void grpc_transport_op_add_cancellation(grpc_transport_op *op, - grpc_status_code status, - grpc_mdstr *message); +void grpc_transport_stream_op_add_cancellation(grpc_transport_stream_op *op, + grpc_status_code status, + grpc_mdstr *message); /* TODO(ctiller): remove this */ void grpc_transport_add_to_pollset(grpc_transport *transport, grpc_pollset *pollset); -char *grpc_transport_op_string(grpc_transport_op *op); +char *grpc_transport_stream_op_string(grpc_transport_stream_op *op); /* Send a batch of operations on a transport @@ -161,9 +161,9 @@ char *grpc_transport_op_string(grpc_transport_op *op); transport - the transport on which to initiate the stream stream - the stream on which to send the operations. This must be non-NULL and previously initialized by the same transport. - op - a grpc_transport_op specifying the op to perform */ + op - a grpc_transport_stream_op specifying the op to perform */ void grpc_transport_perform_op(grpc_transport *transport, grpc_stream *stream, - grpc_transport_op *op); + grpc_transport_stream_op *op); /* Send a ping on a transport diff --git a/src/core/transport/transport_impl.h b/src/core/transport/transport_impl.h index 479e15338f..2f940dde1c 100644 --- a/src/core/transport/transport_impl.h +++ b/src/core/transport/transport_impl.h @@ -43,11 +43,12 @@ typedef struct grpc_transport_vtable { /* implementation of grpc_transport_init_stream */ int (*init_stream)(grpc_transport *self, grpc_stream *stream, - const void *server_data, grpc_transport_op *initial_op); + const void *server_data, + grpc_transport_stream_op *initial_op); /* implementation of grpc_transport_send_batch */ void (*perform_op)(grpc_transport *self, grpc_stream *stream, - grpc_transport_op *op); + grpc_transport_stream_op *op); /* implementation of grpc_transport_add_to_pollset */ void (*add_to_pollset)(grpc_transport *self, grpc_pollset *pollset); diff --git a/src/core/transport/transport_op_string.c b/src/core/transport/transport_op_string.c index 5c4edb006a..43e14a7792 100644 --- a/src/core/transport/transport_op_string.c +++ b/src/core/transport/transport_op_string.c @@ -107,7 +107,7 @@ char *grpc_sopb_string(grpc_stream_op_buffer *sopb) { return out; } -char *grpc_transport_op_string(grpc_transport_op *op) { +char *grpc_transport_stream_op_string(grpc_transport_stream_op *op) { char *tmp; char *out; int first = 1; @@ -158,8 +158,8 @@ char *grpc_transport_op_string(grpc_transport_op *op) { } void grpc_call_log_op(char *file, int line, gpr_log_severity severity, - grpc_call_element *elem, grpc_transport_op *op) { - char *str = grpc_transport_op_string(op); + grpc_call_element *elem, grpc_transport_stream_op *op) { + char *str = grpc_transport_stream_op_string(op); gpr_log(file, line, severity, "OP[%s:%p]: %s", elem->filter->name, elem, str); gpr_free(str); } diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c index fe92f2f023..78779484b2 100644 --- a/test/core/channel/channel_stack_test.c +++ b/test/core/channel/channel_stack_test.c @@ -54,7 +54,7 @@ static void channel_init_func(grpc_channel_element *elem, static void call_init_func(grpc_call_element *elem, const void *server_transport_data, - grpc_transport_op *initial_op) { + grpc_transport_stream_op *initial_op) { ++*(int *)(elem->channel_data); *(int *)(elem->call_data) = 0; } @@ -65,7 +65,7 @@ static void call_destroy_func(grpc_call_element *elem) { ++*(int *)(elem->channel_data); } -static void call_func(grpc_call_element *elem, grpc_transport_op *op) { +static void call_func(grpc_call_element *elem, grpc_transport_stream_op *op) { ++*(int *)(elem->call_data); } -- cgit v1.2.3 From 3f475422ecb8cd5c648ce86f126122ba6dee1c9c Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 25 Jun 2015 10:43:05 -0700 Subject: chop chop chop --- include/grpc/grpc.h | 14 ++++ src/core/channel/channel_stack.c | 8 +- src/core/channel/channel_stack.h | 46 +---------- src/core/channel/client_channel.c | 147 ++++++++++++++++++++++------------ src/core/client_config/subchannel.h | 16 ---- src/core/transport/chttp2_transport.c | 35 -------- src/core/transport/transport.c | 9 ++- src/core/transport/transport.h | 58 ++++++-------- src/core/transport/transport_impl.h | 19 ++--- 9 files changed, 154 insertions(+), 198 deletions(-) (limited to 'src/core/channel/client_channel.c') diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index 8b4676562b..bb6753a9bb 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -118,6 +118,20 @@ typedef struct { #define GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER \ "grpc.http2.initial_sequence_number" +/** Connectivity state of a channel. */ +typedef enum { + /** channel is connecting */ + GRPC_CHANNEL_CONNECTING, + /** channel is ready for work */ + GRPC_CHANNEL_READY, + /** channel has seen a failure but expects to recover */ + GRPC_CHANNEL_TRANSIENT_FAILURE, + /** channel is idle */ + GRPC_CHANNEL_IDLE, + /** channel has seen a failure that it cannot recover from */ + GRPC_CHANNEL_FATAL_FAILURE +} grpc_connectivity_state; + /* Result of a grpc call. If the caller satisfies the prerequisites of a particular operation, the grpc_call_error returned will be GRPC_CALL_OK. Receiving any other value listed here is an indication of a bug in the diff --git a/src/core/channel/channel_stack.c b/src/core/channel/channel_stack.c index b575367b52..ff1077ce4c 100644 --- a/src/core/channel/channel_stack.c +++ b/src/core/channel/channel_stack.c @@ -186,12 +186,12 @@ void grpc_call_stack_destroy(grpc_call_stack *stack) { void grpc_call_next_op(grpc_call_element *elem, grpc_transport_stream_op *op) { grpc_call_element *next_elem = elem + 1; - next_elem->filter->start_transport_op(next_elem, op); + next_elem->filter->start_transport_stream_op(next_elem, op); } -void grpc_channel_next_op(grpc_channel_element *elem, grpc_channel_op *op) { - grpc_channel_element *next_elem = elem + op->dir; - next_elem->filter->channel_op(next_elem, elem, op); +void grpc_channel_next_op(grpc_channel_element *elem, grpc_transport_op *op) { + grpc_channel_element *next_elem = elem + 1; + next_elem->filter->start_transport_op(next_elem, op); } grpc_channel_stack *grpc_channel_stack_from_top_element( diff --git a/src/core/channel/channel_stack.h b/src/core/channel/channel_stack.h index 873a8ac4d3..5ac2372f3a 100644 --- a/src/core/channel/channel_stack.h +++ b/src/core/channel/channel_stack.h @@ -51,45 +51,6 @@ typedef struct grpc_channel_element grpc_channel_element; typedef struct grpc_call_element grpc_call_element; -/* The direction of the call. - The values of the enums (1, -1) matter here - they are used to increment - or decrement a pointer to find the next element to call */ -typedef enum { GRPC_CALL_DOWN = 1, GRPC_CALL_UP = -1 } grpc_call_dir; - -typedef enum { - /* send a goaway message to remote channels indicating that we are going - to disconnect in the future */ - GRPC_CHANNEL_GOAWAY, - /* disconnect any underlying transports */ - GRPC_CHANNEL_DISCONNECT, - /* transport received a new call */ - GRPC_ACCEPT_CALL, - /* an underlying transport was closed */ - GRPC_TRANSPORT_CLOSED, - /* an underlying transport is about to be closed */ - GRPC_TRANSPORT_GOAWAY -} grpc_channel_op_type; - -/* A single filterable operation to be performed on a channel */ -typedef struct { - /* The type of operation we're performing */ - grpc_channel_op_type type; - /* The directionality of this call - is it bubbling up the stack, or down? */ - grpc_call_dir dir; - - /* Argument data, matching up with grpc_channel_op_type names */ - union { - struct { - grpc_transport *transport; - const void *transport_server_data; - } accept_call; - struct { - grpc_status_code status; - gpr_slice message; - } goaway; - } data; -} grpc_channel_op; - /* Channel filters specify: 1. the amount of memory needed in the channel & call (via the sizeof_XXX members) @@ -103,13 +64,12 @@ typedef struct { typedef struct { /* Called to eg. send/receive data on a call. See grpc_call_next_op on how to call the next element in the stack */ - void (*start_transport_op)(grpc_call_element *elem, + void (*start_transport_stream_op)(grpc_call_element *elem, grpc_transport_stream_op *op); /* Called to handle channel level operations - e.g. new calls, or transport closure. See grpc_channel_next_op on how to call the next element in the stack */ - void (*channel_op)(grpc_channel_element *elem, - grpc_channel_element *from_elem, grpc_channel_op *op); + void (*start_transport_op)(grpc_channel_element *elem, grpc_transport_op *op); /* sizeof(per call data) */ size_t sizeof_call_data; @@ -211,7 +171,7 @@ void grpc_call_stack_destroy(grpc_call_stack *stack); void grpc_call_next_op(grpc_call_element *elem, grpc_transport_stream_op *op); /* Call the next operation (depending on call directionality) in a channel stack */ -void grpc_channel_next_op(grpc_channel_element *elem, grpc_channel_op *op); +void grpc_channel_next_op(grpc_channel_element *elem, grpc_transport_op *op); /* Given the top element of a channel stack, get the channel stack itself */ grpc_channel_stack *grpc_channel_stack_from_top_element( diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index 4ae951074d..9630f6898d 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -54,26 +54,27 @@ typedef struct { grpc_mdctx *mdctx; /** resolver for this channel */ grpc_resolver *resolver; - /** channel arguments for this channel - TODO(ctiller): still needed? */ - grpc_channel_args *args; - /** mutex protecting waiting list */ - gpr_mu mu_waiting; /** mutex protecting client configuration, resolution state */ gpr_mu mu_config; - /** currently active load balancer - guarded by mu_config */ grpc_lb_policy *lb_policy; - /** incoming configuration - set by resolver.next guarded by mu_config */ grpc_client_config *incoming_configuration; + /** a list of closures that are all waiting for config to come in */ + grpc_iomgr_closure *waiting_for_config_closures; + /** resolver callback */ + grpc_iomgr_closure on_config_changed; + /** connectivity state being tracked */ + grpc_iomgr_closure *on_connectivity_state_change; + grpc_connectivity_state *connectivity_state; } channel_data; typedef enum { CALL_CREATED, - CALL_WAITING, + CALL_WAITING_FOR_CONFIG, + CALL_WAITING_FOR_PICK, CALL_ACTIVE, CALL_CANCELLED } call_state; @@ -193,13 +194,12 @@ static void pick_target(grpc_lb_policy *lb_policy, call_data *calld) { abort(); } -static void cc_start_transport_op(grpc_call_element *elem, +static void cc_start_transport_stream_op(grpc_call_element *elem, grpc_transport_stream_op *op) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; grpc_subchannel_call *subchannel_call; grpc_lb_policy *lb_policy; - grpc_transport_stream_op waiting_op; GPR_ASSERT(elem->filter == &grpc_client_channel_filter); GRPC_CALL_LOG_OP(GPR_INFO, elem, op); @@ -207,10 +207,8 @@ static void cc_start_transport_op(grpc_call_element *elem, switch (calld->state) { case CALL_ACTIVE: subchannel_call = calld->s.active.subchannel_call; - grpc_subchannel_call_ref(subchannel_call); gpr_mu_unlock(&calld->mu_state); grpc_subchannel_call_process_op(subchannel_call, op); - grpc_subchannel_call_unref(subchannel_call); break; case CALL_CANCELLED: gpr_mu_unlock(&calld->mu_state); @@ -222,7 +220,6 @@ static void cc_start_transport_op(grpc_call_element *elem, gpr_mu_unlock(&calld->mu_state); handle_op_after_cancellation(elem, op); } else { - calld->state = CALL_WAITING; calld->s.waiting_op = *op; gpr_mu_lock(&chand->mu_config); @@ -230,45 +227,44 @@ static void cc_start_transport_op(grpc_call_element *elem, if (lb_policy) { grpc_lb_policy_ref(lb_policy); gpr_mu_unlock(&chand->mu_config); + calld->state = CALL_WAITING_FOR_PICK; gpr_mu_unlock(&calld->mu_state); pick_target(lb_policy, calld); grpc_lb_policy_unref(lb_policy); } else { + calld->state = CALL_WAITING_FOR_CONFIG; add_to_lb_policy_wait_queue_locked_state_config(chand, calld); gpr_mu_unlock(&chand->mu_config); gpr_mu_unlock(&calld->mu_state); } } break; - case CALL_WAITING: + case CALL_WAITING_FOR_CONFIG: + case CALL_WAITING_FOR_PICK: if (op->cancel_with_status != GRPC_STATUS_OK) { - waiting_op = calld->s.waiting_op; calld->state = CALL_CANCELLED; gpr_mu_unlock(&calld->mu_state); - handle_op_after_cancellation(elem, &waiting_op); handle_op_after_cancellation(elem, op); } else { GPR_ASSERT((calld->s.waiting_op.send_ops == NULL) != (op->send_ops == NULL)); GPR_ASSERT((calld->s.waiting_op.recv_ops == NULL) != (op->recv_ops == NULL)); - if (op->send_ops) { + if (op->send_ops != NULL) { calld->s.waiting_op.send_ops = op->send_ops; calld->s.waiting_op.is_last_send = op->is_last_send; calld->s.waiting_op.on_done_send = op->on_done_send; - calld->s.waiting_op.send_user_data = op->send_user_data; } - if (op->recv_ops) { + if (op->recv_ops != NULL) { calld->s.waiting_op.recv_ops = op->recv_ops; calld->s.waiting_op.recv_state = op->recv_state; calld->s.waiting_op.on_done_recv = op->on_done_recv; - calld->s.waiting_op.recv_user_data = op->recv_user_data; } gpr_mu_unlock(&calld->mu_state); - if (op->on_consumed) { - op->on_consumed(op->on_consumed_user_data, 0); + if (op->on_consumed != NULL) { + op->on_consumed->cb(op->on_consumed->cb_arg, 0); } } break; @@ -372,6 +368,55 @@ static void cc_start_transport_op(grpc_call_element *elem, #endif } +static void update_state_locked(channel_data *chand) { + +} + +static void cc_on_config_changed(void *arg, int iomgr_success) { + channel_data *chand = arg; + grpc_lb_policy *lb_policy = NULL; + grpc_lb_policy *old_lb_policy; + grpc_resolver *old_resolver; + grpc_iomgr_closure *wakeup_closures = NULL; + + if (chand->incoming_configuration) { + lb_policy = grpc_client_config_get_lb_policy(chand->incoming_configuration); + grpc_lb_policy_ref(lb_policy); + } + + grpc_client_config_unref(chand->incoming_configuration); + chand->incoming_configuration = NULL; + + gpr_mu_lock(&chand->mu_config); + old_lb_policy = chand->lb_policy; + chand->lb_policy = lb_policy; + if (lb_policy != NULL) { + wakeup_closures = chand->waiting_for_config_closures; + chand->waiting_for_config_closures = NULL; + } + gpr_mu_unlock(&chand->mu_config); + + while (wakeup_closures) { + grpc_iomgr_closure *next = wakeup_closures->next; + grpc_iomgr_add_callback(wakeup_closures); + wakeup_closures = next; + } + + grpc_lb_policy_unref(old_lb_policy); + + if (iomgr_success) { + grpc_resolver_next(chand->resolver, &chand->incoming_configuration, &chand->on_config_changed); + } else { + gpr_mu_lock(&chand->mu_config); + old_resolver = chand->resolver; + chand->resolver = NULL; + update_state_locked(chand); + gpr_mu_unlock(&chand->mu_config); + grpc_resolver_unref(old_resolver); + } +} + +#if 0 static void channel_op(grpc_channel_element *elem, grpc_channel_element *from_elem, grpc_channel_op *op) { channel_data *chand = elem->channel_data; @@ -451,6 +496,9 @@ static void channel_op(grpc_channel_element *elem, break; } } +#endif + +static void cc_start_transport_op(grpc_channel_element *elem, grpc_transport_op *op) {} /* Constructor for call_data */ static void init_call_elem(grpc_call_element *elem, @@ -471,26 +519,28 @@ static void init_call_elem(grpc_call_element *elem, /* Destructor for call_data */ static void destroy_call_elem(grpc_call_element *elem) { call_data *calld = elem->call_data; - channel_data *chand = elem->channel_data; + grpc_subchannel_call *subchannel_call; /* if the call got activated, we need to destroy the child stack also, and remove it from the in-flight requests tracked by the child_entry we picked */ - gpr_mu_lock(&chand->mu); + gpr_mu_lock(&calld->mu_state); switch (calld->state) { case CALL_ACTIVE: - gpr_mu_unlock(&chand->mu); - grpc_child_call_destroy(calld->s.active.child_call); + subchannel_call = calld->s.active.subchannel_call; + gpr_mu_unlock(&calld->mu_state); + grpc_subchannel_call_unref(subchannel_call); break; - case CALL_WAITING: - remove_waiting_child(chand, calld); - gpr_mu_unlock(&chand->mu); + case CALL_CREATED: + case CALL_CANCELLED: + gpr_mu_unlock(&calld->mu_state); break; - default: - gpr_mu_unlock(&chand->mu); + case CALL_WAITING_FOR_PICK: + case CALL_WAITING_FOR_CONFIG: + gpr_log(GPR_ERROR, "should never reach here"); + abort(); break; } - GPR_ASSERT(calld->state != CALL_WAITING); } /* Constructor for channel_data */ @@ -504,41 +554,32 @@ static void init_channel_elem(grpc_channel_element *elem, GPR_ASSERT(is_last); GPR_ASSERT(elem->filter == &grpc_client_channel_filter); - gpr_mu_init(&chand->mu); - chand->active_child = NULL; - chand->waiting_children = NULL; - chand->waiting_child_count = 0; - chand->waiting_child_capacity = 0; - chand->transport_setup = NULL; - chand->transport_setup_initiated = 0; - chand->args = grpc_channel_args_copy(args); + gpr_mu_init(&chand->mu_config); + chand->resolver = NULL; chand->mdctx = metadata_context; + grpc_iomgr_closure_init(&chand->on_config_changed, cc_on_config_changed, chand); } /* Destructor for channel_data */ static void destroy_channel_elem(grpc_channel_element *elem) { channel_data *chand = elem->channel_data; - grpc_transport_setup_cancel(chand->transport_setup); - - if (chand->active_child) { - grpc_child_channel_destroy(chand->active_child, 1); - chand->active_child = NULL; + if (chand->resolver) { + grpc_resolver_unref(chand->resolver); } - - grpc_channel_args_destroy(chand->args); - - gpr_mu_destroy(&chand->mu); - GPR_ASSERT(chand->waiting_child_count == 0); - gpr_free(chand->waiting_children); + if (chand->lb_policy) { + grpc_lb_policy_unref(chand->lb_policy); + } + gpr_mu_destroy(&chand->mu_config); } const grpc_channel_filter grpc_client_channel_filter = { - cc_start_transport_op, channel_op, sizeof(call_data), + cc_start_transport_stream_op, cc_start_transport_op, sizeof(call_data), init_call_elem, destroy_call_elem, sizeof(channel_data), init_channel_elem, destroy_channel_elem, "client-channel", }; +#if 0 grpc_transport_setup_result grpc_client_channel_transport_setup_complete( grpc_channel_stack *channel_stack, grpc_transport *transport, grpc_channel_filter const **channel_filters, size_t num_channel_filters, @@ -620,6 +661,7 @@ grpc_transport_setup_result grpc_client_channel_transport_setup_complete( return result; } +#endif void grpc_client_channel_set_resolver(grpc_channel_stack *channel_stack, grpc_resolver *resolver) { @@ -628,5 +670,6 @@ void grpc_client_channel_set_resolver(grpc_channel_stack *channel_stack, channel_data *chand = elem->channel_data; GPR_ASSERT(!chand->resolver); chand->resolver = resolver; + grpc_resolver_ref(resolver); grpc_resolver_next(resolver, &chand->incoming_configuration, &chand->on_config_changed); } diff --git a/src/core/client_config/subchannel.h b/src/core/client_config/subchannel.h index 9128aaeda7..0c6c9b3e64 100644 --- a/src/core/client_config/subchannel.h +++ b/src/core/client_config/subchannel.h @@ -44,22 +44,6 @@ typedef struct grpc_subchannel grpc_subchannel; typedef struct grpc_subchannel_call grpc_subchannel_call; -/** Connectivity state of a channel. - TODO(ctiller): move to grpc.h when we implement the public - version of the connectivity apis */ -typedef enum { - /** channel is connecting */ - GRPC_CHANNEL_CONNECTING, - /** channel is ready for work */ - GRPC_CHANNEL_READY, - /** channel has seen a failure but expects to recover */ - GRPC_CHANNEL_TRANSIENT_FAILURE, - /** channel is idle */ - GRPC_CHANNEL_IDLE, - /** channel has seen a failure that it cannot recover from */ - GRPC_CHANNEL_FATAL_FAILURE -} grpc_connectivity_state; - void grpc_subchannel_ref(grpc_subchannel *channel); void grpc_subchannel_unref(grpc_subchannel *channel); diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c index 9943dbdbac..685098bcba 100644 --- a/src/core/transport/chttp2_transport.c +++ b/src/core/transport/chttp2_transport.c @@ -114,26 +114,9 @@ static void cancel_from_api(grpc_chttp2_transport_global *transport_global, static void add_to_pollset_locked(grpc_chttp2_transport *t, grpc_pollset *pollset); -<<<<<<< HEAD -static void schedule_cb(transport *t, op_closure closure, int success); -static void maybe_finish_read(transport *t, stream *s); -static void maybe_join_window_updates(transport *t, stream *s); -static void finish_reads(transport *t); -static void add_to_pollset_locked(transport *t, grpc_pollset *pollset); -static void perform_op_locked(transport *t, stream *s, - grpc_transport_stream_op *op); -static void add_metadata_batch(transport *t, stream *s); - -static void flowctl_trace(transport *t, const char *flow, gpr_int32 window, - gpr_uint32 id, gpr_int32 delta) { - gpr_log(GPR_DEBUG, "HTTP:FLOW:%p:%d:%s: %d + %d = %d", t, id, flow, window, - delta, window + delta); -} -======= /** Start new streams that have been created if we can */ static void maybe_start_some_streams( grpc_chttp2_transport_global *transport_global); ->>>>>>> 48f0a13f3872876787f4d7588b396db914319b1b /* * CONSTRUCTION/DESTRUCTION/REFCOUNTING @@ -385,16 +368,9 @@ static void goaway(grpc_transport *gt, grpc_status_code status, } static int init_stream(grpc_transport *gt, grpc_stream *gs, -<<<<<<< HEAD - const void *server_data, - grpc_transport_stream_op *initial_op) { - transport *t = (transport *)gt; - stream *s = (stream *)gs; -======= const void *server_data, grpc_transport_stream_op *initial_op) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs; ->>>>>>> 48f0a13f3872876787f4d7588b396db914319b1b memset(s, 0, sizeof(*s)); @@ -635,14 +611,9 @@ static void maybe_start_some_streams( } } -<<<<<<< HEAD -static void perform_op_locked(transport *t, stream *s, - grpc_transport_stream_op *op) { -======= static void perform_op_locked(grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global *stream_global, grpc_transport_stream_op *op) { ->>>>>>> 48f0a13f3872876787f4d7588b396db914319b1b if (op->cancel_with_status != GRPC_STATUS_OK) { cancel_from_api(transport_global, stream_global, op->cancel_with_status); } @@ -699,15 +670,9 @@ static void perform_op_locked(grpc_chttp2_transport_global *transport_global, } static void perform_op(grpc_transport *gt, grpc_stream *gs, -<<<<<<< HEAD - grpc_transport_stream_op *op) { - transport *t = (transport *)gt; - stream *s = (stream *)gs; -======= grpc_transport_stream_op *op) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs; ->>>>>>> 48f0a13f3872876787f4d7588b396db914319b1b lock(t); perform_op_locked(&t->global, &s->global, op); diff --git a/src/core/transport/transport.c b/src/core/transport/transport.c index a73c32da1a..40faa27211 100644 --- a/src/core/transport/transport.c +++ b/src/core/transport/transport.c @@ -58,9 +58,14 @@ int grpc_transport_init_stream(grpc_transport *transport, grpc_stream *stream, initial_op); } -void grpc_transport_perform_op(grpc_transport *transport, grpc_stream *stream, +void grpc_transport_perform_stream_op(grpc_transport *transport, grpc_stream *stream, grpc_transport_stream_op *op) { - transport->vtable->perform_op(transport, stream, op); + transport->vtable->perform_stream_op(transport, stream, op); +} + +void grpc_transport_perform_op(grpc_transport *transport, + grpc_transport_op *op) { + transport->vtable->perform_op(transport, op); } void grpc_transport_add_to_pollset(grpc_transport *transport, diff --git a/src/core/transport/transport.h b/src/core/transport/transport.h index fbfed46626..7f6a37d048 100644 --- a/src/core/transport/transport.h +++ b/src/core/transport/transport.h @@ -43,7 +43,6 @@ /* forward declarations */ typedef struct grpc_transport grpc_transport; -typedef struct grpc_transport_callbacks grpc_transport_callbacks; /* grpc_stream doesn't actually exist. It's used as a typesafe opaque pointer for whatever data the transport wants to track @@ -62,7 +61,8 @@ typedef enum grpc_stream_state { GRPC_STREAM_CLOSED } grpc_stream_state; -/* Transport op: a set of operations to perform on a transport */ +/* Transport stream op: a set of operations to perform on a transport + against a single stream */ typedef struct grpc_transport_stream_op { grpc_iomgr_closure *on_consumed; @@ -83,30 +83,27 @@ typedef struct grpc_transport_stream_op { grpc_call_context_element *context; } grpc_transport_stream_op; -/* Callbacks made from the transport to the upper layers of grpc. */ -struct grpc_transport_callbacks { - /* Initialize a new stream on behalf of the transport. - Must result in a call to - grpc_transport_init_stream(transport, ..., request) in the same call - stack. - Must not result in any other calls to the transport. - - Arguments: - user_data - the transport user data set at transport creation time - transport - the grpc_transport instance making this call - request - request parameters for this stream (owned by the caller) - server_data - opaque transport dependent argument that should be passed - to grpc_transport_init_stream - */ - void (*accept_stream)(void *user_data, grpc_transport *transport, - const void *server_data); - - void (*goaway)(void *user_data, grpc_transport *transport, - grpc_status_code status, gpr_slice debug); - - /* The transport has been closed */ - void (*closed)(void *user_data, grpc_transport *transport); -}; +/** Transport op: a set of operations to perform on a transport as a whole */ +typedef struct grpc_transport_op { + /** connectivity monitoring */ + grpc_iomgr_closure *on_connectivity_state_change; + grpc_connectivity_state *connectivity_state; + /** should the transport be disconnected */ + int disconnect; + /** should we send a goaway? */ + int send_goaway; + /** what should the goaway contain? */ + grpc_status_code goaway_status; + gpr_slice *goaway_message; + /** set the callback for accepting new streams; + this is a permanent callback, unlike the other one-shot closures */ + void (*set_accept_stream)(void *user_data, grpc_transport *transport, const void *server_data); + void *set_accept_stream_user_data; + /** add this transport to a pollset */ + grpc_pollset *bind_pollset; + /** send a ping, call this back if not NULL */ + grpc_iomgr_closure *send_ping; +} grpc_transport_op; /* Returns the amount of memory required to store a grpc_stream for this transport */ @@ -144,10 +141,6 @@ void grpc_transport_stream_op_add_cancellation(grpc_transport_stream_op *op, grpc_status_code status, grpc_mdstr *message); -/* TODO(ctiller): remove this */ -void grpc_transport_add_to_pollset(grpc_transport *transport, - grpc_pollset *pollset); - char *grpc_transport_stream_op_string(grpc_transport_stream_op *op); /* Send a batch of operations on a transport @@ -159,9 +152,11 @@ char *grpc_transport_stream_op_string(grpc_transport_stream_op *op); stream - the stream on which to send the operations. This must be non-NULL and previously initialized by the same transport. op - a grpc_transport_stream_op specifying the op to perform */ -void grpc_transport_perform_op(grpc_transport *transport, grpc_stream *stream, +void grpc_transport_perform_stream_op(grpc_transport *transport, grpc_stream *stream, grpc_transport_stream_op *op); +void grpc_transport_perform_op(grpc_transport *transport, grpc_transport_op *op); + /* Send a ping on a transport Calls cb with user data when a response is received. */ @@ -180,7 +175,6 @@ void grpc_transport_destroy(grpc_transport *transport); /* Return type for grpc_transport_setup_callback */ typedef struct grpc_transport_setup_result { void *user_data; - const grpc_transport_callbacks *callbacks; } grpc_transport_setup_result; /* Given a transport, return callbacks for that transport. Used to finalize diff --git a/src/core/transport/transport_impl.h b/src/core/transport/transport_impl.h index 442b64ca59..b65b1d5607 100644 --- a/src/core/transport/transport_impl.h +++ b/src/core/transport/transport_impl.h @@ -46,26 +46,17 @@ typedef struct grpc_transport_vtable { const void *server_data, grpc_transport_stream_op *initial_op); - /* implementation of grpc_transport_send_batch */ - void (*perform_op)(grpc_transport *self, grpc_stream *stream, + /* implementation of grpc_transport_perform_stream_op */ + void (*perform_stream_op)(grpc_transport *self, grpc_stream *stream, grpc_transport_stream_op *op); - /* implementation of grpc_transport_add_to_pollset */ - void (*add_to_pollset)(grpc_transport *self, grpc_pollset *pollset); + /* implementation of grpc_transport_perform_op */ + void (*perform_op)(grpc_transport *self, grpc_stream *stream, + grpc_transport_stream_op *op); /* implementation of grpc_transport_destroy_stream */ void (*destroy_stream)(grpc_transport *self, grpc_stream *stream); - /* implementation of grpc_transport_goaway */ - void (*goaway)(grpc_transport *self, grpc_status_code status, - gpr_slice debug_data); - - /* implementation of grpc_transport_close */ - void (*close)(grpc_transport *self); - - /* implementation of grpc_transport_ping */ - void (*ping)(grpc_transport *self, grpc_iomgr_closure *cb); - /* implementation of grpc_transport_destroy */ void (*destroy)(grpc_transport *self); } grpc_transport_vtable; -- cgit v1.2.3 From eb3b12e41752acbde3c020af3cebbdd6baf97e60 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 26 Jun 2015 14:42:49 -0700 Subject: Further client config work --- src/core/channel/client_channel.c | 329 ++++++++++++------------ src/core/client_config/client_config.c | 2 +- src/core/client_config/lb_policies/pick_first.c | 169 ++++++++++++ src/core/client_config/lb_policy.h | 2 +- src/core/client_config/resolver_factory.c | 1 + src/core/client_config/resolver_registry.c | 79 +++--- src/core/client_config/resolver_registry.h | 12 +- src/core/client_config/resolvers/dns_resolver.c | 47 ++-- src/core/client_config/resolvers/dns_resolver.h | 3 +- src/core/client_config/subchannel.c | 77 +++++- src/core/client_config/subchannel.h | 5 +- src/core/client_config/subchannel_factory.c | 12 + src/core/client_config/uri_parser.c | 25 +- src/core/client_config/uri_parser.h | 3 - src/core/surface/init.c | 4 + test/core/end2end/fixtures/chttp2_fullstack.c | 1 + 16 files changed, 511 insertions(+), 260 deletions(-) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index 9630f6898d..965d4e53dc 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -34,6 +34,7 @@ #include "src/core/channel/client_channel.h" #include +#include #include "src/core/channel/channel_args.h" #include "src/core/channel/connected_channel.h" @@ -75,6 +76,7 @@ typedef enum { CALL_CREATED, CALL_WAITING_FOR_CONFIG, CALL_WAITING_FOR_PICK, + CALL_WAITING_FOR_CALL, CALL_ACTIVE, CALL_CANCELLED } call_state; @@ -87,17 +89,13 @@ struct call_data { call_state state; gpr_timespec deadline; - union { - struct { - /* our child call stack */ - grpc_subchannel_call *subchannel_call; - } active; - grpc_transport_stream_op waiting_op; - struct { - grpc_linked_mdelem status; - grpc_linked_mdelem details; - } cancelled; - } s; + grpc_subchannel *picked_channel; + grpc_iomgr_closure async_setup_task; + grpc_transport_stream_op waiting_op; + /* our child call stack */ + grpc_subchannel_call *subchannel_call; + grpc_linked_mdelem status; + grpc_linked_mdelem details; }; #if 0 @@ -110,9 +108,9 @@ static int prepare_activate(grpc_call_element *elem, /* no more access to calld->s.waiting allowed */ GPR_ASSERT(calld->state == CALL_WAITING); - if (calld->s.waiting_op.bind_pollset) { + if (calld->waiting_op.bind_pollset) { grpc_transport_setup_del_interested_party(chand->transport_setup, - calld->s.waiting_op.bind_pollset); + calld->waiting_op.bind_pollset); } calld->state = CALL_ACTIVE; @@ -143,7 +141,7 @@ static void remove_waiting_child(channel_data *chand, call_data *calld) { for (i = 0, new_count = 0; i < chand->waiting_child_count; i++) { if (chand->waiting_children[i] == calld) { grpc_transport_setup_del_interested_party( - chand->transport_setup, calld->s.waiting_op.bind_pollset); + chand->transport_setup, calld->waiting_op.bind_pollset); continue; } chand->waiting_children[new_count++] = chand->waiting_children[i]; @@ -166,15 +164,15 @@ static void handle_op_after_cancellation(grpc_call_element *elem, char status[GPR_LTOA_MIN_BUFSIZE]; grpc_metadata_batch mdb; gpr_ltoa(GRPC_STATUS_CANCELLED, status); - calld->s.cancelled.status.md = + calld->status.md = grpc_mdelem_from_strings(chand->mdctx, "grpc-status", status); - calld->s.cancelled.details.md = + calld->details.md = grpc_mdelem_from_strings(chand->mdctx, "grpc-message", "Cancelled"); - calld->s.cancelled.status.prev = calld->s.cancelled.details.next = NULL; - calld->s.cancelled.status.next = &calld->s.cancelled.details; - calld->s.cancelled.details.prev = &calld->s.cancelled.status; - mdb.list.head = &calld->s.cancelled.status; - mdb.list.tail = &calld->s.cancelled.details; + calld->status.prev = calld->details.next = NULL; + calld->status.next = &calld->details; + calld->details.prev = &calld->status; + mdb.list.head = &calld->status; + mdb.list.tail = &calld->details; mdb.garbage.head = mdb.garbage.tail = NULL; mdb.deadline = gpr_inf_future; grpc_sopb_add_metadata(op->recv_ops, mdb); @@ -186,16 +184,111 @@ static void handle_op_after_cancellation(grpc_call_element *elem, } } -static void add_to_lb_policy_wait_queue_locked_state_config(channel_data *chand, call_data *calld) { - abort(); +typedef struct { + grpc_iomgr_closure closure; + grpc_call_element *elem; +} waiting_call; + +static void perform_transport_stream_op(grpc_call_element *elem, grpc_transport_stream_op *op, int continuation); + +static void continue_with_pick(void *arg, int iomgr_success) { + waiting_call *wc = arg; + call_data *calld = wc->elem->call_data; + perform_transport_stream_op(wc->elem, &calld->waiting_op, 1); + gpr_free(wc); +} + +static void add_to_lb_policy_wait_queue_locked_state_config(grpc_call_element *elem) { + channel_data *chand = elem->channel_data; + waiting_call *wc = gpr_malloc(sizeof(*wc)); + grpc_iomgr_closure_init(&wc->closure, continue_with_pick, wc); + wc->elem = elem; + wc->closure.next = chand->waiting_for_config_closures; + chand->waiting_for_config_closures = &wc->closure; +} + +static int is_empty(void *p, int len) { + char *ptr = p; + int i; + for (i = 0; i < len; i++) { + if (ptr[i] != 0) return 0; + } + return 1; +} + +static void started_call(void *arg, int iomgr_success) { + call_data *calld = arg; + grpc_transport_stream_op op; + int have_waiting; + + gpr_mu_lock(&calld->mu_state); + if (calld->state == CALL_CANCELLED && calld->subchannel_call != NULL) { + memset(&op, 0, sizeof(op)); + op.cancel_with_status = GRPC_STATUS_CANCELLED; + gpr_mu_unlock(&calld->mu_state); + grpc_subchannel_call_process_op(calld->subchannel_call, &op); + } else if (calld->state == CALL_WAITING_FOR_CALL) { + have_waiting = !is_empty(&calld->waiting_op, sizeof(calld->waiting_op)); + if (calld->subchannel_call != NULL) { + calld->state = CALL_ACTIVE; + gpr_mu_unlock(&calld->mu_state); + if (have_waiting) { + grpc_subchannel_call_process_op(calld->subchannel_call, &calld->waiting_op); + } + } else { + calld->state = CALL_CANCELLED; + gpr_mu_unlock(&calld->mu_state); + if (have_waiting) { + handle_op_after_cancellation(calld->elem, &calld->waiting_op); + } + } + } else { + GPR_ASSERT(calld->state == CALL_CANCELLED); + } +} + +static void picked_target(void *arg, int iomgr_success) { + call_data *calld = arg; + channel_data *chand = calld->elem->channel_data; + grpc_transport_stream_op op; + + if (calld->picked_channel == NULL) { + /* treat this like a cancellation */ + calld->waiting_op.cancel_with_status = GRPC_STATUS_UNAVAILABLE; + perform_transport_stream_op(calld->elem, &calld->waiting_op, 1); + } else { + gpr_mu_lock(&calld->mu_state); + if (calld->state == CALL_CANCELLED) { + gpr_mu_unlock(&calld->mu_state); + handle_op_after_cancellation(calld->elem, &calld->waiting_op); + } else { + GPR_ASSERT(calld->state == CALL_WAITING_FOR_PICK); + calld->state = CALL_WAITING_FOR_CALL; + op = calld->waiting_op; + memset(&calld->waiting_op, 0, sizeof(calld->waiting_op)); + gpr_mu_unlock(&calld->mu_state); + grpc_iomgr_closure_init(&calld->async_setup_task, started_call, calld); + grpc_subchannel_create_call(calld->picked_channel, chand->mdctx, &op, &calld->subchannel_call, &calld->async_setup_task); + } + } } static void pick_target(grpc_lb_policy *lb_policy, call_data *calld) { - abort(); + grpc_metadata_batch *initial_metadata; + grpc_transport_stream_op *op = &calld->waiting_op; + + GPR_ASSERT(op->bind_pollset); + GPR_ASSERT(op->send_ops); + GPR_ASSERT(op->send_ops->nops >= 1); + GPR_ASSERT(op->send_ops->ops[0].type == GRPC_OP_METADATA); + initial_metadata = &op->send_ops->ops[0].data.metadata; + + grpc_iomgr_closure_init(&calld->async_setup_task, picked_target, calld); + grpc_lb_policy_pick(lb_policy, op->bind_pollset, + initial_metadata, &calld->picked_channel, &calld->async_setup_task); } -static void cc_start_transport_stream_op(grpc_call_element *elem, - grpc_transport_stream_op *op) { +static void perform_transport_stream_op(grpc_call_element *elem, grpc_transport_stream_op *op, int continuation) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; grpc_subchannel_call *subchannel_call; @@ -206,7 +299,8 @@ static void cc_start_transport_stream_op(grpc_call_element *elem, gpr_mu_lock(&calld->mu_state); switch (calld->state) { case CALL_ACTIVE: - subchannel_call = calld->s.active.subchannel_call; + GPR_ASSERT(!continuation); + subchannel_call = calld->subchannel_call; gpr_mu_unlock(&calld->mu_state); grpc_subchannel_call_process_op(subchannel_call, op); break; @@ -214,13 +308,44 @@ static void cc_start_transport_stream_op(grpc_call_element *elem, gpr_mu_unlock(&calld->mu_state); handle_op_after_cancellation(elem, op); break; + case CALL_WAITING_FOR_CONFIG: + case CALL_WAITING_FOR_PICK: + case CALL_WAITING_FOR_CALL: + if (!continuation) { + if (op->cancel_with_status != GRPC_STATUS_OK) { + calld->state = CALL_CANCELLED; + gpr_mu_unlock(&calld->mu_state); + handle_op_after_cancellation(elem, op); + } else { + GPR_ASSERT((calld->waiting_op.send_ops == NULL) != + (op->send_ops == NULL)); + GPR_ASSERT((calld->waiting_op.recv_ops == NULL) != + (op->recv_ops == NULL)); + if (op->send_ops != NULL) { + calld->waiting_op.send_ops = op->send_ops; + calld->waiting_op.is_last_send = op->is_last_send; + calld->waiting_op.on_done_send = op->on_done_send; + } + if (op->recv_ops != NULL) { + calld->waiting_op.recv_ops = op->recv_ops; + calld->waiting_op.recv_state = op->recv_state; + calld->waiting_op.on_done_recv = op->on_done_recv; + } + gpr_mu_unlock(&calld->mu_state); + if (op->on_consumed != NULL) { + op->on_consumed->cb(op->on_consumed->cb_arg, 0); + } + } + break; + } + /* fall through */ case CALL_CREATED: if (op->cancel_with_status != GRPC_STATUS_OK) { calld->state = CALL_CANCELLED; gpr_mu_unlock(&calld->mu_state); handle_op_after_cancellation(elem, op); } else { - calld->s.waiting_op = *op; + calld->waiting_op = *op; gpr_mu_lock(&chand->mu_config); lb_policy = chand->lb_policy; @@ -235,141 +360,22 @@ static void cc_start_transport_stream_op(grpc_call_element *elem, grpc_lb_policy_unref(lb_policy); } else { calld->state = CALL_WAITING_FOR_CONFIG; - add_to_lb_policy_wait_queue_locked_state_config(chand, calld); + add_to_lb_policy_wait_queue_locked_state_config(elem); gpr_mu_unlock(&chand->mu_config); gpr_mu_unlock(&calld->mu_state); } } break; - case CALL_WAITING_FOR_CONFIG: - case CALL_WAITING_FOR_PICK: - if (op->cancel_with_status != GRPC_STATUS_OK) { - calld->state = CALL_CANCELLED; - gpr_mu_unlock(&calld->mu_state); - handle_op_after_cancellation(elem, op); - } else { - GPR_ASSERT((calld->s.waiting_op.send_ops == NULL) != - (op->send_ops == NULL)); - GPR_ASSERT((calld->s.waiting_op.recv_ops == NULL) != - (op->recv_ops == NULL)); - if (op->send_ops != NULL) { - calld->s.waiting_op.send_ops = op->send_ops; - calld->s.waiting_op.is_last_send = op->is_last_send; - calld->s.waiting_op.on_done_send = op->on_done_send; - } - if (op->recv_ops != NULL) { - calld->s.waiting_op.recv_ops = op->recv_ops; - calld->s.waiting_op.recv_state = op->recv_state; - calld->s.waiting_op.on_done_recv = op->on_done_recv; - } - gpr_mu_unlock(&calld->mu_state); - if (op->on_consumed != NULL) { - op->on_consumed->cb(op->on_consumed->cb_arg, 0); - } - } - break; } +} - - - -#if 0 - gpr_mu_lock(&chand->mu); - switch (calld->state) { - case CALL_ACTIVE: - child_elem = grpc_child_call_get_top_element(calld->s.active.child_call); - gpr_mu_unlock(&chand->mu); - child_elem->filter->start_transport_op(child_elem, op); - break; - case CALL_CREATED: - if (op->cancel_with_status != GRPC_STATUS_OK) { - calld->state = CALL_CANCELLED; - gpr_mu_unlock(&chand->mu); - handle_op_after_cancellation(elem, op); - } else { - calld->state = CALL_WAITING; - calld->s.waiting_op.bind_pollset = NULL; - if (chand->active_child) { - /* channel is connected - use the connected stack */ - if (prepare_activate(elem, chand->active_child)) { - gpr_mu_unlock(&chand->mu); - /* activate the request (pass it down) outside the lock */ - complete_activate(elem, op); - } else { - gpr_mu_unlock(&chand->mu); - } - } else { - /* check to see if we should initiate a connection (if we're not - already), - but don't do so until outside the lock to avoid re-entrancy - problems if - the callback is immediate */ - int initiate_transport_setup = 0; - if (!chand->transport_setup_initiated) { - chand->transport_setup_initiated = 1; - initiate_transport_setup = 1; - } - /* add this call to the waiting set to be resumed once we have a child - channel stack, growing the waiting set if needed */ - if (chand->waiting_child_count == chand->waiting_child_capacity) { - chand->waiting_child_capacity = - GPR_MAX(chand->waiting_child_capacity * 2, 8); - chand->waiting_children = gpr_realloc( - chand->waiting_children, - chand->waiting_child_capacity * sizeof(call_data *)); - } - calld->s.waiting_op = *op; - chand->waiting_children[chand->waiting_child_count++] = calld; - grpc_transport_setup_add_interested_party(chand->transport_setup, - op->bind_pollset); - gpr_mu_unlock(&chand->mu); - - /* finally initiate transport setup if needed */ - if (initiate_transport_setup) { - grpc_transport_setup_initiate(chand->transport_setup); - } - } - } - break; - case CALL_WAITING: - if (op->cancel_with_status != GRPC_STATUS_OK) { - waiting_op = calld->s.waiting_op; - remove_waiting_child(chand, calld); - calld->state = CALL_CANCELLED; - gpr_mu_unlock(&chand->mu); - handle_op_after_cancellation(elem, &waiting_op); - handle_op_after_cancellation(elem, op); - } else { - GPR_ASSERT((calld->s.waiting_op.send_ops == NULL) != - (op->send_ops == NULL)); - GPR_ASSERT((calld->s.waiting_op.recv_ops == NULL) != - (op->recv_ops == NULL)); - if (op->send_ops) { - calld->s.waiting_op.send_ops = op->send_ops; - calld->s.waiting_op.is_last_send = op->is_last_send; - calld->s.waiting_op.on_done_send = op->on_done_send; - } - if (op->recv_ops) { - calld->s.waiting_op.recv_ops = op->recv_ops; - calld->s.waiting_op.recv_state = op->recv_state; - calld->s.waiting_op.on_done_recv = op->on_done_recv; - } - gpr_mu_unlock(&chand->mu); - if (op->on_consumed) { - op->on_consumed->cb(op->on_consumed->cb_arg, 0); - } - } - break; - case CALL_CANCELLED: - gpr_mu_unlock(&chand->mu); - handle_op_after_cancellation(elem, op); - break; - } -#endif +static void cc_start_transport_stream_op(grpc_call_element *elem, + grpc_transport_stream_op *op) { + perform_transport_stream_op(elem, op, 0); } static void update_state_locked(channel_data *chand) { - + gpr_log(GPR_ERROR, "update_state_locked not implemented"); } static void cc_on_config_changed(void *arg, int iomgr_success) { @@ -382,9 +388,10 @@ static void cc_on_config_changed(void *arg, int iomgr_success) { if (chand->incoming_configuration) { lb_policy = grpc_client_config_get_lb_policy(chand->incoming_configuration); grpc_lb_policy_ref(lb_policy); + + grpc_client_config_unref(chand->incoming_configuration); } - grpc_client_config_unref(chand->incoming_configuration); chand->incoming_configuration = NULL; gpr_mu_lock(&chand->mu_config); @@ -402,7 +409,9 @@ static void cc_on_config_changed(void *arg, int iomgr_success) { wakeup_closures = next; } - grpc_lb_policy_unref(old_lb_policy); + if (old_lb_policy) { + grpc_lb_policy_unref(old_lb_policy); + } if (iomgr_success) { grpc_resolver_next(chand->resolver, &chand->incoming_configuration, &chand->on_config_changed); @@ -511,6 +520,7 @@ static void init_call_elem(grpc_call_element *elem, GPR_ASSERT(elem->filter == &grpc_client_channel_filter); GPR_ASSERT(server_transport_data == NULL); + gpr_mu_init(&calld->mu_state); calld->elem = elem; calld->state = CALL_CREATED; calld->deadline = gpr_inf_future; @@ -527,7 +537,7 @@ static void destroy_call_elem(grpc_call_element *elem) { gpr_mu_lock(&calld->mu_state); switch (calld->state) { case CALL_ACTIVE: - subchannel_call = calld->s.active.subchannel_call; + subchannel_call = calld->subchannel_call; gpr_mu_unlock(&calld->mu_state); grpc_subchannel_call_unref(subchannel_call); break; @@ -537,6 +547,7 @@ static void destroy_call_elem(grpc_call_element *elem) { break; case CALL_WAITING_FOR_PICK: case CALL_WAITING_FOR_CONFIG: + case CALL_WAITING_FOR_CALL: gpr_log(GPR_ERROR, "should never reach here"); abort(); break; @@ -550,12 +561,12 @@ static void init_channel_elem(grpc_channel_element *elem, int is_last) { channel_data *chand = elem->channel_data; - GPR_ASSERT(!is_first); + memset(chand, 0, sizeof(*chand)); + GPR_ASSERT(is_last); GPR_ASSERT(elem->filter == &grpc_client_channel_filter); gpr_mu_init(&chand->mu_config); - chand->resolver = NULL; chand->mdctx = metadata_context; grpc_iomgr_closure_init(&chand->on_config_changed, cc_on_config_changed, chand); } @@ -633,7 +644,7 @@ grpc_transport_setup_result grpc_client_channel_transport_setup_complete( call_ops = gpr_malloc(sizeof(*call_ops) * waiting_child_count); for (i = 0; i < waiting_child_count; i++) { - call_ops[i] = waiting_children[i]->s.waiting_op; + call_ops[i] = waiting_children[i]->waiting_op; if (!prepare_activate(waiting_children[i]->elem, chand->active_child)) { waiting_children[i] = NULL; grpc_transport_stream_op_finish_with_failure(&call_ops[i]); diff --git a/src/core/client_config/client_config.c b/src/core/client_config/client_config.c index e7d7647b88..bc8dcec54e 100644 --- a/src/core/client_config/client_config.c +++ b/src/core/client_config/client_config.c @@ -61,7 +61,7 @@ void grpc_client_config_unref(grpc_client_config *c) { void grpc_client_config_set_lb_policy(grpc_client_config *c, grpc_lb_policy *lb_policy) { if (lb_policy) { - grpc_lb_policy_ref(c->lb_policy); + grpc_lb_policy_ref(lb_policy); } if (c->lb_policy) { grpc_lb_policy_unref(c->lb_policy); diff --git a/src/core/client_config/lb_policies/pick_first.c b/src/core/client_config/lb_policies/pick_first.c index 46732b8444..83a25a9a72 100644 --- a/src/core/client_config/lb_policies/pick_first.c +++ b/src/core/client_config/lb_policies/pick_first.c @@ -32,3 +32,172 @@ */ #include "src/core/client_config/lb_policies/pick_first.h" + +#include + +#include + +typedef struct pending_pick { + struct pending_pick *next; + grpc_pollset *pollset; + grpc_subchannel **target; + grpc_iomgr_closure *on_complete; +} pending_pick; + +typedef struct { + /** base policy: must be first */ + grpc_lb_policy base; + /** ref count */ + gpr_refcount refs; + /** all our subchannels */ + grpc_subchannel **subchannels; + size_t num_subchannels; + + grpc_iomgr_closure connectivity_changed; + + /** mutex protecting remaining members */ + gpr_mu mu; + /** the selected channel + TODO(ctiller): this should be atomically set so we don't + need to take a mutex in the common case */ + grpc_subchannel *selected; + /** have we started picking? */ + int started_picking; + /** which subchannel are we watching? */ + size_t checking_subchannel; + /** what is the connectivity of that channel? */ + grpc_connectivity_state checking_connectivity; + /** list of picks that are waiting on connectivity */ + pending_pick *pending_picks; +} pick_first_lb_policy; + +void pf_ref(grpc_lb_policy *pol) { + pick_first_lb_policy *p = (pick_first_lb_policy *)pol; + gpr_ref(&p->refs); +} + +void pf_unref(grpc_lb_policy *pol) { + pick_first_lb_policy *p = (pick_first_lb_policy *)pol; + if (gpr_unref(&p->refs)) { + gpr_free(p->subchannels); + gpr_mu_destroy(&p->mu); + gpr_free(p); + } +} + +void pf_shutdown(grpc_lb_policy *pol) { + /* pick_first_lb_policy *p = (pick_first_lb_policy*)pol; */ + abort(); +} + +void pf_pick(grpc_lb_policy *pol, grpc_pollset *pollset, + grpc_metadata_batch *initial_metadata, grpc_subchannel **target, + grpc_iomgr_closure *on_complete) { + pick_first_lb_policy *p = (pick_first_lb_policy*)pol; + pending_pick *pp; + gpr_mu_lock(&p->mu); + if (p->selected) { + gpr_mu_unlock(&p->mu); + *target = p->selected; + on_complete->cb(on_complete->cb_arg, 1); + } else { + if (!p->started_picking) { + p->started_picking = 1; + p->checking_subchannel = 0; + p->checking_connectivity = GRPC_CHANNEL_IDLE; + pf_ref(pol); + grpc_subchannel_notify_on_state_change(p->subchannels[0], &p->checking_connectivity, &p->connectivity_changed); + } + grpc_subchannel_add_interested_party(p->subchannels[p->checking_subchannel], pollset); + pp = gpr_malloc(sizeof(*pp)); + pp->next = p->pending_picks; + pp->pollset = pollset; + pp->target = target; + pp->on_complete = on_complete; + p->pending_picks = pp; + gpr_mu_unlock(&p->mu); + } +} + +static void del_interested_parties_locked(pick_first_lb_policy *p) { + pending_pick *pp; + for (pp = p->pending_picks; pp; pp = pp->next) { + grpc_subchannel_del_interested_party(p->subchannels[p->checking_subchannel], pp->pollset); + } +} + +static void add_interested_parties_locked(pick_first_lb_policy *p) { + pending_pick *pp; + for (pp = p->pending_picks; pp; pp = pp->next) { + grpc_subchannel_add_interested_party(p->subchannels[p->checking_subchannel], pp->pollset); + } +} + +static void pf_connectivity_changed(void *arg, int iomgr_success) { + pick_first_lb_policy *p = arg; + pending_pick *pp; + int unref = 0; + + gpr_mu_lock(&p->mu); +loop: + switch (p->checking_connectivity) { + case GRPC_CHANNEL_READY: + p->selected = p->subchannels[p->checking_connectivity]; + while ((pp = p->pending_picks)) { + p->pending_picks = pp->next; + *pp->target = p->selected; + grpc_subchannel_del_interested_party(p->selected, pp->pollset); + grpc_iomgr_add_delayed_callback(pp->on_complete, 1); + gpr_free(pp); + } + unref = 1; + break; + case GRPC_CHANNEL_TRANSIENT_FAILURE: + del_interested_parties_locked(p); + p->checking_subchannel = (p->checking_subchannel + 1) % p->num_subchannels; + p->checking_connectivity = grpc_subchannel_check_connectivity(p->subchannels[p->checking_subchannel]); + add_interested_parties_locked(p); + goto loop; + case GRPC_CHANNEL_CONNECTING: + case GRPC_CHANNEL_IDLE: + grpc_subchannel_notify_on_state_change(p->subchannels[p->checking_subchannel], &p->checking_connectivity, &p->connectivity_changed); + break; + case GRPC_CHANNEL_FATAL_FAILURE: + del_interested_parties_locked(p); + GPR_SWAP(grpc_subchannel *, p->subchannels[p->checking_subchannel], p->subchannels[p->num_subchannels - 1]); + p->checking_subchannel %= p->num_subchannels; + p->checking_connectivity = grpc_subchannel_check_connectivity(p->subchannels[p->checking_subchannel]); + p->num_subchannels--; + grpc_subchannel_unref(p->subchannels[p->num_subchannels]); + add_interested_parties_locked(p); + if (p->num_subchannels == 0) { + abort(); + } else { + goto loop; + } + } + gpr_mu_unlock(&p->mu); + + if (unref) { + pf_unref(&p->base); + } +} + +static const grpc_lb_policy_vtable pick_first_lb_policy_vtable = { + pf_ref, pf_unref, pf_shutdown, pf_pick}; + +grpc_lb_policy *grpc_create_pick_first_lb_policy(grpc_subchannel **subchannels, + size_t num_subchannels) { + pick_first_lb_policy *p = gpr_malloc(sizeof(*p)); + GPR_ASSERT(num_subchannels); + memset(p, 0, sizeof(*p)); + p->base.vtable = &pick_first_lb_policy_vtable; + gpr_ref_init(&p->refs, 1); + p->subchannels = gpr_malloc(sizeof(grpc_subchannel *) * num_subchannels); + p->num_subchannels = num_subchannels; + memcpy(p->subchannels, subchannels, + sizeof(grpc_subchannel *) * num_subchannels); + grpc_iomgr_closure_init(&p->connectivity_changed, pf_connectivity_changed, p); + gpr_mu_init(&p->mu); + return &p->base; +} diff --git a/src/core/client_config/lb_policy.h b/src/core/client_config/lb_policy.h index 4e185d9086..42929e933b 100644 --- a/src/core/client_config/lb_policy.h +++ b/src/core/client_config/lb_policy.h @@ -45,7 +45,7 @@ typedef void (*grpc_lb_completion)(void *cb_arg, grpc_subchannel *subchannel, grpc_status_code status, const char *errmsg); struct grpc_lb_policy { - grpc_lb_policy_vtable *vtable; + const grpc_lb_policy_vtable *vtable; }; struct grpc_lb_policy_vtable { diff --git a/src/core/client_config/resolver_factory.c b/src/core/client_config/resolver_factory.c index 378529d5b2..6721977e21 100644 --- a/src/core/client_config/resolver_factory.c +++ b/src/core/client_config/resolver_factory.c @@ -45,5 +45,6 @@ void grpc_resolver_factory_unref(grpc_resolver_factory *factory) { grpc_resolver *grpc_resolver_factory_create_resolver( grpc_resolver_factory *factory, grpc_uri *uri, grpc_subchannel_factory *subchannel_factory) { + if (!factory) return NULL; return factory->vtable->create_resolver(factory, uri, subchannel_factory); } diff --git a/src/core/client_config/resolver_registry.c b/src/core/client_config/resolver_registry.c index 770d4aca8e..abdb5f9377 100644 --- a/src/core/client_config/resolver_registry.c +++ b/src/core/client_config/resolver_registry.c @@ -46,57 +46,76 @@ typedef struct { grpc_resolver_factory *factory; } registered_resolver; -static registered_resolver all_of_the_resolvers[MAX_RESOLVERS]; -static int number_of_resolvers = 0; +static registered_resolver g_all_of_the_resolvers[MAX_RESOLVERS]; +static int g_number_of_resolvers = 0; -void grpc_resolver_registry_init(grpc_resolver_factory *r) { - number_of_resolvers = 0; - grpc_register_resolver_type("default-grpc-resolver", r); +static char *g_default_resolver_scheme; + +void grpc_resolver_registry_init(const char *default_resolver_scheme) { + g_number_of_resolvers = 0; + g_default_resolver_scheme = gpr_strdup(default_resolver_scheme); } void grpc_resolver_registry_shutdown(void) { int i; - for (i = 0; i < number_of_resolvers; i++) { - gpr_free(all_of_the_resolvers[i].scheme); - grpc_resolver_factory_unref(all_of_the_resolvers[i].factory); + for (i = 0; i < g_number_of_resolvers; i++) { + gpr_free(g_all_of_the_resolvers[i].scheme); + grpc_resolver_factory_unref(g_all_of_the_resolvers[i].factory); } + gpr_free(g_default_resolver_scheme); } void grpc_register_resolver_type(const char *scheme, grpc_resolver_factory *factory) { int i; - for (i = 0; i < number_of_resolvers; i++) { - GPR_ASSERT(0 != strcmp(scheme, all_of_the_resolvers[i].scheme)); + for (i = 0; i < g_number_of_resolvers; i++) { + GPR_ASSERT(0 != strcmp(scheme, g_all_of_the_resolvers[i].scheme)); } - GPR_ASSERT(number_of_resolvers != MAX_RESOLVERS); - all_of_the_resolvers[number_of_resolvers].scheme = gpr_strdup(scheme); + GPR_ASSERT(g_number_of_resolvers != MAX_RESOLVERS); + g_all_of_the_resolvers[g_number_of_resolvers].scheme = gpr_strdup(scheme); grpc_resolver_factory_ref(factory); - all_of_the_resolvers[number_of_resolvers].factory = factory; - number_of_resolvers++; + g_all_of_the_resolvers[g_number_of_resolvers].factory = factory; + g_number_of_resolvers++; +} + +static grpc_resolver_factory *lookup_factory(grpc_uri *uri) { + int i; + + /* handling NULL uri's here simplifies grpc_resolver_create */ + if (!uri) return NULL; + + for (i = 0; i < g_number_of_resolvers; i++) { + if (0 == strcmp(uri->scheme, g_all_of_the_resolvers[i].scheme)) { + return g_all_of_the_resolvers[i].factory; + } + } + + return NULL; } grpc_resolver *grpc_resolver_create( const char *name, grpc_subchannel_factory *subchannel_factory) { grpc_uri *uri; - int i; char *tmp; - grpc_resolver *resolver = NULL; - if (grpc_has_scheme(name)) { - uri = grpc_uri_parse(name); - if (!uri) { - return NULL; - } - for (i = 0; i < number_of_resolvers; i++) { - if (0 == strcmp(all_of_the_resolvers[i].scheme, uri->scheme)) { - grpc_resolver_factory_create_resolver(all_of_the_resolvers[i].factory, - uri, subchannel_factory); - } + grpc_resolver_factory *factory = NULL; + grpc_resolver *resolver; + + uri = grpc_uri_parse(name); + factory = lookup_factory(uri); + if (factory == NULL && g_default_resolver_scheme != NULL) { + grpc_uri_destroy(uri); + gpr_asprintf(&tmp, "%s%s", g_default_resolver_scheme, name); + uri = grpc_uri_parse(tmp); + factory = lookup_factory(uri); + if (factory == NULL) { + gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", name, tmp); } - } else { - gpr_asprintf(&tmp, "default-grpc-resolver:%s", name); - GPR_ASSERT(grpc_has_scheme(tmp)); - resolver = grpc_resolver_create(tmp, subchannel_factory); gpr_free(tmp); + } else if (factory == NULL) { + gpr_log(GPR_ERROR, "don't know how to resolve '%s'", name); } + resolver = + grpc_resolver_factory_create_resolver(factory, uri, subchannel_factory); + grpc_uri_destroy(uri); return resolver; } diff --git a/src/core/client_config/resolver_registry.h b/src/core/client_config/resolver_registry.h index 53335172da..31aa47620a 100644 --- a/src/core/client_config/resolver_registry.h +++ b/src/core/client_config/resolver_registry.h @@ -36,7 +36,7 @@ #include "src/core/client_config/resolver_factory.h" -void grpc_resolver_registry_init(grpc_resolver_factory *default_resolver); +void grpc_resolver_registry_init(const char *default_prefix); void grpc_resolver_registry_shutdown(void); /** Register a resolver type. @@ -47,7 +47,15 @@ void grpc_resolver_registry_shutdown(void); void grpc_register_resolver_type(const char *scheme, grpc_resolver_factory *factory); -/** Create a resolver given a \a uri string (with an optional scheme prefix) */ +/** Create a resolver given \a name. + First tries to parse \a name as a URI. If this succeeds, tries + to locate a registered resolver factory based on the URI scheme. + If parsing or location fails, prefixes default_prefix from + grpc_resolver_registry_init to name, and tries again (if default_prefix + was not NULL). + If a resolver factory was found, use it to instantiate a resolver and + return it. + If a resolver factory was not found, return NULL. */ grpc_resolver *grpc_resolver_create( const char *name, grpc_subchannel_factory *subchannel_factory); diff --git a/src/core/client_config/resolvers/dns_resolver.c b/src/core/client_config/resolvers/dns_resolver.c index 95f38ecab7..ba82675275 100644 --- a/src/core/client_config/resolvers/dns_resolver.c +++ b/src/core/client_config/resolvers/dns_resolver.c @@ -38,6 +38,7 @@ #include #include +#include "src/core/client_config/lb_policies/pick_first.h" #include "src/core/iomgr/resolve_address.h" #include "src/core/support/string.h" @@ -177,6 +178,8 @@ static void dns_start_resolving_locked(dns_resolver *r) { static void dns_maybe_finish_next_locked(dns_resolver *r) { if (r->next_completion != NULL && r->resolved_version != r->published_version) { + *r->target_config = r->resolved_config; + grpc_client_config_ref(r->resolved_config); grpc_iomgr_add_callback(r->next_completion); r->next_completion = NULL; r->published_version = r->resolved_version; @@ -191,8 +194,11 @@ static void dns_destroy(dns_resolver *r) { gpr_free(r); } -static grpc_resolver *dns_create(grpc_uri *uri, const char *default_port, - grpc_subchannel_factory *subchannel_factory) { +static grpc_resolver *dns_create( + grpc_uri *uri, const char *default_port, + grpc_lb_policy *(*lb_policy_factory)(grpc_subchannel **subchannels, + size_t num_subchannels), + grpc_subchannel_factory *subchannel_factory) { dns_resolver *r; const char *path = uri->path; @@ -211,6 +217,7 @@ static grpc_resolver *dns_create(grpc_uri *uri, const char *default_port, r->name = gpr_strdup(path); r->default_port = gpr_strdup(default_port); r->subchannel_factory = subchannel_factory; + r->lb_policy_factory = lb_policy_factory; grpc_subchannel_factory_ref(subchannel_factory); return &r->base; } @@ -219,43 +226,21 @@ static grpc_resolver *dns_create(grpc_uri *uri, const char *default_port, * FACTORY */ -typedef struct { - /** base: must be first */ - grpc_resolver_factory base; - /** ref count */ - gpr_refcount refs; - /** default port */ - char *default_port; -} dns_resolver_factory; - -static void dns_factory_ref(grpc_resolver_factory *factory) { - dns_resolver_factory *f = (dns_resolver_factory *)factory; - gpr_ref(&f->refs); -} +static void dns_factory_ref(grpc_resolver_factory *factory) {} -static void dns_factory_unref(grpc_resolver_factory *factory) { - dns_resolver_factory *f = (dns_resolver_factory *)factory; - if (gpr_unref(&f->refs)) { - gpr_free(f->default_port); - gpr_free(f); - } -} +static void dns_factory_unref(grpc_resolver_factory *factory) {} static grpc_resolver *dns_factory_create_resolver( grpc_resolver_factory *factory, grpc_uri *uri, grpc_subchannel_factory *subchannel_factory) { - dns_resolver_factory *f = (dns_resolver_factory *)factory; - return dns_create(uri, f->default_port, subchannel_factory); + return dns_create(uri, "https", grpc_create_pick_first_lb_policy, + subchannel_factory); } static const grpc_resolver_factory_vtable dns_factory_vtable = { dns_factory_ref, dns_factory_unref, dns_factory_create_resolver}; +static grpc_resolver_factory dns_resolver_factory = {&dns_factory_vtable}; -grpc_resolver_factory *grpc_dns_resolver_factory_create( - const char *default_port) { - dns_resolver_factory *f = gpr_malloc(sizeof(*f)); - memset(f, 0, sizeof(*f)); - f->base.vtable = &dns_factory_vtable; - f->default_port = gpr_strdup(default_port); - return &f->base; +grpc_resolver_factory *grpc_dns_resolver_factory_create() { + return &dns_resolver_factory; } diff --git a/src/core/client_config/resolvers/dns_resolver.h b/src/core/client_config/resolvers/dns_resolver.h index 9881448fd8..09322b16cf 100644 --- a/src/core/client_config/resolvers/dns_resolver.h +++ b/src/core/client_config/resolvers/dns_resolver.h @@ -37,7 +37,6 @@ #include "src/core/client_config/resolver_factory.h" /** Create a dns resolver for \a name */ -grpc_resolver_factory *grpc_dns_resolver_factory_create( - const char *default_port); +grpc_resolver_factory *grpc_dns_resolver_factory_create(void); #endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H */ diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c index 037f0c0ab0..9637cf39fe 100644 --- a/src/core/client_config/subchannel.c +++ b/src/core/client_config/subchannel.c @@ -37,6 +37,13 @@ #include +#include "src/core/channel/channel_args.h" + +typedef struct { + gpr_refcount refs; + grpc_subchannel *subchannel; +} connection; + struct grpc_subchannel { gpr_refcount refs; grpc_connector *connector; @@ -49,24 +56,45 @@ struct grpc_subchannel { /** address to connect to */ struct sockaddr *addr; size_t addr_len; + + /** set during connection */ + grpc_transport *connecting_transport; + + /** callback for connection finishing */ + grpc_iomgr_closure connected; + + /** mutex protecting remaining elements */ + gpr_mu mu; + + /** active connection */ + connection *active; + /** are we connecting */ + int connecting; + /** closures waiting for a connection */ + grpc_iomgr_closure *waiting; }; struct grpc_subchannel_call { - grpc_subchannel *subchannel; + connection *connection; gpr_refcount refs; }; #define SUBCHANNEL_CALL_TO_CALL_STACK(call) (((grpc_call_stack *)(call)) + 1) +static grpc_subchannel_call *create_call(connection *con, grpc_transport_stream_op *initial_op); + /* * grpc_subchannel implementation */ -void grpc_subchannel_ref(grpc_subchannel *channel) { gpr_ref(&channel->refs); } +void grpc_subchannel_ref(grpc_subchannel *c) { gpr_ref(&c->refs); } -void grpc_subchannel_unref(grpc_subchannel *channel) { - if (gpr_unref(&channel->refs)) { - gpr_free(channel); +void grpc_subchannel_unref(grpc_subchannel *c) { + if (gpr_unref(&c->refs)) { + gpr_free(c->filters); + grpc_channel_args_destroy(c->args); + gpr_free(c->addr); + gpr_free(c); } } @@ -84,9 +112,39 @@ grpc_subchannel *grpc_subchannel_create(grpc_connector *connector, c->addr = gpr_malloc(args->addr_len); memcpy(c->addr, args->addr, args->addr_len); c->addr_len = args->addr_len; + c->args = grpc_channel_args_copy(args->args); + gpr_mu_init(&c->mu); return c; } +void grpc_subchannel_create_call(grpc_subchannel *c, + grpc_mdctx *mdctx, + grpc_transport_stream_op *initial_op, + grpc_subchannel_call **target, + grpc_iomgr_closure *notify) { + connection *con; + gpr_mu_lock(&c->mu); + if (c->active != NULL) { + con = c->active; + gpr_ref(&con->refs); + gpr_mu_unlock(&c->mu); + + *target = create_call(con, initial_op); + notify->cb(notify->cb_arg, 1); + } else { + notify->next = c->waiting; + c->waiting = notify; + if (!c->connecting) { + c->connecting = 1; + gpr_mu_unlock(&c->mu); + + grpc_connector_connect(c->connector, c->args, mdctx, &c->connecting_transport, &c->connected); + } else { + gpr_mu_unlock(&c->mu); + } + } +} + /* * grpc_subchannel_call implementation */ @@ -98,7 +156,9 @@ void grpc_subchannel_call_ref(grpc_subchannel_call *call) { void grpc_subchannel_call_unref(grpc_subchannel_call *call) { if (gpr_unref(&call->refs)) { grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(call)); - grpc_subchannel_unref(call->subchannel); + if (gpr_unref(&call->connection->refs)) { + gpr_free(call->connection); + } gpr_free(call); } } @@ -109,3 +169,8 @@ void grpc_subchannel_call_process_op(grpc_subchannel_call *call, grpc_call_element *top_elem = grpc_call_stack_element(call_stack, 0); top_elem->filter->start_transport_stream_op(top_elem, op); } + +grpc_subchannel_call *create_call(connection *con, grpc_transport_stream_op *initial_op) { + abort(); + return NULL; +} diff --git a/src/core/client_config/subchannel.h b/src/core/client_config/subchannel.h index b4d40eadfa..8b3d82eb0a 100644 --- a/src/core/client_config/subchannel.h +++ b/src/core/client_config/subchannel.h @@ -59,9 +59,12 @@ void grpc_subchannel_notify_on_state_change(grpc_subchannel *channel, grpc_connectivity_state *state, grpc_iomgr_closure *notify); +void grpc_subchannel_add_interested_party(grpc_subchannel *channel, grpc_pollset *pollset); +void grpc_subchannel_del_interested_party(grpc_subchannel *channel, grpc_pollset *pollset); + /** construct a call (possibly asynchronously) */ void grpc_subchannel_create_call(grpc_subchannel *subchannel, - grpc_call_element *parent, + grpc_mdctx *mdctx, grpc_transport_stream_op *initial_op, grpc_subchannel_call **target, grpc_iomgr_closure *notify); diff --git a/src/core/client_config/subchannel_factory.c b/src/core/client_config/subchannel_factory.c index 06e8a4bdaf..f71386594c 100644 --- a/src/core/client_config/subchannel_factory.c +++ b/src/core/client_config/subchannel_factory.c @@ -32,3 +32,15 @@ */ #include "src/core/client_config/subchannel_factory.h" + +void grpc_subchannel_factory_ref(grpc_subchannel_factory *factory) { + factory->vtable->ref(factory); +} +void grpc_subchannel_factory_unref(grpc_subchannel_factory *factory) { + factory->vtable->unref(factory); +} + +grpc_subchannel *grpc_subchannel_factory_create_subchannel( + grpc_subchannel_factory *factory, grpc_subchannel_args *args) { + return factory->vtable->create_subchannel(factory, args); +} diff --git a/src/core/client_config/uri_parser.c b/src/core/client_config/uri_parser.c index 24dfaae497..43b5b47f55 100644 --- a/src/core/client_config/uri_parser.c +++ b/src/core/client_config/uri_parser.c @@ -64,30 +64,6 @@ static char *copy_fragment(const char *src, int begin, int end) { return out; } -int grpc_has_scheme(const char *uri_text) { - int scheme_begin = 0; - int scheme_end = -1; - int i; - - for (i = scheme_begin; uri_text[i] != 0; i++) { - if (uri_text[i] == ':') { - scheme_end = i; - break; - } - if (uri_text[i] >= 'a' && uri_text[i] <= 'z') continue; - if (uri_text[i] >= 'A' && uri_text[i] <= 'Z') continue; - if (i != scheme_begin) { - if (uri_text[i] >= '0' && uri_text[i] <= '9') continue; - if (uri_text[i] == '+') continue; - if (uri_text[i] == '-') continue; - if (uri_text[i] == '.') continue; - } - break; - } - - return scheme_end != -1; -} - grpc_uri *grpc_uri_parse(const char *uri_text) { grpc_uri *uri; int scheme_begin = 0; @@ -162,6 +138,7 @@ grpc_uri *grpc_uri_parse(const char *uri_text) { } void grpc_uri_destroy(grpc_uri *uri) { + if (!uri) return; gpr_free(uri->scheme); gpr_free(uri->authority); gpr_free(uri->path); diff --git a/src/core/client_config/uri_parser.h b/src/core/client_config/uri_parser.h index 0e21d568a9..b6821f9621 100644 --- a/src/core/client_config/uri_parser.h +++ b/src/core/client_config/uri_parser.h @@ -43,9 +43,6 @@ typedef struct { /** parse a uri, return NULL on failure */ grpc_uri *grpc_uri_parse(const char *uri_text); -/** return 1 if uri_text has something that is likely a scheme, 0 otherwise */ -int grpc_has_scheme(const char *uri_text); - /** destroy a uri */ void grpc_uri_destroy(grpc_uri *uri); diff --git a/src/core/surface/init.c b/src/core/surface/init.c index ca61a38a35..03add81466 100644 --- a/src/core/surface/init.c +++ b/src/core/surface/init.c @@ -34,6 +34,8 @@ #include #include #include "src/core/channel/channel_stack.h" +#include "src/core/client_config/resolver_registry.h" +#include "src/core/client_config/resolvers/dns_resolver.h" #include "src/core/debug/trace.h" #include "src/core/iomgr/iomgr.h" #include "src/core/profiling/timers.h" @@ -56,6 +58,8 @@ void grpc_init(void) { gpr_mu_lock(&g_init_mu); if (++g_initializations == 1) { + grpc_resolver_registry_init("dns:///"); + grpc_register_resolver_type("dns", grpc_dns_resolver_factory_create()); grpc_register_tracer("channel", &grpc_trace_channel); grpc_register_tracer("surface", &grpc_surface_trace); grpc_register_tracer("http", &grpc_http_trace); diff --git a/test/core/end2end/fixtures/chttp2_fullstack.c b/test/core/end2end/fixtures/chttp2_fullstack.c index e647434509..8a1530e63b 100644 --- a/test/core/end2end/fixtures/chttp2_fullstack.c +++ b/test/core/end2end/fixtures/chttp2_fullstack.c @@ -73,6 +73,7 @@ void chttp2_init_client_fullstack(grpc_end2end_test_fixture *f, grpc_channel_args *client_args) { fullstack_fixture_data *ffd = f->fixture_data; f->client = grpc_channel_create(ffd->localaddr, client_args); + GPR_ASSERT(f->client); } void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f, -- cgit v1.2.3 From 5f84c8478ab61c30cc98d956bbe327e02142d2e6 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Fri, 26 Jun 2015 16:08:21 -0700 Subject: Connector progress --- src/core/channel/client_channel.c | 5 +- src/core/client_config/connector.c | 14 ++-- src/core/client_config/connector.h | 16 +++-- src/core/client_config/subchannel.c | 130 ++++++++++++++++++++++++++++++++++-- src/core/client_config/subchannel.h | 3 +- src/core/surface/channel_create.c | 67 +++++++++++++++++-- 6 files changed, 205 insertions(+), 30 deletions(-) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index 965d4e53dc..dc838de715 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -249,7 +249,6 @@ static void started_call(void *arg, int iomgr_success) { static void picked_target(void *arg, int iomgr_success) { call_data *calld = arg; - channel_data *chand = calld->elem->channel_data; grpc_transport_stream_op op; if (calld->picked_channel == NULL) { @@ -268,7 +267,9 @@ static void picked_target(void *arg, int iomgr_success) { memset(&calld->waiting_op, 0, sizeof(calld->waiting_op)); gpr_mu_unlock(&calld->mu_state); grpc_iomgr_closure_init(&calld->async_setup_task, started_call, calld); - grpc_subchannel_create_call(calld->picked_channel, chand->mdctx, &op, &calld->subchannel_call, &calld->async_setup_task); + grpc_subchannel_create_call(calld->picked_channel, &op, + &calld->subchannel_call, + &calld->async_setup_task); } } } diff --git a/src/core/client_config/connector.c b/src/core/client_config/connector.c index c3a8962ea6..60c392f85b 100644 --- a/src/core/client_config/connector.c +++ b/src/core/client_config/connector.c @@ -41,11 +41,11 @@ void grpc_connector_unref(grpc_connector *connector) { connector->vtable->unref(connector); } -void grpc_connector_connect(grpc_connector *connector, - const grpc_channel_args *channel_args, - grpc_mdctx *metadata_context, - grpc_transport **transport, - grpc_iomgr_closure *notify) { - connector->vtable->connect(connector, channel_args, metadata_context, - transport, notify); +void grpc_connector_connect( + grpc_connector *connector, grpc_pollset_set *pollset_set, + const struct sockaddr *addr, int addr_len, gpr_timespec deadline, + const grpc_channel_args *channel_args, grpc_mdctx *metadata_context, + grpc_transport **transport, grpc_iomgr_closure *notify) { + connector->vtable->connect(connector, pollset_set, addr, addr_len, deadline, + channel_args, metadata_context, transport, notify); } diff --git a/src/core/client_config/connector.h b/src/core/client_config/connector.h index 8ada75ec70..7241437729 100644 --- a/src/core/client_config/connector.h +++ b/src/core/client_config/connector.h @@ -34,6 +34,7 @@ #ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_CONNECTOR_H #define GRPC_INTERNAL_CORE_CLIENT_CONFIG_CONNECTOR_H +#include "src/core/iomgr/sockaddr.h" #include "src/core/transport/transport.h" typedef struct grpc_connector grpc_connector; @@ -46,18 +47,19 @@ struct grpc_connector { struct grpc_connector_vtable { void (*ref)(grpc_connector *connector); void (*unref)(grpc_connector *connector); - void (*connect)(grpc_connector *connector, - const grpc_channel_args *channel_args, + void (*connect)(grpc_connector *connector, grpc_pollset_set *pollset_set, + const struct sockaddr *addr, int addr_len, + gpr_timespec deadline, const grpc_channel_args *channel_args, grpc_mdctx *metadata_context, grpc_transport **transport, grpc_iomgr_closure *notify); }; void grpc_connector_ref(grpc_connector *connector); void grpc_connector_unref(grpc_connector *connector); -void grpc_connector_connect(grpc_connector *connector, - const grpc_channel_args *channel_args, - grpc_mdctx *metadata_context, - grpc_transport **transport, - grpc_iomgr_closure *notify); +void grpc_connector_connect( + grpc_connector *connector, grpc_pollset_set *pollset_set, + const struct sockaddr *addr, int addr_len, gpr_timespec deadline, + const grpc_channel_args *channel_args, grpc_mdctx *metadata_context, + grpc_transport **transport, grpc_iomgr_closure *notify); #endif diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c index 9637cf39fe..2b4c7ea1d3 100644 --- a/src/core/client_config/subchannel.c +++ b/src/core/client_config/subchannel.c @@ -44,6 +44,19 @@ typedef struct { grpc_subchannel *subchannel; } connection; +typedef struct waiting_for_connect { + struct waiting_for_connect *next; + grpc_iomgr_closure *notify; + grpc_transport_stream_op *initial_op; + grpc_subchannel_call **target; +} waiting_for_connect; + +typedef struct connectivity_state_watcher { + struct connectivity_state_watcher *next; + grpc_iomgr_closure *notify; + grpc_connectivity_state *current; +} connectivity_state_watcher; + struct grpc_subchannel { gpr_refcount refs; grpc_connector *connector; @@ -56,6 +69,8 @@ struct grpc_subchannel { /** address to connect to */ struct sockaddr *addr; size_t addr_len; + /** metadata context */ + grpc_mdctx *mdctx; /** set during connection */ grpc_transport *connecting_transport; @@ -63,6 +78,10 @@ struct grpc_subchannel { /** callback for connection finishing */ grpc_iomgr_closure connected; + /** pollset_set tracking who's interested in a connection + being setup */ + grpc_pollset_set pollset_set; + /** mutex protecting remaining elements */ gpr_mu mu; @@ -70,8 +89,10 @@ struct grpc_subchannel { connection *active; /** are we connecting */ int connecting; - /** closures waiting for a connection */ - grpc_iomgr_closure *waiting; + /** things waiting for a connection */ + waiting_for_connect *waiting; + /** things watching the connectivity state */ + connectivity_state_watcher *watchers; }; struct grpc_subchannel_call { @@ -82,6 +103,9 @@ struct grpc_subchannel_call { #define SUBCHANNEL_CALL_TO_CALL_STACK(call) (((grpc_call_stack *)(call)) + 1) static grpc_subchannel_call *create_call(connection *con, grpc_transport_stream_op *initial_op); +static void connectivity_state_changed_locked(grpc_subchannel *c); +static grpc_connectivity_state compute_connectivity_locked(grpc_subchannel *c); +static gpr_timespec compute_connect_deadline(grpc_subchannel *c); /* * grpc_subchannel implementation @@ -94,10 +118,21 @@ void grpc_subchannel_unref(grpc_subchannel *c) { gpr_free(c->filters); grpc_channel_args_destroy(c->args); gpr_free(c->addr); + grpc_mdctx_unref(c->mdctx); gpr_free(c); } } +void grpc_subchannel_add_interested_party(grpc_subchannel *c, + grpc_pollset *pollset) { + grpc_pollset_set_add_pollset(&c->pollset_set, pollset); +} + +void grpc_subchannel_del_interested_party(grpc_subchannel *c, + grpc_pollset *pollset) { + grpc_pollset_set_del_pollset(&c->pollset_set, pollset); +} + grpc_subchannel *grpc_subchannel_create(grpc_connector *connector, grpc_subchannel_args *args) { grpc_subchannel *c = gpr_malloc(sizeof(*c)); @@ -113,12 +148,13 @@ grpc_subchannel *grpc_subchannel_create(grpc_connector *connector, memcpy(c->addr, args->addr, args->addr_len); c->addr_len = args->addr_len; c->args = grpc_channel_args_copy(args->args); + c->mdctx = args->mdctx; + grpc_mdctx_ref(c->mdctx); gpr_mu_init(&c->mu); return c; } void grpc_subchannel_create_call(grpc_subchannel *c, - grpc_mdctx *mdctx, grpc_transport_stream_op *initial_op, grpc_subchannel_call **target, grpc_iomgr_closure *notify) { @@ -132,19 +168,101 @@ void grpc_subchannel_create_call(grpc_subchannel *c, *target = create_call(con, initial_op); notify->cb(notify->cb_arg, 1); } else { - notify->next = c->waiting; - c->waiting = notify; + waiting_for_connect *w4c = gpr_malloc(sizeof(*w4c)); + w4c->next = c->waiting; + w4c->notify = notify; + w4c->initial_op = initial_op; + w4c->target = target; + c->waiting = w4c; + grpc_subchannel_add_interested_party(c, initial_op->bind_pollset); if (!c->connecting) { c->connecting = 1; + connectivity_state_changed_locked(c); gpr_mu_unlock(&c->mu); - grpc_connector_connect(c->connector, c->args, mdctx, &c->connecting_transport, &c->connected); + grpc_connector_connect(c->connector, &c->pollset_set, c->addr, + c->addr_len, compute_connect_deadline(c), c->args, + c->mdctx, &c->connecting_transport, &c->connected); } else { gpr_mu_unlock(&c->mu); } } } +grpc_connectivity_state grpc_subchannel_check_connectivity(grpc_subchannel *c) { + grpc_connectivity_state state; + gpr_mu_lock(&c->mu); + state = compute_connectivity_locked(c); + gpr_mu_unlock(&c->mu); + return state; +} + +void grpc_subchannel_notify_on_state_change(grpc_subchannel *c, + grpc_connectivity_state *state, + grpc_iomgr_closure *notify) { + grpc_connectivity_state current; + int do_connect = 0; + connectivity_state_watcher *w = gpr_malloc(sizeof(*w)); + w->current = state; + w->notify = notify; + gpr_mu_lock(&c->mu); + current = compute_connectivity_locked(c); + if (current == GRPC_CHANNEL_IDLE) { + current = GRPC_CHANNEL_CONNECTING; + c->connecting = 1; + do_connect = 1; + connectivity_state_changed_locked(c); + } + if (current != *state) { + gpr_mu_unlock(&c->mu); + *state = current; + grpc_iomgr_add_callback(notify); + gpr_free(w); + } else { + w->next = c->watchers; + c->watchers = w; + gpr_mu_unlock(&c->mu); + } + if (do_connect) { + grpc_connector_connect(c->connector, &c->pollset_set, c->addr, c->addr_len, + compute_connect_deadline(c), c->args, c->mdctx, + &c->connecting_transport, &c->connected); + } +} + +static gpr_timespec compute_connect_deadline(grpc_subchannel *c) { + return gpr_time_add(gpr_now(), gpr_time_from_seconds(60)); +} + +static grpc_connectivity_state compute_connectivity_locked(grpc_subchannel *c) { + if (c->connecting) { + return GRPC_CHANNEL_CONNECTING; + } + if (c->active) { + return GRPC_CHANNEL_READY; + } + return GRPC_CHANNEL_IDLE; +} + +static void connectivity_state_changed_locked(grpc_subchannel *c) { + grpc_connectivity_state current = compute_connectivity_locked(c); + connectivity_state_watcher *new = NULL; + connectivity_state_watcher *w; + while ((w = c->watchers)) { + c->watchers = w->next; + + if (current != *w->current) { + *w->current = current; + grpc_iomgr_add_callback(w->notify); + gpr_free(w); + } else { + w->next = new; + new = w; + } + } + c->watchers = new; +} + /* * grpc_subchannel_call implementation */ diff --git a/src/core/client_config/subchannel.h b/src/core/client_config/subchannel.h index 8b3d82eb0a..8836f9b09c 100644 --- a/src/core/client_config/subchannel.h +++ b/src/core/client_config/subchannel.h @@ -64,7 +64,6 @@ void grpc_subchannel_del_interested_party(grpc_subchannel *channel, grpc_pollset /** construct a call (possibly asynchronously) */ void grpc_subchannel_create_call(grpc_subchannel *subchannel, - grpc_mdctx *mdctx, grpc_transport_stream_op *initial_op, grpc_subchannel_call **target, grpc_iomgr_closure *notify); @@ -84,6 +83,8 @@ struct grpc_subchannel_args { /** Address to connect to */ struct sockaddr *addr; size_t addr_len; + /** metadata context to use */ + grpc_mdctx *mdctx; }; /** create a subchannel given a connector */ diff --git a/src/core/surface/channel_create.c b/src/core/surface/channel_create.c index ba4e1a24ec..46d1d708dd 100644 --- a/src/core/surface/channel_create.c +++ b/src/core/surface/channel_create.c @@ -41,11 +41,18 @@ #include "src/core/channel/channel_args.h" #include "src/core/channel/client_channel.h" #include "src/core/client_config/resolver_registry.h" +#include "src/core/iomgr/tcp_client.h" #include "src/core/surface/channel.h" +#include "src/core/transport/chttp2_transport.h" typedef struct { grpc_connector base; gpr_refcount refs; + + grpc_transport **transport; + grpc_iomgr_closure *notify; + const grpc_channel_args *args; + grpc_mdctx *mdctx; } connector; static void connector_ref(grpc_connector *con) { @@ -60,28 +67,68 @@ static void connector_unref(grpc_connector *con) { } } -static void connector_connect(grpc_connector *connector, const grpc_channel_args *channel_args, grpc_mdctx *metadata_context, grpc_transport **transport, grpc_iomgr_closure *notify) { - abort(); +static void connected(void *arg, grpc_endpoint *tcp) { + connector *c = arg; + grpc_iomgr_closure *notify; + if (tcp != NULL) { + *c->transport = + grpc_create_chttp2_transport(c->args, tcp, NULL, 0, c->mdctx, 1); + } else { + *c->transport = NULL; + } + notify = c->notify; + c->notify = NULL; + grpc_iomgr_add_callback(notify); +} + +static void connector_connect( + grpc_connector *con, grpc_pollset_set *pollset_set, + const struct sockaddr *addr, int addr_len, gpr_timespec deadline, + const grpc_channel_args *channel_args, grpc_mdctx *metadata_context, + grpc_transport **transport, grpc_iomgr_closure *notify) { + connector *c = (connector *)con; + GPR_ASSERT(c->notify == NULL); + c->notify = notify; + c->args = channel_args; + c->mdctx = metadata_context; + grpc_tcp_client_connect(connected, c, pollset_set, addr, addr_len, deadline); } static const grpc_connector_vtable connector_vtable = {connector_ref, connector_unref, connector_connect}; -static void subchannel_factory_ref(grpc_subchannel_factory *scf) {} +typedef struct { + grpc_subchannel_factory base; + gpr_refcount refs; + grpc_mdctx *mdctx; +} subchannel_factory; + +static void subchannel_factory_ref(grpc_subchannel_factory *scf) { + subchannel_factory *f = (subchannel_factory *)scf; + gpr_ref(&f->refs); +} -static void subchannel_factory_unref(grpc_subchannel_factory *scf) {} +static void subchannel_factory_unref(grpc_subchannel_factory *scf) { + subchannel_factory *f = (subchannel_factory *)scf; + if (gpr_unref(&f->refs)) { + grpc_mdctx_unref(f->mdctx); + gpr_free(f); + } +} static grpc_subchannel *subchannel_factory_create_subchannel(grpc_subchannel_factory *scf, grpc_subchannel_args *args) { + subchannel_factory *f = (subchannel_factory *)scf; connector *c = gpr_malloc(sizeof(*c)); grpc_subchannel *s; + memset(c, 0, sizeof(*c)); c->base.vtable = &connector_vtable; gpr_ref_init(&c->refs, 1); + args->mdctx = f->mdctx; s = grpc_subchannel_create(&c->base, args); grpc_connector_unref(&c->base); return s; } static const grpc_subchannel_factory_vtable subchannel_factory_vtable = {subchannel_factory_ref, subchannel_factory_unref, subchannel_factory_create_subchannel}; -static grpc_subchannel_factory subchannel_factory = {&subchannel_factory_vtable}; /* Create a client channel: Asynchronously: - resolve target @@ -93,6 +140,8 @@ grpc_channel *grpc_channel_create(const char *target, #define MAX_FILTERS 3 const grpc_channel_filter *filters[MAX_FILTERS]; grpc_resolver *resolver; + subchannel_factory *f; + grpc_mdctx *mdctx = grpc_mdctx_create(); int n = 0; /* TODO(census) if (grpc_channel_args_is_census_enabled(args)) { @@ -101,12 +150,16 @@ grpc_channel *grpc_channel_create(const char *target, filters[n++] = &grpc_client_channel_filter; GPR_ASSERT(n <= MAX_FILTERS); - resolver = grpc_resolver_create(target, &subchannel_factory); + f = gpr_malloc(sizeof(*f)); + f->base.vtable = &subchannel_factory_vtable; + gpr_ref_init(&f->refs, 1); + f->mdctx = mdctx; + resolver = grpc_resolver_create(target, &f->base); if (!resolver) { return NULL; } - channel = grpc_channel_create_from_filters(filters, n, args, grpc_mdctx_create(), 1); + channel = grpc_channel_create_from_filters(filters, n, args, mdctx, 1); grpc_client_channel_set_resolver(grpc_channel_get_channel_stack(channel), resolver); return channel; -- cgit v1.2.3 From c7b5f7605e7210e2bfa1915f585a9ccfa44bbb30 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Sat, 27 Jun 2015 11:48:42 -0700 Subject: Factor out channel state watching --- BUILD | 40 ++++- Makefile | 2 + build.json | 2 + gRPC.podspec | 3 + src/core/channel/client_channel.c | 166 --------------------- src/core/channel/connectivity_state.c | 92 ++++++++++++ src/core/channel/connectivity_state.h | 66 ++++++++ src/core/client_config/lb_policies/pick_first.c | 44 +++++- src/core/client_config/lb_policy.h | 10 ++ src/core/client_config/subchannel.c | 58 ++----- src/core/client_config/subchannel.h | 15 +- tools/doxygen/Doxyfile.core.internal | 2 + tools/run_tests/sources_and_headers.json | 120 ++++++++++++--- vsprojects/grpc/grpc.vcxproj | 3 + vsprojects/grpc/grpc.vcxproj.filters | 6 + vsprojects/grpc_unsecure/grpc_unsecure.vcxproj | 3 + .../grpc_unsecure/grpc_unsecure.vcxproj.filters | 6 + 17 files changed, 398 insertions(+), 240 deletions(-) create mode 100644 src/core/channel/connectivity_state.c create mode 100644 src/core/channel/connectivity_state.h (limited to 'src/core/channel/client_channel.c') diff --git a/BUILD b/BUILD index af2712549c..201d8449c8 100644 --- a/BUILD +++ b/BUILD @@ -152,6 +152,7 @@ cc_library( "src/core/channel/channel_stack.h", "src/core/channel/client_channel.h", "src/core/channel/connected_channel.h", + "src/core/channel/connectivity_state.h", "src/core/channel/context.h", "src/core/channel/http_client_filter.h", "src/core/channel/http_server_filter.h", @@ -268,6 +269,7 @@ cc_library( "src/core/channel/channel_stack.c", "src/core/channel/client_channel.c", "src/core/channel/connected_channel.c", + "src/core/channel/connectivity_state.c", "src/core/channel/http_client_filter.c", "src/core/channel/http_server_filter.c", "src/core/channel/noop_filter.c", @@ -400,6 +402,7 @@ cc_library( "src/core/channel/channel_stack.h", "src/core/channel/client_channel.h", "src/core/channel/connected_channel.h", + "src/core/channel/connectivity_state.h", "src/core/channel/context.h", "src/core/channel/http_client_filter.h", "src/core/channel/http_server_filter.h", @@ -494,6 +497,7 @@ cc_library( "src/core/channel/channel_stack.c", "src/core/channel/client_channel.c", "src/core/channel/connected_channel.c", + "src/core/channel/connectivity_state.c", "src/core/channel/http_client_filter.c", "src/core/channel/http_server_filter.c", "src/core/channel/noop_filter.c", @@ -930,13 +934,23 @@ objc_library( "src/core/census/grpc_context.c", "src/core/channel/channel_args.c", "src/core/channel/channel_stack.c", - "src/core/channel/child_channel.c", "src/core/channel/client_channel.c", - "src/core/channel/client_setup.c", "src/core/channel/connected_channel.c", + "src/core/channel/connectivity_state.c", "src/core/channel/http_client_filter.c", "src/core/channel/http_server_filter.c", "src/core/channel/noop_filter.c", + "src/core/client_config/client_config.c", + "src/core/client_config/connector.c", + "src/core/client_config/lb_policies/pick_first.c", + "src/core/client_config/lb_policy.c", + "src/core/client_config/resolver.c", + "src/core/client_config/resolver_factory.c", + "src/core/client_config/resolver_registry.c", + "src/core/client_config/resolvers/dns_resolver.c", + "src/core/client_config/subchannel.c", + "src/core/client_config/subchannel_factory.c", + "src/core/client_config/uri_parser.c", "src/core/compression/algorithm.c", "src/core/compression/message_compress.c", "src/core/debug/trace.c", @@ -989,7 +1003,6 @@ objc_library( "src/core/surface/call_log_batch.c", "src/core/surface/channel.c", "src/core/surface/channel_create.c", - "src/core/surface/client.c", "src/core/surface/completion_queue.c", "src/core/surface/event_string.c", "src/core/surface/init.c", @@ -1010,11 +1023,15 @@ objc_library( "src/core/transport/chttp2/hpack_parser.c", "src/core/transport/chttp2/hpack_table.c", "src/core/transport/chttp2/huffsyms.c", + "src/core/transport/chttp2/incoming_metadata.c", + "src/core/transport/chttp2/parsing.c", "src/core/transport/chttp2/status_conversion.c", "src/core/transport/chttp2/stream_encoder.c", + "src/core/transport/chttp2/stream_lists.c", "src/core/transport/chttp2/stream_map.c", "src/core/transport/chttp2/timeout_encoding.c", "src/core/transport/chttp2/varint.c", + "src/core/transport/chttp2/writing.c", "src/core/transport/chttp2_transport.c", "src/core/transport/metadata.c", "src/core/transport/stream_op.c", @@ -1034,14 +1051,24 @@ objc_library( "src/core/channel/census_filter.h", "src/core/channel/channel_args.h", "src/core/channel/channel_stack.h", - "src/core/channel/child_channel.h", "src/core/channel/client_channel.h", - "src/core/channel/client_setup.h", "src/core/channel/connected_channel.h", + "src/core/channel/connectivity_state.h", "src/core/channel/context.h", "src/core/channel/http_client_filter.h", "src/core/channel/http_server_filter.h", "src/core/channel/noop_filter.h", + "src/core/client_config/client_config.h", + "src/core/client_config/connector.h", + "src/core/client_config/lb_policies/pick_first.h", + "src/core/client_config/lb_policy.h", + "src/core/client_config/resolver.h", + "src/core/client_config/resolver_factory.h", + "src/core/client_config/resolver_registry.h", + "src/core/client_config/resolvers/dns_resolver.h", + "src/core/client_config/subchannel.h", + "src/core/client_config/subchannel_factory.h", + "src/core/client_config/uri_parser.h", "src/core/compression/message_compress.h", "src/core/debug/trace.h", "src/core/iomgr/alarm.h", @@ -1084,7 +1111,6 @@ objc_library( "src/core/surface/byte_buffer_queue.h", "src/core/surface/call.h", "src/core/surface/channel.h", - "src/core/surface/client.h", "src/core/surface/completion_queue.h", "src/core/surface/event_string.h", "src/core/surface/init.h", @@ -1103,6 +1129,8 @@ objc_library( "src/core/transport/chttp2/hpack_table.h", "src/core/transport/chttp2/http2_errors.h", "src/core/transport/chttp2/huffsyms.h", + "src/core/transport/chttp2/incoming_metadata.h", + "src/core/transport/chttp2/internal.h", "src/core/transport/chttp2/status_conversion.h", "src/core/transport/chttp2/stream_encoder.h", "src/core/transport/chttp2/stream_map.h", diff --git a/Makefile b/Makefile index 766db0c2d8..ff8a41598f 100644 --- a/Makefile +++ b/Makefile @@ -3018,6 +3018,7 @@ LIBGRPC_SRC = \ src/core/channel/channel_stack.c \ src/core/channel/client_channel.c \ src/core/channel/connected_channel.c \ + src/core/channel/connectivity_state.c \ src/core/channel/http_client_filter.c \ src/core/channel/http_server_filter.c \ src/core/channel/noop_filter.c \ @@ -3276,6 +3277,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/channel/channel_stack.c \ src/core/channel/client_channel.c \ src/core/channel/connected_channel.c \ + src/core/channel/connectivity_state.c \ src/core/channel/http_client_filter.c \ src/core/channel/http_server_filter.c \ src/core/channel/noop_filter.c \ diff --git a/build.json b/build.json index c4f0242388..7893ea3d0f 100644 --- a/build.json +++ b/build.json @@ -113,6 +113,7 @@ "src/core/channel/channel_stack.h", "src/core/channel/client_channel.h", "src/core/channel/connected_channel.h", + "src/core/channel/connectivity_state.h", "src/core/channel/context.h", "src/core/channel/http_client_filter.h", "src/core/channel/http_server_filter.h", @@ -207,6 +208,7 @@ "src/core/channel/channel_stack.c", "src/core/channel/client_channel.c", "src/core/channel/connected_channel.c", + "src/core/channel/connectivity_state.c", "src/core/channel/http_client_filter.c", "src/core/channel/http_server_filter.c", "src/core/channel/noop_filter.c", diff --git a/gRPC.podspec b/gRPC.podspec index 862c24b27e..4cc71e3cf1 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -154,6 +154,7 @@ Pod::Spec.new do |s| 'src/core/channel/channel_stack.h', 'src/core/channel/client_channel.h', 'src/core/channel/connected_channel.h', + 'src/core/channel/connectivity_state.h', 'src/core/channel/context.h', 'src/core/channel/http_client_filter.h', 'src/core/channel/http_server_filter.h', @@ -277,6 +278,7 @@ Pod::Spec.new do |s| 'src/core/channel/channel_stack.c', 'src/core/channel/client_channel.c', 'src/core/channel/connected_channel.c', + 'src/core/channel/connectivity_state.c', 'src/core/channel/http_client_filter.c', 'src/core/channel/http_server_filter.c', 'src/core/channel/noop_filter.c', @@ -408,6 +410,7 @@ Pod::Spec.new do |s| 'src/core/channel/channel_stack.h', 'src/core/channel/client_channel.h', 'src/core/channel/connected_channel.h', + 'src/core/channel/connectivity_state.h', 'src/core/channel/context.h', 'src/core/channel/http_client_filter.h', 'src/core/channel/http_server_filter.h', diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index dc838de715..4d082aceb8 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -426,88 +426,6 @@ static void cc_on_config_changed(void *arg, int iomgr_success) { } } -#if 0 -static void channel_op(grpc_channel_element *elem, - grpc_channel_element *from_elem, grpc_channel_op *op) { - channel_data *chand = elem->channel_data; - grpc_child_channel *child_channel; - grpc_channel_op rop; - GPR_ASSERT(elem->filter == &grpc_client_channel_filter); - - switch (op->type) { - case GRPC_CHANNEL_GOAWAY: - /* sending goaway: clear out the active child on the way through */ - gpr_mu_lock(&chand->mu); - child_channel = chand->active_child; - chand->active_child = NULL; - gpr_mu_unlock(&chand->mu); - if (child_channel) { - grpc_child_channel_handle_op(child_channel, op); - grpc_child_channel_destroy(child_channel, 1); - } else { - gpr_slice_unref(op->data.goaway.message); - } - break; - case GRPC_CHANNEL_DISCONNECT: - /* sending disconnect: clear out the active child on the way through */ - gpr_mu_lock(&chand->mu); - child_channel = chand->active_child; - chand->active_child = NULL; - gpr_mu_unlock(&chand->mu); - if (child_channel) { - grpc_child_channel_destroy(child_channel, 1); - } - /* fake a transport closed to satisfy the refcounting in client */ - rop.type = GRPC_TRANSPORT_CLOSED; - rop.dir = GRPC_CALL_UP; - grpc_channel_next_op(elem, &rop); - break; - case GRPC_TRANSPORT_GOAWAY: - /* receiving goaway: if it's from our active child, drop the active child; - in all cases consume the event here */ - gpr_mu_lock(&chand->mu); - child_channel = grpc_channel_stack_from_top_element(from_elem); - if (child_channel == chand->active_child) { - chand->active_child = NULL; - } else { - child_channel = NULL; - } - gpr_mu_unlock(&chand->mu); - if (child_channel) { - grpc_child_channel_destroy(child_channel, 0); - } - gpr_slice_unref(op->data.goaway.message); - break; - case GRPC_TRANSPORT_CLOSED: - /* receiving disconnect: if it's from our active child, drop the active - child; in all cases consume the event here */ - gpr_mu_lock(&chand->mu); - child_channel = grpc_channel_stack_from_top_element(from_elem); - if (child_channel == chand->active_child) { - chand->active_child = NULL; - } else { - child_channel = NULL; - } - gpr_mu_unlock(&chand->mu); - if (child_channel) { - grpc_child_channel_destroy(child_channel, 0); - } - break; - default: - switch (op->dir) { - case GRPC_CALL_UP: - grpc_channel_next_op(elem, op); - break; - case GRPC_CALL_DOWN: - gpr_log(GPR_ERROR, "unhandled channel op: %d", op->type); - abort(); - break; - } - break; - } -} -#endif - static void cc_start_transport_op(grpc_channel_element *elem, grpc_transport_op *op) {} /* Constructor for call_data */ @@ -591,90 +509,6 @@ const grpc_channel_filter grpc_client_channel_filter = { init_channel_elem, destroy_channel_elem, "client-channel", }; -#if 0 -grpc_transport_setup_result grpc_client_channel_transport_setup_complete( - grpc_channel_stack *channel_stack, grpc_transport *transport, - grpc_channel_filter const **channel_filters, size_t num_channel_filters, - grpc_mdctx *mdctx) { - /* we just got a new transport: lets create a child channel stack for it */ - grpc_channel_element *elem = grpc_channel_stack_last_element(channel_stack); - channel_data *chand = elem->channel_data; - size_t num_child_filters = 2 + num_channel_filters; - grpc_channel_filter const **child_filters; - grpc_transport_setup_result result; - grpc_child_channel *old_active = NULL; - call_data **waiting_children; - size_t waiting_child_count; - size_t i; - grpc_transport_stream_op *call_ops; - - /* build the child filter stack */ - child_filters = gpr_malloc(sizeof(grpc_channel_filter *) * num_child_filters); - /* we always need a link back filter to get back to the connected channel */ - child_filters[0] = &grpc_child_channel_top_filter; - for (i = 0; i < num_channel_filters; i++) { - child_filters[i + 1] = channel_filters[i]; - } - /* and we always need a connected channel to talk to the transport */ - child_filters[num_child_filters - 1] = &grpc_connected_channel_filter; - - GPR_ASSERT(elem->filter == &grpc_client_channel_filter); - - /* BEGIN LOCKING CHANNEL */ - gpr_mu_lock(&chand->mu); - chand->transport_setup_initiated = 0; - - if (chand->active_child) { - old_active = chand->active_child; - } - chand->active_child = grpc_child_channel_create( - elem, child_filters, num_child_filters, chand->args, mdctx); - result = - grpc_connected_channel_bind_transport(chand->active_child, transport); - - /* capture the waiting children - we'll activate them outside the lock - to avoid re-entrancy problems */ - waiting_children = chand->waiting_children; - waiting_child_count = chand->waiting_child_count; - /* bumping up inflight_requests here avoids taking a lock per rpc below */ - - chand->waiting_children = NULL; - chand->waiting_child_count = 0; - chand->waiting_child_capacity = 0; - - call_ops = gpr_malloc(sizeof(*call_ops) * waiting_child_count); - - for (i = 0; i < waiting_child_count; i++) { - call_ops[i] = waiting_children[i]->waiting_op; - if (!prepare_activate(waiting_children[i]->elem, chand->active_child)) { - waiting_children[i] = NULL; - grpc_transport_stream_op_finish_with_failure(&call_ops[i]); - } - } - - /* END LOCKING CHANNEL */ - gpr_mu_unlock(&chand->mu); - - /* activate any pending operations - this is safe to do as we guarantee one - and only one write operation per request at the surface api - if we lose - that guarantee we need to do some curly locking here */ - for (i = 0; i < waiting_child_count; i++) { - if (waiting_children[i]) { - complete_activate(waiting_children[i]->elem, &call_ops[i]); - } - } - gpr_free(waiting_children); - gpr_free(call_ops); - gpr_free(child_filters); - - if (old_active) { - grpc_child_channel_destroy(old_active, 1); - } - - return result; -} -#endif - void grpc_client_channel_set_resolver(grpc_channel_stack *channel_stack, grpc_resolver *resolver) { /* post construction initialization: set the transport setup pointer */ diff --git a/src/core/channel/connectivity_state.c b/src/core/channel/connectivity_state.c new file mode 100644 index 0000000000..566a2c3344 --- /dev/null +++ b/src/core/channel/connectivity_state.c @@ -0,0 +1,92 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "src/core/channel/connectivity_state.h" +#include + +void grpc_connectivity_state_init(grpc_connectivity_state_tracker *tracker, grpc_connectivity_state init_state) { + tracker->current_state = init_state; + tracker->watchers = NULL; +} + +void grpc_connectivity_state_destroy(grpc_connectivity_state_tracker *tracker) { + grpc_connectivity_state_watcher *w; + while ((w = tracker->watchers)) { + tracker->watchers = w->next; + + if (GRPC_CHANNEL_FATAL_FAILURE != *w->current) { + *w->current = GRPC_CHANNEL_FATAL_FAILURE; + grpc_iomgr_add_callback(w->notify); + } else { + grpc_iomgr_add_delayed_callback(w->notify, 0); + } + gpr_free(w); + } +} + +grpc_connectivity_state grpc_connectivity_state_check(grpc_connectivity_state_tracker *tracker) { + return tracker->current_state; +} + +int grpc_connectivity_state_notify_on_state_change(grpc_connectivity_state_tracker *tracker, grpc_connectivity_state *current, grpc_iomgr_closure *notify) { + if (tracker->current_state != *current) { + *current = tracker->current_state; + grpc_iomgr_add_callback(notify); + } else { + grpc_connectivity_state_watcher *w = gpr_malloc(sizeof(*w)); + w->current = current; + w->notify = notify; + w->next = tracker->watchers; + tracker->watchers = w; + } + return tracker->current_state == GRPC_CHANNEL_IDLE; +} + +void grpc_connectivity_state_set(grpc_connectivity_state_tracker *tracker, grpc_connectivity_state state) { + grpc_connectivity_state_watcher *new = NULL; + grpc_connectivity_state_watcher *w; + tracker->current_state = state; + while ((w = tracker->watchers)) { + tracker->watchers = w->next; + + if (state != *w->current) { + *w->current = state; + grpc_iomgr_add_callback(w->notify); + gpr_free(w); + } else { + w->next = new; + new = w; + } + } + tracker->watchers = new; +} diff --git a/src/core/channel/connectivity_state.h b/src/core/channel/connectivity_state.h new file mode 100644 index 0000000000..ebc1acc559 --- /dev/null +++ b/src/core/channel/connectivity_state.h @@ -0,0 +1,66 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_INTERNAL_CORE_CHANNEL_CONNECTIVITY_STATE_H +#define GRPC_INTERNAL_CORE_CHANNEL_CONNECTIVITY_STATE_H + +#include +#include "src/core/iomgr/iomgr.h" + +typedef struct grpc_connectivity_state_watcher { + /** we keep watchers in a linked list */ + struct grpc_connectivity_state_watcher *next; + /** closure to notify on change */ + grpc_iomgr_closure *notify; + /** the current state as believed by the watcher */ + grpc_connectivity_state *current; +} grpc_connectivity_state_watcher; + +typedef struct { + /** current connectivity state */ + grpc_connectivity_state current_state; + /** all our watchers */ + grpc_connectivity_state_watcher *watchers; +} grpc_connectivity_state_tracker; + +void grpc_connectivity_state_init(grpc_connectivity_state_tracker *tracker, grpc_connectivity_state init_state); +void grpc_connectivity_state_destroy(grpc_connectivity_state_tracker *tracker); + +void grpc_connectivity_state_set(grpc_connectivity_state_tracker *tracker, grpc_connectivity_state state); + +grpc_connectivity_state grpc_connectivity_state_check(grpc_connectivity_state_tracker *tracker); + +/** Return 1 if the channel should start connecting, 0 otherwise */ +int grpc_connectivity_state_notify_on_state_change(grpc_connectivity_state_tracker *tracker, grpc_connectivity_state *current, grpc_iomgr_closure *notify); + +#endif /* GRPC_INTERNAL_CORE_CHANNEL_CONNECTIVITY_STATE_H */ diff --git a/src/core/client_config/lb_policies/pick_first.c b/src/core/client_config/lb_policies/pick_first.c index f3a6d21eb5..4fda07a63f 100644 --- a/src/core/client_config/lb_policies/pick_first.c +++ b/src/core/client_config/lb_policies/pick_first.c @@ -36,6 +36,7 @@ #include #include +#include "src/core/channel/connectivity_state.h" typedef struct pending_pick { struct pending_pick *next; @@ -69,6 +70,9 @@ typedef struct { grpc_connectivity_state checking_connectivity; /** list of picks that are waiting on connectivity */ pending_pick *pending_picks; + + /** our connectivity state tracker */ + grpc_connectivity_state_tracker state_tracker; } pick_first_lb_policy; void pf_ref(grpc_lb_policy *pol) { @@ -184,8 +188,46 @@ loop: } } +static void pf_broadcast(grpc_lb_policy *pol, grpc_transport_op *op) { + pick_first_lb_policy *p = (pick_first_lb_policy*)pol; + size_t i; + size_t n; + grpc_subchannel **subchannels; + + gpr_mu_lock(&p->mu); + n = p->num_subchannels; + subchannels = gpr_malloc(n * sizeof(*subchannels)); + for (i = 0; i < n; i++) { + subchannels[i] = p->subchannels[i]; + grpc_subchannel_ref(subchannels[i]); + } + gpr_mu_unlock(&p->mu); + + for (i = 0; i < n; i++) { + grpc_subchannel_process_transport_op(subchannels[i], op); + grpc_subchannel_unref(subchannels[i]); + } + gpr_free(subchannels); +} + +static grpc_connectivity_state pf_check_connectivity(grpc_lb_policy *pol) { + pick_first_lb_policy *p = (pick_first_lb_policy*)pol; + grpc_connectivity_state st; + gpr_mu_lock(&p->mu); + st = grpc_connectivity_state_check(&p->state_tracker); + gpr_mu_unlock(&p->mu); + return st; +} + +static void pf_notify_on_state_change(grpc_lb_policy *pol, grpc_connectivity_state *current, grpc_iomgr_closure *notify) { + pick_first_lb_policy *p = (pick_first_lb_policy*)pol; + gpr_mu_lock(&p->mu); + grpc_connectivity_state_notify_on_state_change(&p->state_tracker, current, notify); + gpr_mu_unlock(&p->mu); +} + static const grpc_lb_policy_vtable pick_first_lb_policy_vtable = { - pf_ref, pf_unref, pf_shutdown, pf_pick}; + pf_ref, pf_unref, pf_shutdown, pf_pick, pf_broadcast, pf_check_connectivity, pf_notify_on_state_change}; grpc_lb_policy *grpc_create_pick_first_lb_policy(grpc_subchannel **subchannels, size_t num_subchannels) { diff --git a/src/core/client_config/lb_policy.h b/src/core/client_config/lb_policy.h index 42929e933b..42be9152cb 100644 --- a/src/core/client_config/lb_policy.h +++ b/src/core/client_config/lb_policy.h @@ -58,6 +58,16 @@ struct grpc_lb_policy_vtable { void (*pick)(grpc_lb_policy *policy, grpc_pollset *pollset, grpc_metadata_batch *initial_metadata, grpc_subchannel **target, grpc_iomgr_closure *on_complete); + + /** broadcast a transport op to all subchannels */ + void (*broadcast)(grpc_lb_policy *policy, grpc_transport_op *op); + + /** check the current connectivity of the lb_policy */ + grpc_connectivity_state (*check_connectivity)(grpc_lb_policy *policy); + + /** call notify when the connectivity state of a channel changes from *state. + Updates *state with the new state of the policy */ + void (*notify_on_state_change)(grpc_lb_policy *policy, grpc_connectivity_state *state, grpc_iomgr_closure *closure); }; void grpc_lb_policy_ref(grpc_lb_policy *policy); diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c index b489ce04a5..5cbb5d9971 100644 --- a/src/core/client_config/subchannel.c +++ b/src/core/client_config/subchannel.c @@ -39,6 +39,7 @@ #include "src/core/channel/channel_args.h" #include "src/core/channel/connected_channel.h" +#include "src/core/channel/connectivity_state.h" typedef struct { gpr_refcount refs; @@ -52,12 +53,6 @@ typedef struct waiting_for_connect { grpc_subchannel_call **target; } waiting_for_connect; -typedef struct connectivity_state_watcher { - struct connectivity_state_watcher *next; - grpc_iomgr_closure *notify; - grpc_connectivity_state *current; -} connectivity_state_watcher; - struct grpc_subchannel { gpr_refcount refs; grpc_connector *connector; @@ -92,8 +87,8 @@ struct grpc_subchannel { int connecting; /** things waiting for a connection */ waiting_for_connect *waiting; - /** things watching the connectivity state */ - connectivity_state_watcher *watchers; + /** connectivity state tracking */ + grpc_connectivity_state_tracker state_tracker; }; struct grpc_subchannel_call { @@ -123,6 +118,7 @@ void grpc_subchannel_unref(grpc_subchannel *c) { gpr_free(c->addr); grpc_mdctx_unref(c->mdctx); grpc_pollset_set_destroy(&c->pollset_set); + grpc_connectivity_state_destroy(&c->state_tracker); gpr_free(c); } } @@ -156,6 +152,7 @@ grpc_subchannel *grpc_subchannel_create(grpc_connector *connector, grpc_mdctx_ref(c->mdctx); grpc_pollset_set_init(&c->pollset_set); grpc_iomgr_closure_init(&c->connected, subchannel_connected, c); + grpc_connectivity_state_init(&c->state_tracker, GRPC_CHANNEL_IDLE); gpr_mu_init(&c->mu); return c; } @@ -210,7 +207,7 @@ void grpc_subchannel_create_call(grpc_subchannel *c, grpc_connectivity_state grpc_subchannel_check_connectivity(grpc_subchannel *c) { grpc_connectivity_state state; gpr_mu_lock(&c->mu); - state = compute_connectivity_locked(c); + state = grpc_connectivity_state_check(&c->state_tracker); gpr_mu_unlock(&c->mu); return state; } @@ -218,35 +215,24 @@ grpc_connectivity_state grpc_subchannel_check_connectivity(grpc_subchannel *c) { void grpc_subchannel_notify_on_state_change(grpc_subchannel *c, grpc_connectivity_state *state, grpc_iomgr_closure *notify) { - grpc_connectivity_state current; int do_connect = 0; - connectivity_state_watcher *w = gpr_malloc(sizeof(*w)); - w->current = state; - w->notify = notify; gpr_mu_lock(&c->mu); - current = compute_connectivity_locked(c); - if (current == GRPC_CHANNEL_IDLE) { - current = GRPC_CHANNEL_CONNECTING; + if (grpc_connectivity_state_notify_on_state_change(&c->state_tracker, state, notify)) { + do_connect = 1; c->connecting = 1; - do_connect = 1; grpc_subchannel_ref(c); - connectivity_state_changed_locked(c); - } - if (current != *state) { - gpr_mu_unlock(&c->mu); - *state = current; - grpc_iomgr_add_callback(notify); - gpr_free(w); - } else { - w->next = c->watchers; - c->watchers = w; - gpr_mu_unlock(&c->mu); + grpc_connectivity_state_set(&c->state_tracker, compute_connectivity_locked(c)); } + gpr_mu_unlock(&c->mu); if (do_connect) { start_connect(c); } } +void grpc_subchannel_process_transport_op(grpc_subchannel *c, grpc_transport_op *op) { + abort(); +} + static void publish_transport(grpc_subchannel *c) { size_t channel_stack_size; connection *con; @@ -311,21 +297,7 @@ static grpc_connectivity_state compute_connectivity_locked(grpc_subchannel *c) { static void connectivity_state_changed_locked(grpc_subchannel *c) { grpc_connectivity_state current = compute_connectivity_locked(c); - connectivity_state_watcher *new = NULL; - connectivity_state_watcher *w; - while ((w = c->watchers)) { - c->watchers = w->next; - - if (current != *w->current) { - *w->current = current; - grpc_iomgr_add_callback(w->notify); - gpr_free(w); - } else { - w->next = new; - new = w; - } - } - c->watchers = new; + grpc_connectivity_state_set(&c->state_tracker, current); } /* diff --git a/src/core/client_config/subchannel.h b/src/core/client_config/subchannel.h index 8836f9b09c..60b95d3d8f 100644 --- a/src/core/client_config/subchannel.h +++ b/src/core/client_config/subchannel.h @@ -46,6 +46,15 @@ typedef struct grpc_subchannel_args grpc_subchannel_args; void grpc_subchannel_ref(grpc_subchannel *channel); void grpc_subchannel_unref(grpc_subchannel *channel); +/** construct a call (possibly asynchronously) */ +void grpc_subchannel_create_call(grpc_subchannel *subchannel, + grpc_transport_stream_op *initial_op, + grpc_subchannel_call **target, + grpc_iomgr_closure *notify); + +/** process a transport level op */ +void grpc_subchannel_process_transport_op(grpc_subchannel *subchannel, grpc_transport_op *op); + void grpc_subchannel_call_ref(grpc_subchannel_call *call); void grpc_subchannel_call_unref(grpc_subchannel_call *call); @@ -62,12 +71,6 @@ void grpc_subchannel_notify_on_state_change(grpc_subchannel *channel, void grpc_subchannel_add_interested_party(grpc_subchannel *channel, grpc_pollset *pollset); void grpc_subchannel_del_interested_party(grpc_subchannel *channel, grpc_pollset *pollset); -/** construct a call (possibly asynchronously) */ -void grpc_subchannel_create_call(grpc_subchannel *subchannel, - grpc_transport_stream_op *initial_op, - grpc_subchannel_call **target, - grpc_iomgr_closure *notify); - /** continue processing a transport op */ void grpc_subchannel_call_process_op(grpc_subchannel_call *subchannel_call, grpc_transport_stream_op *op); diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 56af4ce312..edc7c5d6fe 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -789,6 +789,7 @@ src/core/channel/channel_args.h \ src/core/channel/channel_stack.h \ src/core/channel/client_channel.h \ src/core/channel/connected_channel.h \ +src/core/channel/connectivity_state.h \ src/core/channel/context.h \ src/core/channel/http_client_filter.h \ src/core/channel/http_server_filter.h \ @@ -905,6 +906,7 @@ src/core/channel/channel_args.c \ src/core/channel/channel_stack.c \ src/core/channel/client_channel.c \ src/core/channel/connected_channel.c \ +src/core/channel/connectivity_state.c \ src/core/channel/http_client_filter.c \ src/core/channel/http_server_filter.c \ src/core/channel/noop_filter.c \ diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 5c74bf1eea..8dab263d7a 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -931,6 +931,20 @@ "test/core/tsi/transport_security_test.c" ] }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc_test_util" + ], + "headers": [], + "language": "c", + "name": "uri_parser_test", + "src": [ + "test/core/client_config/uri_parser_test.c" + ] + }, { "deps": [ "gpr", @@ -8636,14 +8650,24 @@ "src/core/channel/census_filter.h", "src/core/channel/channel_args.h", "src/core/channel/channel_stack.h", - "src/core/channel/child_channel.h", "src/core/channel/client_channel.h", - "src/core/channel/client_setup.h", "src/core/channel/connected_channel.h", + "src/core/channel/connectivity_state.h", "src/core/channel/context.h", "src/core/channel/http_client_filter.h", "src/core/channel/http_server_filter.h", "src/core/channel/noop_filter.h", + "src/core/client_config/client_config.h", + "src/core/client_config/connector.h", + "src/core/client_config/lb_policies/pick_first.h", + "src/core/client_config/lb_policy.h", + "src/core/client_config/resolver.h", + "src/core/client_config/resolver_factory.h", + "src/core/client_config/resolver_registry.h", + "src/core/client_config/resolvers/dns_resolver.h", + "src/core/client_config/subchannel.h", + "src/core/client_config/subchannel_factory.h", + "src/core/client_config/uri_parser.h", "src/core/compression/message_compress.h", "src/core/debug/trace.h", "src/core/httpcli/format_request.h", @@ -8698,7 +8722,6 @@ "src/core/surface/byte_buffer_queue.h", "src/core/surface/call.h", "src/core/surface/channel.h", - "src/core/surface/client.h", "src/core/surface/completion_queue.h", "src/core/surface/event_string.h", "src/core/surface/init.h", @@ -8717,6 +8740,8 @@ "src/core/transport/chttp2/hpack_table.h", "src/core/transport/chttp2/http2_errors.h", "src/core/transport/chttp2/huffsyms.h", + "src/core/transport/chttp2/incoming_metadata.h", + "src/core/transport/chttp2/internal.h", "src/core/transport/chttp2/status_conversion.h", "src/core/transport/chttp2/stream_encoder.h", "src/core/transport/chttp2/stream_map.h", @@ -8752,14 +8777,12 @@ "src/core/channel/channel_args.h", "src/core/channel/channel_stack.c", "src/core/channel/channel_stack.h", - "src/core/channel/child_channel.c", - "src/core/channel/child_channel.h", "src/core/channel/client_channel.c", "src/core/channel/client_channel.h", - "src/core/channel/client_setup.c", - "src/core/channel/client_setup.h", "src/core/channel/connected_channel.c", "src/core/channel/connected_channel.h", + "src/core/channel/connectivity_state.c", + "src/core/channel/connectivity_state.h", "src/core/channel/context.h", "src/core/channel/http_client_filter.c", "src/core/channel/http_client_filter.h", @@ -8767,6 +8790,28 @@ "src/core/channel/http_server_filter.h", "src/core/channel/noop_filter.c", "src/core/channel/noop_filter.h", + "src/core/client_config/client_config.c", + "src/core/client_config/client_config.h", + "src/core/client_config/connector.c", + "src/core/client_config/connector.h", + "src/core/client_config/lb_policies/pick_first.c", + "src/core/client_config/lb_policies/pick_first.h", + "src/core/client_config/lb_policy.c", + "src/core/client_config/lb_policy.h", + "src/core/client_config/resolver.c", + "src/core/client_config/resolver.h", + "src/core/client_config/resolver_factory.c", + "src/core/client_config/resolver_factory.h", + "src/core/client_config/resolver_registry.c", + "src/core/client_config/resolver_registry.h", + "src/core/client_config/resolvers/dns_resolver.c", + "src/core/client_config/resolvers/dns_resolver.h", + "src/core/client_config/subchannel.c", + "src/core/client_config/subchannel.h", + "src/core/client_config/subchannel_factory.c", + "src/core/client_config/subchannel_factory.h", + "src/core/client_config/uri_parser.c", + "src/core/client_config/uri_parser.h", "src/core/compression/algorithm.c", "src/core/compression/message_compress.c", "src/core/compression/message_compress.h", @@ -8891,8 +8936,6 @@ "src/core/surface/channel.c", "src/core/surface/channel.h", "src/core/surface/channel_create.c", - "src/core/surface/client.c", - "src/core/surface/client.h", "src/core/surface/completion_queue.c", "src/core/surface/completion_queue.h", "src/core/surface/event_string.c", @@ -8933,16 +8976,22 @@ "src/core/transport/chttp2/http2_errors.h", "src/core/transport/chttp2/huffsyms.c", "src/core/transport/chttp2/huffsyms.h", + "src/core/transport/chttp2/incoming_metadata.c", + "src/core/transport/chttp2/incoming_metadata.h", + "src/core/transport/chttp2/internal.h", + "src/core/transport/chttp2/parsing.c", "src/core/transport/chttp2/status_conversion.c", "src/core/transport/chttp2/status_conversion.h", "src/core/transport/chttp2/stream_encoder.c", "src/core/transport/chttp2/stream_encoder.h", + "src/core/transport/chttp2/stream_lists.c", "src/core/transport/chttp2/stream_map.c", "src/core/transport/chttp2/stream_map.h", "src/core/transport/chttp2/timeout_encoding.c", "src/core/transport/chttp2/timeout_encoding.h", "src/core/transport/chttp2/varint.c", "src/core/transport/chttp2/varint.h", + "src/core/transport/chttp2/writing.c", "src/core/transport/chttp2_transport.c", "src/core/transport/chttp2_transport.h", "src/core/transport/metadata.c", @@ -9047,14 +9096,24 @@ "src/core/channel/census_filter.h", "src/core/channel/channel_args.h", "src/core/channel/channel_stack.h", - "src/core/channel/child_channel.h", "src/core/channel/client_channel.h", - "src/core/channel/client_setup.h", "src/core/channel/connected_channel.h", + "src/core/channel/connectivity_state.h", "src/core/channel/context.h", "src/core/channel/http_client_filter.h", "src/core/channel/http_server_filter.h", "src/core/channel/noop_filter.h", + "src/core/client_config/client_config.h", + "src/core/client_config/connector.h", + "src/core/client_config/lb_policies/pick_first.h", + "src/core/client_config/lb_policy.h", + "src/core/client_config/resolver.h", + "src/core/client_config/resolver_factory.h", + "src/core/client_config/resolver_registry.h", + "src/core/client_config/resolvers/dns_resolver.h", + "src/core/client_config/subchannel.h", + "src/core/client_config/subchannel_factory.h", + "src/core/client_config/uri_parser.h", "src/core/compression/message_compress.h", "src/core/debug/trace.h", "src/core/iomgr/alarm.h", @@ -9097,7 +9156,6 @@ "src/core/surface/byte_buffer_queue.h", "src/core/surface/call.h", "src/core/surface/channel.h", - "src/core/surface/client.h", "src/core/surface/completion_queue.h", "src/core/surface/event_string.h", "src/core/surface/init.h", @@ -9116,6 +9174,8 @@ "src/core/transport/chttp2/hpack_table.h", "src/core/transport/chttp2/http2_errors.h", "src/core/transport/chttp2/huffsyms.h", + "src/core/transport/chttp2/incoming_metadata.h", + "src/core/transport/chttp2/internal.h", "src/core/transport/chttp2/status_conversion.h", "src/core/transport/chttp2/stream_encoder.h", "src/core/transport/chttp2/stream_map.h", @@ -9146,14 +9206,12 @@ "src/core/channel/channel_args.h", "src/core/channel/channel_stack.c", "src/core/channel/channel_stack.h", - "src/core/channel/child_channel.c", - "src/core/channel/child_channel.h", "src/core/channel/client_channel.c", "src/core/channel/client_channel.h", - "src/core/channel/client_setup.c", - "src/core/channel/client_setup.h", "src/core/channel/connected_channel.c", "src/core/channel/connected_channel.h", + "src/core/channel/connectivity_state.c", + "src/core/channel/connectivity_state.h", "src/core/channel/context.h", "src/core/channel/http_client_filter.c", "src/core/channel/http_client_filter.h", @@ -9161,6 +9219,28 @@ "src/core/channel/http_server_filter.h", "src/core/channel/noop_filter.c", "src/core/channel/noop_filter.h", + "src/core/client_config/client_config.c", + "src/core/client_config/client_config.h", + "src/core/client_config/connector.c", + "src/core/client_config/connector.h", + "src/core/client_config/lb_policies/pick_first.c", + "src/core/client_config/lb_policies/pick_first.h", + "src/core/client_config/lb_policy.c", + "src/core/client_config/lb_policy.h", + "src/core/client_config/resolver.c", + "src/core/client_config/resolver.h", + "src/core/client_config/resolver_factory.c", + "src/core/client_config/resolver_factory.h", + "src/core/client_config/resolver_registry.c", + "src/core/client_config/resolver_registry.h", + "src/core/client_config/resolvers/dns_resolver.c", + "src/core/client_config/resolvers/dns_resolver.h", + "src/core/client_config/subchannel.c", + "src/core/client_config/subchannel.h", + "src/core/client_config/subchannel_factory.c", + "src/core/client_config/subchannel_factory.h", + "src/core/client_config/uri_parser.c", + "src/core/client_config/uri_parser.h", "src/core/compression/algorithm.c", "src/core/compression/message_compress.c", "src/core/compression/message_compress.h", @@ -9255,8 +9335,6 @@ "src/core/surface/channel.c", "src/core/surface/channel.h", "src/core/surface/channel_create.c", - "src/core/surface/client.c", - "src/core/surface/client.h", "src/core/surface/completion_queue.c", "src/core/surface/completion_queue.h", "src/core/surface/event_string.c", @@ -9296,16 +9374,22 @@ "src/core/transport/chttp2/http2_errors.h", "src/core/transport/chttp2/huffsyms.c", "src/core/transport/chttp2/huffsyms.h", + "src/core/transport/chttp2/incoming_metadata.c", + "src/core/transport/chttp2/incoming_metadata.h", + "src/core/transport/chttp2/internal.h", + "src/core/transport/chttp2/parsing.c", "src/core/transport/chttp2/status_conversion.c", "src/core/transport/chttp2/status_conversion.h", "src/core/transport/chttp2/stream_encoder.c", "src/core/transport/chttp2/stream_encoder.h", + "src/core/transport/chttp2/stream_lists.c", "src/core/transport/chttp2/stream_map.c", "src/core/transport/chttp2/stream_map.h", "src/core/transport/chttp2/timeout_encoding.c", "src/core/transport/chttp2/timeout_encoding.h", "src/core/transport/chttp2/varint.c", "src/core/transport/chttp2/varint.h", + "src/core/transport/chttp2/writing.c", "src/core/transport/chttp2_transport.c", "src/core/transport/chttp2_transport.h", "src/core/transport/metadata.c", diff --git a/vsprojects/grpc/grpc.vcxproj b/vsprojects/grpc/grpc.vcxproj index 854443935b..7354bbc2f6 100644 --- a/vsprojects/grpc/grpc.vcxproj +++ b/vsprojects/grpc/grpc.vcxproj @@ -178,6 +178,7 @@ + @@ -324,6 +325,8 @@ + + diff --git a/vsprojects/grpc/grpc.vcxproj.filters b/vsprojects/grpc/grpc.vcxproj.filters index 2c02e4a0d8..639fa7093e 100644 --- a/vsprojects/grpc/grpc.vcxproj.filters +++ b/vsprojects/grpc/grpc.vcxproj.filters @@ -85,6 +85,9 @@ src\core\channel + + src\core\channel + src\core\channel @@ -482,6 +485,9 @@ src\core\channel + + src\core\channel + src\core\channel diff --git a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj index 9080bffff9..6ab4803dbc 100644 --- a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj @@ -160,6 +160,7 @@ + @@ -262,6 +263,8 @@ + + diff --git a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters index 3861eef863..a970a728c3 100644 --- a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -19,6 +19,9 @@ src\core\channel + + src\core\channel + src\core\channel @@ -365,6 +368,9 @@ src\core\channel + + src\core\channel + src\core\channel -- cgit v1.2.3 From ca3e9d3e57a664b63b46d31a22b79a3fe2e3738f Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Sat, 27 Jun 2015 18:37:27 -0700 Subject: refcount debugging --- src/core/channel/client_channel.c | 94 ++++++++++--------------- src/core/channel/connectivity_state.c | 3 + src/core/client_config/lb_policies/pick_first.c | 6 +- src/core/client_config/lb_policy.c | 4 ++ src/core/client_config/lb_policy.h | 2 + src/core/client_config/subchannel.c | 94 +++++++++++++++++++++---- src/core/client_config/subchannel.h | 22 +++++- src/core/surface/channel.c | 28 +------- src/core/surface/channel.h | 2 - 9 files changed, 149 insertions(+), 106 deletions(-) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index 4d082aceb8..19700a90a6 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -38,6 +38,7 @@ #include "src/core/channel/channel_args.h" #include "src/core/channel/connected_channel.h" +#include "src/core/channel/connectivity_state.h" #include "src/core/iomgr/iomgr.h" #include "src/core/iomgr/pollset_set.h" #include "src/core/support/string.h" @@ -68,8 +69,7 @@ typedef struct { /** resolver callback */ grpc_iomgr_closure on_config_changed; /** connectivity state being tracked */ - grpc_iomgr_closure *on_connectivity_state_change; - grpc_connectivity_state *connectivity_state; + grpc_connectivity_state_tracker state_tracker; } channel_data; typedef enum { @@ -98,60 +98,6 @@ struct call_data { grpc_linked_mdelem details; }; -#if 0 -static int prepare_activate(grpc_call_element *elem, - grpc_child_channel *on_child) { - call_data *calld = elem->call_data; - channel_data *chand = elem->channel_data; - if (calld->state == CALL_CANCELLED) return 0; - - /* no more access to calld->s.waiting allowed */ - GPR_ASSERT(calld->state == CALL_WAITING); - - if (calld->waiting_op.bind_pollset) { - grpc_transport_setup_del_interested_party(chand->transport_setup, - calld->waiting_op.bind_pollset); - } - - calld->state = CALL_ACTIVE; - - /* create a child call */ - /* TODO(ctiller): pass the waiting op down here */ - calld->s.active.child_call = - grpc_child_channel_create_call(on_child, elem, NULL); - - return 1; -} - -static void complete_activate(grpc_call_element *elem, grpc_transport_stream_op *op) { - call_data *calld = elem->call_data; - grpc_call_element *child_elem = - grpc_child_call_get_top_element(calld->s.active.child_call); - - GPR_ASSERT(calld->state == CALL_ACTIVE); - - /* continue the start call down the stack, this nees to happen after metadata - are flushed*/ - child_elem->filter->start_transport_op(child_elem, op); -} - -static void remove_waiting_child(channel_data *chand, call_data *calld) { - size_t new_count; - size_t i; - for (i = 0, new_count = 0; i < chand->waiting_child_count; i++) { - if (chand->waiting_children[i] == calld) { - grpc_transport_setup_del_interested_party( - chand->transport_setup, calld->waiting_op.bind_pollset); - continue; - } - chand->waiting_children[new_count++] = chand->waiting_children[i]; - } - GPR_ASSERT(new_count == chand->waiting_child_count - 1 || - new_count == chand->waiting_child_count); - chand->waiting_child_count = new_count; -} -#endif - static void handle_op_after_cancellation(grpc_call_element *elem, grpc_transport_stream_op *op) { call_data *calld = elem->call_data; @@ -426,7 +372,39 @@ static void cc_on_config_changed(void *arg, int iomgr_success) { } } -static void cc_start_transport_op(grpc_channel_element *elem, grpc_transport_op *op) {} +static void cc_start_transport_op(grpc_channel_element *elem, grpc_transport_op *op) { + grpc_lb_policy *lb_policy = NULL; + channel_data *chand = elem->channel_data; + grpc_iomgr_closure *on_consumed = op->on_consumed; + op->on_consumed = NULL; + + GPR_ASSERT(op->set_accept_stream == NULL); + GPR_ASSERT(op->bind_pollset == NULL); + + gpr_mu_lock(&chand->mu_config); + if (op->on_connectivity_state_change != NULL) { + grpc_connectivity_state_notify_on_state_change(&chand->state_tracker, op->connectivity_state, op->on_connectivity_state_change); + op->on_connectivity_state_change = NULL; + op->connectivity_state = NULL; + } + + if (!is_empty(op, sizeof(*op))) { + lb_policy = chand->lb_policy; + if (lb_policy) { + grpc_lb_policy_ref(lb_policy); + } + } + gpr_mu_unlock(&chand->mu_config); + + if (lb_policy) { + grpc_lb_policy_broadcast(lb_policy, op); + grpc_lb_policy_unref(lb_policy); + } + + if (on_consumed) { + grpc_iomgr_add_callback(on_consumed); + } +} /* Constructor for call_data */ static void init_call_elem(grpc_call_element *elem, @@ -458,7 +436,7 @@ static void destroy_call_elem(grpc_call_element *elem) { case CALL_ACTIVE: subchannel_call = calld->subchannel_call; gpr_mu_unlock(&calld->mu_state); - grpc_subchannel_call_unref(subchannel_call); + GRPC_SUBCHANNEL_CALL_UNREF(subchannel_call, "channel"); break; case CALL_CREATED: case CALL_CANCELLED: diff --git a/src/core/channel/connectivity_state.c b/src/core/channel/connectivity_state.c index 566a2c3344..0ee268ee59 100644 --- a/src/core/channel/connectivity_state.c +++ b/src/core/channel/connectivity_state.c @@ -75,6 +75,9 @@ int grpc_connectivity_state_notify_on_state_change(grpc_connectivity_state_track void grpc_connectivity_state_set(grpc_connectivity_state_tracker *tracker, grpc_connectivity_state state) { grpc_connectivity_state_watcher *new = NULL; grpc_connectivity_state_watcher *w; + if (tracker->current_state == state) { + return; + } tracker->current_state = state; while ((w = tracker->watchers)) { tracker->watchers = w->next; diff --git a/src/core/client_config/lb_policies/pick_first.c b/src/core/client_config/lb_policies/pick_first.c index 4fda07a63f..e6e743fa7a 100644 --- a/src/core/client_config/lb_policies/pick_first.c +++ b/src/core/client_config/lb_policies/pick_first.c @@ -173,7 +173,7 @@ loop: p->checking_subchannel %= p->num_subchannels; p->checking_connectivity = grpc_subchannel_check_connectivity(p->subchannels[p->checking_subchannel]); p->num_subchannels--; - grpc_subchannel_unref(p->subchannels[p->num_subchannels]); + GRPC_SUBCHANNEL_UNREF(p->subchannels[p->num_subchannels], "pick_first"); add_interested_parties_locked(p); if (p->num_subchannels == 0) { abort(); @@ -199,13 +199,13 @@ static void pf_broadcast(grpc_lb_policy *pol, grpc_transport_op *op) { subchannels = gpr_malloc(n * sizeof(*subchannels)); for (i = 0; i < n; i++) { subchannels[i] = p->subchannels[i]; - grpc_subchannel_ref(subchannels[i]); + GRPC_SUBCHANNEL_REF(subchannels[i], "broadcast"); } gpr_mu_unlock(&p->mu); for (i = 0; i < n; i++) { grpc_subchannel_process_transport_op(subchannels[i], op); - grpc_subchannel_unref(subchannels[i]); + GRPC_SUBCHANNEL_UNREF(subchannels[i], "broadcast"); } gpr_free(subchannels); } diff --git a/src/core/client_config/lb_policy.c b/src/core/client_config/lb_policy.c index 5a2b70b94e..2daba14c2a 100644 --- a/src/core/client_config/lb_policy.c +++ b/src/core/client_config/lb_policy.c @@ -49,3 +49,7 @@ void grpc_lb_policy_pick(grpc_lb_policy *policy, grpc_pollset *pollset, grpc_iomgr_closure *on_complete) { policy->vtable->pick(policy, pollset, initial_metadata, target, on_complete); } + +void grpc_lb_policy_broadcast(grpc_lb_policy *policy, grpc_transport_op *op) { + policy->vtable->broadcast(policy, op); +} diff --git a/src/core/client_config/lb_policy.h b/src/core/client_config/lb_policy.h index 42be9152cb..dcefa6e27e 100644 --- a/src/core/client_config/lb_policy.h +++ b/src/core/client_config/lb_policy.h @@ -85,4 +85,6 @@ void grpc_lb_policy_pick(grpc_lb_policy *policy, grpc_pollset *pollset, grpc_subchannel **target, grpc_iomgr_closure *on_complete); +void grpc_lb_policy_broadcast(grpc_lb_policy *policy, grpc_transport_op *op); + #endif /* GRPC_INTERNAL_CORE_CONFIG_LB_POLICY_H */ diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c index 5cbb5d9971..e441befc0c 100644 --- a/src/core/client_config/subchannel.c +++ b/src/core/client_config/subchannel.c @@ -105,14 +105,68 @@ static grpc_connectivity_state compute_connectivity_locked(grpc_subchannel *c); static gpr_timespec compute_connect_deadline(grpc_subchannel *c); static void subchannel_connected(void *subchannel, int iomgr_success); +/* + * connection implementation + */ + +#ifdef GRPC_SUBCHANNEL_REFCOUNT_DEBUG +#define CONNECTION_REF(c, r) connection_ref((c), __FILE__, __LINE__, (r)) +#define CONNECTION_UNREF(c, r) connection_unref((c), __FILE__, __LINE__, (r)) +#else +#define CONNECTION_REF(c, r) connection_ref((c)) +#define CONNECTION_UNREF(c, r) connection_unref((c)) +#endif + +#ifdef GRPC_SUBCHANNEL_REFCOUNT_DEBUG +static void connection_ref(connection *c, const char *file, int line, const char *reason) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SUBCONN:%p ref %d -> %d %s", + c, (int)c->refs.count, (int)c->refs.count + 1, + reason); +#else +static void connection_ref(connection *c) { +#endif + gpr_ref(&c->refs); +} + +#ifdef GRPC_SUBCHANNEL_REFCOUNT_DEBUG +static void connection_unref(connection *c, const char *file, int line, const char *reason) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SUBCONN:%p unref %d -> %d %s", + c, (int)c->refs.count, (int)c->refs.count - 1, + reason); +#else +static void connection_unref(connection *c) { +#endif + if (gpr_unref(&c->refs)) { + GRPC_SUBCHANNEL_UNREF(c->subchannel, "connection"); + gpr_free(c); + } +} + /* * grpc_subchannel implementation */ -void grpc_subchannel_ref(grpc_subchannel *c) { gpr_ref(&c->refs); } +#ifdef GRPC_SUBCHANNEL_REFCOUNT_DEBUG +void grpc_subchannel_ref(grpc_subchannel *c, const char *file, int line, const char *reason) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SUBCHAN:%p ref %d -> %d %s", + c, (int)c->refs.count, (int)c->refs.count + 1, + reason); +#else +void grpc_subchannel_ref(grpc_subchannel *c) { +#endif + gpr_ref(&c->refs); +} +#ifdef GRPC_SUBCHANNEL_REFCOUNT_DEBUG +void grpc_subchannel_unref(grpc_subchannel *c, const char *file, int line, const char *reason) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SUBCHAN:%p unref %d -> %d %s", + c, (int)c->refs.count, (int)c->refs.count - 1, + reason); +#else void grpc_subchannel_unref(grpc_subchannel *c) { +#endif if (gpr_unref(&c->refs)) { + if (c->active != NULL) CONNECTION_UNREF(c->active, "subchannel"); gpr_free(c->filters); grpc_channel_args_destroy(c->args); gpr_free(c->addr); @@ -178,7 +232,7 @@ void grpc_subchannel_create_call(grpc_subchannel *c, gpr_mu_lock(&c->mu); if (c->active != NULL) { con = c->active; - gpr_ref(&con->refs); + CONNECTION_REF(con, "call"); gpr_mu_unlock(&c->mu); *target = create_call(con, initial_op); @@ -194,7 +248,7 @@ void grpc_subchannel_create_call(grpc_subchannel *c, if (!c->connecting) { c->connecting = 1; connectivity_state_changed_locked(c); - grpc_subchannel_ref(c); + GRPC_SUBCHANNEL_REF(c, "connection"); gpr_mu_unlock(&c->mu); start_connect(c); @@ -220,7 +274,7 @@ void grpc_subchannel_notify_on_state_change(grpc_subchannel *c, if (grpc_connectivity_state_notify_on_state_change(&c->state_tracker, state, notify)) { do_connect = 1; c->connecting = 1; - grpc_subchannel_ref(c); + GRPC_SUBCHANNEL_REF(c, "connection"); grpc_connectivity_state_set(&c->state_tracker, compute_connectivity_locked(c)); } gpr_mu_unlock(&c->mu); @@ -275,7 +329,7 @@ static void subchannel_connected(void *arg, int iomgr_success) { if (c->connecting_result.transport) { publish_transport(c); } else { - grpc_subchannel_unref(c); + GRPC_SUBCHANNEL_UNREF(c, "connection"); /* TODO(ctiller): retry after sleeping */ abort(); } @@ -304,17 +358,29 @@ static void connectivity_state_changed_locked(grpc_subchannel *c) { * grpc_subchannel_call implementation */ -void grpc_subchannel_call_ref(grpc_subchannel_call *call) { - gpr_ref(&call->refs); +#ifdef GRPC_SUBCHANNEL_REFCOUNT_DEBUG +void grpc_subchannel_call_ref(grpc_subchannel_call *c, const char *file, int line, const char *reason) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SUBCALL:%p ref %d -> %d %s", + c, (int)c->refs.count, (int)c->refs.count + 1, + reason); +#else +void grpc_subchannel_call_ref(grpc_subchannel_call *c) { +#endif + gpr_ref(&c->refs); } -void grpc_subchannel_call_unref(grpc_subchannel_call *call) { - if (gpr_unref(&call->refs)) { - grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(call)); - if (gpr_unref(&call->connection->refs)) { - gpr_free(call->connection); - } - gpr_free(call); +#ifdef GRPC_SUBCHANNEL_REFCOUNT_DEBUG +void grpc_subchannel_call_unref(grpc_subchannel_call *c, const char *file, int line, const char *reason) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SUBCALL:%p unref %d -> %d %s", + c, (int)c->refs.count, (int)c->refs.count - 1, + reason); +#else +void grpc_subchannel_call_unref(grpc_subchannel_call *c) { +#endif + if (gpr_unref(&c->refs)) { + grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(c)); + CONNECTION_UNREF(c->connection, "call"); + gpr_free(c); } } diff --git a/src/core/client_config/subchannel.h b/src/core/client_config/subchannel.h index 60b95d3d8f..7cdcccce8f 100644 --- a/src/core/client_config/subchannel.h +++ b/src/core/client_config/subchannel.h @@ -37,14 +37,33 @@ #include "src/core/channel/channel_stack.h" #include "src/core/client_config/connector.h" +#define GRPC_SUBCHANNEL_REFCOUNT_DEBUG + /** A (sub-)channel that knows how to connect to exactly one target address. Provides a target for load balancing. */ typedef struct grpc_subchannel grpc_subchannel; typedef struct grpc_subchannel_call grpc_subchannel_call; typedef struct grpc_subchannel_args grpc_subchannel_args; +#ifdef GRPC_SUBCHANNEL_REFCOUNT_DEBUG +#define GRPC_SUBCHANNEL_REF(c, r) grpc_subchannel_ref((c), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_UNREF(c, r) grpc_subchannel_unref((c), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_CALL_REF(c, r) grpc_subchannel_call_ref((c), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_CALL_UNREF(c, r) grpc_subchannel_call_unref((c), __FILE__, __LINE__, (r)) +void grpc_subchannel_ref(grpc_subchannel *channel, const char *file, int line, const char *reason); +void grpc_subchannel_unref(grpc_subchannel *channel, const char *file, int line, const char *reason); +void grpc_subchannel_call_ref(grpc_subchannel_call *call, const char *file, int line, const char *reason); +void grpc_subchannel_call_unref(grpc_subchannel_call *call, const char *file, int line, const char *reason); +#else +#define GRPC_SUBCHANNEL_REF(c, r) grpc_subchannel_ref((c)) +#define GRPC_SUBCHANNEL_UNREF(c, r) grpc_subchannel_unref((c)) +#define GRPC_SUBCHANNEL_CALL_REF(c, r) grpc_subchannel_call_ref((c)) +#define GRPC_SUBCHANNEL_CALL_UNREF(c, r) grpc_subchannel_call_unref((c)) void grpc_subchannel_ref(grpc_subchannel *channel); void grpc_subchannel_unref(grpc_subchannel *channel); +void grpc_subchannel_call_ref(grpc_subchannel_call *call); +void grpc_subchannel_call_unref(grpc_subchannel_call *call); +#endif /** construct a call (possibly asynchronously) */ void grpc_subchannel_create_call(grpc_subchannel *subchannel, @@ -55,9 +74,6 @@ void grpc_subchannel_create_call(grpc_subchannel *subchannel, /** process a transport level op */ void grpc_subchannel_process_transport_op(grpc_subchannel *subchannel, grpc_transport_op *op); -void grpc_subchannel_call_ref(grpc_subchannel_call *call); -void grpc_subchannel_call_unref(grpc_subchannel_call *call); - /** poll the current connectivity state of a channel */ grpc_connectivity_state grpc_subchannel_check_connectivity( grpc_subchannel *channel); diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c index 8c136af841..4857912b4f 100644 --- a/src/core/surface/channel.c +++ b/src/core/surface/channel.c @@ -93,9 +93,8 @@ grpc_channel *grpc_channel_create_from_filters( grpc_channel *channel = gpr_malloc(size); GPR_ASSERT(grpc_is_initialized() && "call grpc_init()"); channel->is_client = is_client; - /* decremented by grpc_channel_destroy, and grpc_client_channel_closed if - * is_client */ - gpr_ref_init(&channel->refs, 1 + is_client); + /* decremented by grpc_channel_destroy */ + gpr_ref_init(&channel->refs, 1); channel->metadata_context = mdctx; channel->grpc_status_string = grpc_mdstr_from_string(mdctx, "grpc-status"); channel->grpc_compression_level_string = @@ -237,33 +236,10 @@ void grpc_channel_internal_unref(grpc_channel *channel) { } } -static void default_consumed(void *arg, int iomgr_success) { - grpc_channel *channel = arg; - GRPC_CHANNEL_INTERNAL_UNREF(channel, "op"); -} - -static void execute_op(grpc_channel *channel, grpc_transport_op *op) { - grpc_channel_element *elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CHANNEL(channel), 0); - if (op->on_consumed == NULL) { - GRPC_CHANNEL_INTERNAL_REF(channel, "op"); - op->on_consumed = gpr_malloc(sizeof(*op->on_consumed)); - grpc_iomgr_closure_init(op->on_consumed, default_consumed, channel); - } - elem->filter->start_transport_op(elem, op); -} - void grpc_channel_destroy(grpc_channel *channel) { - grpc_transport_op op; - memset(&op, 0, sizeof(op)); - op.disconnect = 1; - execute_op(channel, &op); GRPC_CHANNEL_INTERNAL_UNREF(channel, "channel"); } -void grpc_client_channel_closed(grpc_channel_element *elem) { - GRPC_CHANNEL_INTERNAL_UNREF(CHANNEL_FROM_TOP_ELEM(elem), "closed"); -} - grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel) { return CHANNEL_STACK_FROM_CHANNEL(channel); } diff --git a/src/core/surface/channel.h b/src/core/surface/channel.h index 516c0ac559..71f8a55731 100644 --- a/src/core/surface/channel.h +++ b/src/core/surface/channel.h @@ -58,8 +58,6 @@ grpc_mdstr *grpc_channel_get_compresssion_level_string(grpc_channel *channel); grpc_mdstr *grpc_channel_get_message_string(grpc_channel *channel); gpr_uint32 grpc_channel_get_max_message_length(grpc_channel *channel); -void grpc_client_channel_closed(grpc_channel_element *elem); - #ifdef GRPC_CHANNEL_REF_COUNT_DEBUG void grpc_channel_internal_ref(grpc_channel *channel, const char *reason); void grpc_channel_internal_unref(grpc_channel *channel, const char *reason); -- cgit v1.2.3 From d7b68e72f55e34cafd0042623b707814a6c2b64e Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Sun, 28 Jun 2015 11:41:09 -0700 Subject: Simple request unsecure passes with new client_config code --- src/core/channel/client_channel.c | 22 ++-- src/core/client_config/client_config.c | 6 +- src/core/client_config/lb_policies/pick_first.c | 36 +++--- src/core/client_config/lb_policy.c | 27 +++- src/core/client_config/lb_policy.h | 18 ++- src/core/client_config/resolvers/dns_resolver.c | 11 +- src/core/client_config/subchannel.c | 161 ++++++++++++------------ src/core/client_config/subchannel.h | 17 --- src/core/surface/channel_create.c | 1 + 9 files changed, 164 insertions(+), 135 deletions(-) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index 19700a90a6..b33ef7842f 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -297,14 +297,14 @@ static void perform_transport_stream_op(grpc_call_element *elem, grpc_transport_ gpr_mu_lock(&chand->mu_config); lb_policy = chand->lb_policy; if (lb_policy) { - grpc_lb_policy_ref(lb_policy); + GRPC_LB_POLICY_REF(lb_policy, "pick"); gpr_mu_unlock(&chand->mu_config); calld->state = CALL_WAITING_FOR_PICK; gpr_mu_unlock(&calld->mu_state); pick_target(lb_policy, calld); - grpc_lb_policy_unref(lb_policy); + GRPC_LB_POLICY_UNREF(lb_policy, "pick"); } else { calld->state = CALL_WAITING_FOR_CONFIG; add_to_lb_policy_wait_queue_locked_state_config(elem); @@ -332,9 +332,9 @@ static void cc_on_config_changed(void *arg, int iomgr_success) { grpc_resolver *old_resolver; grpc_iomgr_closure *wakeup_closures = NULL; - if (chand->incoming_configuration) { + if (chand->incoming_configuration != NULL) { lb_policy = grpc_client_config_get_lb_policy(chand->incoming_configuration); - grpc_lb_policy_ref(lb_policy); + GRPC_LB_POLICY_REF(lb_policy, "channel"); grpc_client_config_unref(chand->incoming_configuration); } @@ -357,7 +357,7 @@ static void cc_on_config_changed(void *arg, int iomgr_success) { } if (old_lb_policy) { - grpc_lb_policy_unref(old_lb_policy); + GRPC_LB_POLICY_UNREF(old_lb_policy, "channel"); } if (iomgr_success) { @@ -391,14 +391,14 @@ static void cc_start_transport_op(grpc_channel_element *elem, grpc_transport_op if (!is_empty(op, sizeof(*op))) { lb_policy = chand->lb_policy; if (lb_policy) { - grpc_lb_policy_ref(lb_policy); + GRPC_LB_POLICY_REF(lb_policy, "broadcast"); } } gpr_mu_unlock(&chand->mu_config); if (lb_policy) { grpc_lb_policy_broadcast(lb_policy, op); - grpc_lb_policy_unref(lb_policy); + GRPC_LB_POLICY_UNREF(lb_policy, "broadcast"); } if (on_consumed) { @@ -436,7 +436,7 @@ static void destroy_call_elem(grpc_call_element *elem) { case CALL_ACTIVE: subchannel_call = calld->subchannel_call; gpr_mu_unlock(&calld->mu_state); - GRPC_SUBCHANNEL_CALL_UNREF(subchannel_call, "channel"); + grpc_subchannel_call_unref(subchannel_call); break; case CALL_CREATED: case CALL_CANCELLED: @@ -472,11 +472,11 @@ static void init_channel_elem(grpc_channel_element *elem, static void destroy_channel_elem(grpc_channel_element *elem) { channel_data *chand = elem->channel_data; - if (chand->resolver) { + if (chand->resolver != NULL) { grpc_resolver_unref(chand->resolver); } - if (chand->lb_policy) { - grpc_lb_policy_unref(chand->lb_policy); + if (chand->lb_policy != NULL) { + GRPC_LB_POLICY_UNREF(chand->lb_policy, "channel"); } gpr_mu_destroy(&chand->mu_config); } diff --git a/src/core/client_config/client_config.c b/src/core/client_config/client_config.c index bc8dcec54e..4453824148 100644 --- a/src/core/client_config/client_config.c +++ b/src/core/client_config/client_config.c @@ -53,7 +53,7 @@ void grpc_client_config_ref(grpc_client_config *c) { gpr_ref(&c->refs); } void grpc_client_config_unref(grpc_client_config *c) { if (gpr_unref(&c->refs)) { - grpc_lb_policy_unref(c->lb_policy); + GRPC_LB_POLICY_UNREF(c->lb_policy, "client_config"); gpr_free(c); } } @@ -61,10 +61,10 @@ void grpc_client_config_unref(grpc_client_config *c) { void grpc_client_config_set_lb_policy(grpc_client_config *c, grpc_lb_policy *lb_policy) { if (lb_policy) { - grpc_lb_policy_ref(lb_policy); + GRPC_LB_POLICY_REF(lb_policy, "client_config"); } if (c->lb_policy) { - grpc_lb_policy_unref(c->lb_policy); + GRPC_LB_POLICY_UNREF(c->lb_policy, "client_config"); } c->lb_policy = lb_policy; } diff --git a/src/core/client_config/lb_policies/pick_first.c b/src/core/client_config/lb_policies/pick_first.c index e6e743fa7a..9d6c264e37 100644 --- a/src/core/client_config/lb_policies/pick_first.c +++ b/src/core/client_config/lb_policies/pick_first.c @@ -48,8 +48,6 @@ typedef struct pending_pick { typedef struct { /** base policy: must be first */ grpc_lb_policy base; - /** ref count */ - gpr_refcount refs; /** all our subchannels */ grpc_subchannel **subchannels; size_t num_subchannels; @@ -75,18 +73,15 @@ typedef struct { grpc_connectivity_state_tracker state_tracker; } pick_first_lb_policy; -void pf_ref(grpc_lb_policy *pol) { - pick_first_lb_policy *p = (pick_first_lb_policy *)pol; - gpr_ref(&p->refs); -} - -void pf_unref(grpc_lb_policy *pol) { - pick_first_lb_policy *p = (pick_first_lb_policy *)pol; - if (gpr_unref(&p->refs)) { - gpr_free(p->subchannels); - gpr_mu_destroy(&p->mu); - gpr_free(p); +void pf_destroy(grpc_lb_policy *pol) { + pick_first_lb_policy *p = (pick_first_lb_policy*)pol; + size_t i; + for (i = 0; i < p->num_subchannels; i++) { + grpc_subchannel_unref(p->subchannels[i]); } + gpr_free(p->subchannels); + gpr_mu_destroy(&p->mu); + gpr_free(p); } void pf_shutdown(grpc_lb_policy *pol) { @@ -109,7 +104,7 @@ void pf_pick(grpc_lb_policy *pol, grpc_pollset *pollset, p->started_picking = 1; p->checking_subchannel = 0; p->checking_connectivity = GRPC_CHANNEL_IDLE; - pf_ref(pol); + GRPC_LB_POLICY_REF(pol, "pick_first_connectivity"); grpc_subchannel_notify_on_state_change(p->subchannels[p->checking_subchannel], &p->checking_connectivity, &p->connectivity_changed); } grpc_subchannel_add_interested_party(p->subchannels[p->checking_subchannel], pollset); @@ -173,7 +168,7 @@ loop: p->checking_subchannel %= p->num_subchannels; p->checking_connectivity = grpc_subchannel_check_connectivity(p->subchannels[p->checking_subchannel]); p->num_subchannels--; - GRPC_SUBCHANNEL_UNREF(p->subchannels[p->num_subchannels], "pick_first"); + grpc_subchannel_unref(p->subchannels[p->num_subchannels]); add_interested_parties_locked(p); if (p->num_subchannels == 0) { abort(); @@ -184,7 +179,7 @@ loop: gpr_mu_unlock(&p->mu); if (unref) { - pf_unref(&p->base); + GRPC_LB_POLICY_UNREF(&p->base, "pick_first_connectivity"); } } @@ -199,13 +194,13 @@ static void pf_broadcast(grpc_lb_policy *pol, grpc_transport_op *op) { subchannels = gpr_malloc(n * sizeof(*subchannels)); for (i = 0; i < n; i++) { subchannels[i] = p->subchannels[i]; - GRPC_SUBCHANNEL_REF(subchannels[i], "broadcast"); + grpc_subchannel_ref(subchannels[i]); } gpr_mu_unlock(&p->mu); for (i = 0; i < n; i++) { grpc_subchannel_process_transport_op(subchannels[i], op); - GRPC_SUBCHANNEL_UNREF(subchannels[i], "broadcast"); + grpc_subchannel_unref(subchannels[i]); } gpr_free(subchannels); } @@ -227,15 +222,14 @@ static void pf_notify_on_state_change(grpc_lb_policy *pol, grpc_connectivity_sta } static const grpc_lb_policy_vtable pick_first_lb_policy_vtable = { - pf_ref, pf_unref, pf_shutdown, pf_pick, pf_broadcast, pf_check_connectivity, pf_notify_on_state_change}; + pf_destroy, pf_shutdown, pf_pick, pf_broadcast, pf_check_connectivity, pf_notify_on_state_change}; grpc_lb_policy *grpc_create_pick_first_lb_policy(grpc_subchannel **subchannels, size_t num_subchannels) { pick_first_lb_policy *p = gpr_malloc(sizeof(*p)); GPR_ASSERT(num_subchannels); memset(p, 0, sizeof(*p)); - p->base.vtable = &pick_first_lb_policy_vtable; - gpr_ref_init(&p->refs, 1); + grpc_lb_policy_init(&p->base, &pick_first_lb_policy_vtable); p->subchannels = gpr_malloc(sizeof(grpc_subchannel *) * num_subchannels); p->num_subchannels = num_subchannels; memcpy(p->subchannels, subchannels, diff --git a/src/core/client_config/lb_policy.c b/src/core/client_config/lb_policy.c index 2daba14c2a..dfe21cf443 100644 --- a/src/core/client_config/lb_policy.c +++ b/src/core/client_config/lb_policy.c @@ -33,10 +33,33 @@ #include "src/core/client_config/lb_policy.h" -void grpc_lb_policy_ref(grpc_lb_policy *policy) { policy->vtable->ref(policy); } +void grpc_lb_policy_init(grpc_lb_policy *policy, const grpc_lb_policy_vtable *vtable) { + policy->vtable = vtable; + gpr_ref_init(&policy->refs, 1); +} + +#ifdef GRPC_LB_POLICY_REFCOUNT_DEBUG +void grpc_lb_policy_ref(grpc_lb_policy *policy, const char *file, int line, const char *reason) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "LB_POLICY:%p ref %d -> %d %s", + policy, (int)policy->refs.count, (int)policy->refs.count + 1, + reason); +#else +void grpc_lb_policy_ref(grpc_lb_policy *policy) { +#endif + gpr_ref(&policy->refs); +} +#ifdef GRPC_LB_POLICY_REFCOUNT_DEBUG +void grpc_lb_policy_unref(grpc_lb_policy *policy, const char *file, int line, const char *reason) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "LB_POLICY:%p unref %d -> %d %s", + policy, (int)policy->refs.count, (int)policy->refs.count - 1, + reason); +#else void grpc_lb_policy_unref(grpc_lb_policy *policy) { - policy->vtable->unref(policy); +#endif + if (gpr_unref(&policy->refs)) { + policy->vtable->destroy(policy); + } } void grpc_lb_policy_shutdown(grpc_lb_policy *policy) { diff --git a/src/core/client_config/lb_policy.h b/src/core/client_config/lb_policy.h index dcefa6e27e..890a89f5c9 100644 --- a/src/core/client_config/lb_policy.h +++ b/src/core/client_config/lb_policy.h @@ -46,11 +46,11 @@ typedef void (*grpc_lb_completion)(void *cb_arg, grpc_subchannel *subchannel, struct grpc_lb_policy { const grpc_lb_policy_vtable *vtable; + gpr_refcount refs; }; struct grpc_lb_policy_vtable { - void (*ref)(grpc_lb_policy *policy); - void (*unref)(grpc_lb_policy *policy); + void (*destroy)(grpc_lb_policy *policy); void (*shutdown)(grpc_lb_policy *policy); @@ -70,8 +70,22 @@ struct grpc_lb_policy_vtable { void (*notify_on_state_change)(grpc_lb_policy *policy, grpc_connectivity_state *state, grpc_iomgr_closure *closure); }; +#define GRPC_LB_POLICY_REFCOUNT_DEBUG + +#ifdef GRPC_LB_POLICY_REFCOUNT_DEBUG +#define GRPC_LB_POLICY_REF(p, r) grpc_lb_policy_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_LB_POLICY_UNREF(p, r) grpc_lb_policy_unref((p), __FILE__, __LINE__, (r)) +void grpc_lb_policy_ref(grpc_lb_policy *policy, const char *file, int line, const char *reason); +void grpc_lb_policy_unref(grpc_lb_policy *policy, const char *file, int line, const char *reason); +#else +#define GRPC_LB_POLICY_REF(p, r) grpc_lb_policy_ref((p)) +#define GRPC_LB_POLICY_UNREF(p, r) grpc_lb_policy_unref((p)) void grpc_lb_policy_ref(grpc_lb_policy *policy); void grpc_lb_policy_unref(grpc_lb_policy *policy); +#endif + +/** called by concrete implementations to initialize the base struct */ +void grpc_lb_policy_init(grpc_lb_policy *policy, const grpc_lb_policy_vtable *vtable); /** Start shutting down (fail any pending picks) */ void grpc_lb_policy_shutdown(grpc_lb_policy *policy); diff --git a/src/core/client_config/resolvers/dns_resolver.c b/src/core/client_config/resolvers/dns_resolver.c index ba82675275..8693bcf5eb 100644 --- a/src/core/client_config/resolvers/dns_resolver.c +++ b/src/core/client_config/resolvers/dns_resolver.c @@ -145,6 +145,7 @@ static void dns_on_resolved(void *arg, grpc_resolved_addresses *addresses) { grpc_client_config *config = NULL; grpc_subchannel **subchannels; grpc_subchannel_args args; + grpc_lb_policy *lb_policy; size_t i; if (addresses) { config = grpc_client_config_create(); @@ -156,8 +157,9 @@ static void dns_on_resolved(void *arg, grpc_resolved_addresses *addresses) { subchannels[i] = grpc_subchannel_factory_create_subchannel( r->subchannel_factory, &args); } - grpc_client_config_set_lb_policy( - config, r->lb_policy_factory(subchannels, addresses->naddrs)); + lb_policy = r->lb_policy_factory(subchannels, addresses->naddrs); + grpc_client_config_set_lb_policy(config, lb_policy); + GRPC_LB_POLICY_UNREF(lb_policy, "construction"); } gpr_mu_lock(&r->mu); if (r->resolved_config) { @@ -167,6 +169,8 @@ static void dns_on_resolved(void *arg, grpc_resolved_addresses *addresses) { r->resolved_version++; dns_maybe_finish_next_locked(r); gpr_mu_unlock(&r->mu); + + dns_unref(&r->base); } static void dns_start_resolving_locked(dns_resolver *r) { @@ -188,6 +192,9 @@ static void dns_maybe_finish_next_locked(dns_resolver *r) { static void dns_destroy(dns_resolver *r) { gpr_mu_destroy(&r->mu); + if (r->resolved_config) { + grpc_client_config_unref(r->resolved_config); + } grpc_subchannel_factory_unref(r->subchannel_factory); gpr_free(r->name); gpr_free(r->default_port); diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c index e441befc0c..b4da9cda3f 100644 --- a/src/core/client_config/subchannel.c +++ b/src/core/client_config/subchannel.c @@ -42,7 +42,10 @@ #include "src/core/channel/connectivity_state.h" typedef struct { - gpr_refcount refs; + /* all fields protected by subchannel->mu */ + /** refcount */ + int refs; + /** parent subchannel */ grpc_subchannel *subchannel; } connection; @@ -54,7 +57,6 @@ typedef struct waiting_for_connect { } waiting_for_connect; struct grpc_subchannel { - gpr_refcount refs; grpc_connector *connector; /** non-transport related channel filters */ @@ -83,6 +85,8 @@ struct grpc_subchannel { /** active connection */ connection *active; + /** refcount */ + int refs; /** are we connecting */ int connecting; /** things waiting for a connection */ @@ -105,76 +109,76 @@ static grpc_connectivity_state compute_connectivity_locked(grpc_subchannel *c); static gpr_timespec compute_connect_deadline(grpc_subchannel *c); static void subchannel_connected(void *subchannel, int iomgr_success); +static void subchannel_ref_locked(grpc_subchannel *c); +static int subchannel_unref_locked(grpc_subchannel *c) GRPC_MUST_USE_RESULT; +static void connection_ref_locked(connection *c); +static grpc_subchannel *connection_unref_locked(connection *c) GRPC_MUST_USE_RESULT; +static void subchannel_destroy(grpc_subchannel *c); + /* * connection implementation */ -#ifdef GRPC_SUBCHANNEL_REFCOUNT_DEBUG -#define CONNECTION_REF(c, r) connection_ref((c), __FILE__, __LINE__, (r)) -#define CONNECTION_UNREF(c, r) connection_unref((c), __FILE__, __LINE__, (r)) -#else -#define CONNECTION_REF(c, r) connection_ref((c)) -#define CONNECTION_UNREF(c, r) connection_unref((c)) -#endif - -#ifdef GRPC_SUBCHANNEL_REFCOUNT_DEBUG -static void connection_ref(connection *c, const char *file, int line, const char *reason) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SUBCONN:%p ref %d -> %d %s", - c, (int)c->refs.count, (int)c->refs.count + 1, - reason); -#else -static void connection_ref(connection *c) { -#endif - gpr_ref(&c->refs); +static void connection_destroy(connection *c) { + GPR_ASSERT(c->refs == 0); + grpc_channel_stack_destroy(CHANNEL_STACK_FROM_CONNECTION(c)); + gpr_free(c); } -#ifdef GRPC_SUBCHANNEL_REFCOUNT_DEBUG -static void connection_unref(connection *c, const char *file, int line, const char *reason) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SUBCONN:%p unref %d -> %d %s", - c, (int)c->refs.count, (int)c->refs.count - 1, - reason); -#else -static void connection_unref(connection *c) { -#endif - if (gpr_unref(&c->refs)) { - GRPC_SUBCHANNEL_UNREF(c->subchannel, "connection"); - gpr_free(c); +static void connection_ref_locked(connection *c) { + subchannel_ref_locked(c->subchannel); + ++c->refs; +} + +static grpc_subchannel *connection_unref_locked(connection *c) { + grpc_subchannel *destroy = NULL; + if (subchannel_unref_locked(c->subchannel)) { + destroy = c->subchannel; + } + if (--c->refs == 0 && c->subchannel->active != c) { + connection_destroy(c); } + return destroy; } + /* * grpc_subchannel implementation */ -#ifdef GRPC_SUBCHANNEL_REFCOUNT_DEBUG -void grpc_subchannel_ref(grpc_subchannel *c, const char *file, int line, const char *reason) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SUBCHAN:%p ref %d -> %d %s", - c, (int)c->refs.count, (int)c->refs.count + 1, - reason); -#else -void grpc_subchannel_ref(grpc_subchannel *c) { -#endif - gpr_ref(&c->refs); +static void subchannel_ref_locked(grpc_subchannel *c) { + ++c->refs; +} + +static int subchannel_unref_locked(grpc_subchannel *c) { + return --c->refs == 0; +} + +void grpc_subchannel_ref(grpc_subchannel *c) { + gpr_mu_lock(&c->mu); + subchannel_ref_locked(c); + gpr_mu_unlock(&c->mu); } -#ifdef GRPC_SUBCHANNEL_REFCOUNT_DEBUG -void grpc_subchannel_unref(grpc_subchannel *c, const char *file, int line, const char *reason) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SUBCHAN:%p unref %d -> %d %s", - c, (int)c->refs.count, (int)c->refs.count - 1, - reason); -#else void grpc_subchannel_unref(grpc_subchannel *c) { -#endif - if (gpr_unref(&c->refs)) { - if (c->active != NULL) CONNECTION_UNREF(c->active, "subchannel"); - gpr_free(c->filters); - grpc_channel_args_destroy(c->args); - gpr_free(c->addr); - grpc_mdctx_unref(c->mdctx); - grpc_pollset_set_destroy(&c->pollset_set); - grpc_connectivity_state_destroy(&c->state_tracker); - gpr_free(c); - } + int destroy; + gpr_mu_lock(&c->mu); + destroy = subchannel_unref_locked(c); + gpr_mu_unlock(&c->mu); + if (destroy) subchannel_destroy(c); +} + +static void subchannel_destroy(grpc_subchannel *c) { + if (c->active != NULL) { + connection_destroy(c->active); + } + gpr_free(c->filters); + grpc_channel_args_destroy(c->args); + gpr_free(c->addr); + grpc_mdctx_unref(c->mdctx); + grpc_pollset_set_destroy(&c->pollset_set); + grpc_connectivity_state_destroy(&c->state_tracker); + gpr_free(c); } void grpc_subchannel_add_interested_party(grpc_subchannel *c, @@ -191,7 +195,7 @@ grpc_subchannel *grpc_subchannel_create(grpc_connector *connector, grpc_subchannel_args *args) { grpc_subchannel *c = gpr_malloc(sizeof(*c)); memset(c, 0, sizeof(*c)); - gpr_ref_init(&c->refs, 1); + c->refs = 1; c->connector = connector; grpc_connector_ref(c->connector); c->num_filters = args->filter_count; @@ -232,7 +236,7 @@ void grpc_subchannel_create_call(grpc_subchannel *c, gpr_mu_lock(&c->mu); if (c->active != NULL) { con = c->active; - CONNECTION_REF(con, "call"); + connection_ref_locked(con); gpr_mu_unlock(&c->mu); *target = create_call(con, initial_op); @@ -248,7 +252,7 @@ void grpc_subchannel_create_call(grpc_subchannel *c, if (!c->connecting) { c->connecting = 1; connectivity_state_changed_locked(c); - GRPC_SUBCHANNEL_REF(c, "connection"); + subchannel_ref_locked(c); gpr_mu_unlock(&c->mu); start_connect(c); @@ -274,7 +278,7 @@ void grpc_subchannel_notify_on_state_change(grpc_subchannel *c, if (grpc_connectivity_state_notify_on_state_change(&c->state_tracker, state, notify)) { do_connect = 1; c->connecting = 1; - GRPC_SUBCHANNEL_REF(c, "connection"); + subchannel_ref_locked(c); grpc_connectivity_state_set(&c->state_tracker, compute_connectivity_locked(c)); } gpr_mu_unlock(&c->mu); @@ -294,6 +298,7 @@ static void publish_transport(grpc_subchannel *c) { size_t num_filters; const grpc_channel_filter **filters; waiting_for_connect *w4c; + int destroy; num_filters = c->num_filters + c->connecting_result.num_filters + 1; filters = gpr_malloc(sizeof(*filters) * num_filters); @@ -305,7 +310,7 @@ static void publish_transport(grpc_subchannel *c) { con = gpr_malloc(sizeof(connection) + channel_stack_size); stk = (grpc_channel_stack *)(con + 1); - gpr_ref_init(&con->refs, 1); + con->refs = 0; con->subchannel = c; grpc_channel_stack_init(filters, num_filters, c->args, c->mdctx, stk); grpc_connected_channel_bind_transport(stk, c->connecting_result.transport); @@ -319,9 +324,14 @@ static void publish_transport(grpc_subchannel *c) { while ((w4c = c->waiting)) { abort(); /* not implemented */ } + destroy = subchannel_unref_locked(c); gpr_mu_unlock(&c->mu); gpr_free(filters); + + if (destroy) { + subchannel_destroy(c); + } } static void subchannel_connected(void *arg, int iomgr_success) { @@ -329,7 +339,11 @@ static void subchannel_connected(void *arg, int iomgr_success) { if (c->connecting_result.transport) { publish_transport(c); } else { - GRPC_SUBCHANNEL_UNREF(c, "connection"); + int destroy; + gpr_mu_lock(&c->mu); + destroy = subchannel_unref_locked(c); + gpr_mu_unlock(&c->mu); + if (destroy) subchannel_destroy(c); /* TODO(ctiller): retry after sleeping */ abort(); } @@ -358,29 +372,22 @@ static void connectivity_state_changed_locked(grpc_subchannel *c) { * grpc_subchannel_call implementation */ -#ifdef GRPC_SUBCHANNEL_REFCOUNT_DEBUG -void grpc_subchannel_call_ref(grpc_subchannel_call *c, const char *file, int line, const char *reason) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SUBCALL:%p ref %d -> %d %s", - c, (int)c->refs.count, (int)c->refs.count + 1, - reason); -#else void grpc_subchannel_call_ref(grpc_subchannel_call *c) { -#endif gpr_ref(&c->refs); } -#ifdef GRPC_SUBCHANNEL_REFCOUNT_DEBUG -void grpc_subchannel_call_unref(grpc_subchannel_call *c, const char *file, int line, const char *reason) { - gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "SUBCALL:%p unref %d -> %d %s", - c, (int)c->refs.count, (int)c->refs.count - 1, - reason); -#else void grpc_subchannel_call_unref(grpc_subchannel_call *c) { -#endif if (gpr_unref(&c->refs)) { + gpr_mu *mu = &c->connection->subchannel->mu; + grpc_subchannel *destroy; grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(c)); - CONNECTION_UNREF(c->connection, "call"); + gpr_mu_lock(mu); + destroy = connection_unref_locked(c->connection); + gpr_mu_unlock(mu); gpr_free(c); + if (destroy) { + subchannel_destroy(destroy); + } } } diff --git a/src/core/client_config/subchannel.h b/src/core/client_config/subchannel.h index 7cdcccce8f..8155aba14c 100644 --- a/src/core/client_config/subchannel.h +++ b/src/core/client_config/subchannel.h @@ -37,33 +37,16 @@ #include "src/core/channel/channel_stack.h" #include "src/core/client_config/connector.h" -#define GRPC_SUBCHANNEL_REFCOUNT_DEBUG - /** A (sub-)channel that knows how to connect to exactly one target address. Provides a target for load balancing. */ typedef struct grpc_subchannel grpc_subchannel; typedef struct grpc_subchannel_call grpc_subchannel_call; typedef struct grpc_subchannel_args grpc_subchannel_args; -#ifdef GRPC_SUBCHANNEL_REFCOUNT_DEBUG -#define GRPC_SUBCHANNEL_REF(c, r) grpc_subchannel_ref((c), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_UNREF(c, r) grpc_subchannel_unref((c), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_CALL_REF(c, r) grpc_subchannel_call_ref((c), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_CALL_UNREF(c, r) grpc_subchannel_call_unref((c), __FILE__, __LINE__, (r)) -void grpc_subchannel_ref(grpc_subchannel *channel, const char *file, int line, const char *reason); -void grpc_subchannel_unref(grpc_subchannel *channel, const char *file, int line, const char *reason); -void grpc_subchannel_call_ref(grpc_subchannel_call *call, const char *file, int line, const char *reason); -void grpc_subchannel_call_unref(grpc_subchannel_call *call, const char *file, int line, const char *reason); -#else -#define GRPC_SUBCHANNEL_REF(c, r) grpc_subchannel_ref((c)) -#define GRPC_SUBCHANNEL_UNREF(c, r) grpc_subchannel_unref((c)) -#define GRPC_SUBCHANNEL_CALL_REF(c, r) grpc_subchannel_call_ref((c)) -#define GRPC_SUBCHANNEL_CALL_UNREF(c, r) grpc_subchannel_call_unref((c)) void grpc_subchannel_ref(grpc_subchannel *channel); void grpc_subchannel_unref(grpc_subchannel *channel); void grpc_subchannel_call_ref(grpc_subchannel_call *call); void grpc_subchannel_call_unref(grpc_subchannel_call *call); -#endif /** construct a call (possibly asynchronously) */ void grpc_subchannel_create_call(grpc_subchannel *subchannel, diff --git a/src/core/surface/channel_create.c b/src/core/surface/channel_create.c index a00c08a830..494a44725a 100644 --- a/src/core/surface/channel_create.c +++ b/src/core/surface/channel_create.c @@ -163,6 +163,7 @@ grpc_channel *grpc_channel_create(const char *target, channel = grpc_channel_create_from_filters(filters, n, args, mdctx, 1); grpc_client_channel_set_resolver(grpc_channel_get_channel_stack(channel), resolver); + grpc_resolver_unref(resolver); return channel; } -- cgit v1.2.3 From 08a1cf8f4fd747ab331393916bd5d9cc7f4804c1 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 29 Jun 2015 09:37:52 -0700 Subject: Use connectivity state tracking code in chttp2 transport --- BUILD | 12 +-- Makefile | 4 +- build.json | 4 +- gRPC.podspec | 6 +- src/core/channel/client_channel.c | 2 +- src/core/channel/connectivity_state.c | 95 -------------------- src/core/channel/connectivity_state.h | 66 -------------- src/core/client_config/lb_policies/pick_first.c | 2 +- src/core/client_config/subchannel.c | 2 +- src/core/transport/chttp2/internal.h | 6 +- src/core/transport/chttp2_transport.c | 55 +++++------- src/core/transport/connectivity_state.c | 100 +++++++++++++++++++++ src/core/transport/connectivity_state.h | 71 +++++++++++++++ tools/doxygen/Doxyfile.core.internal | 4 +- tools/run_tests/sources_and_headers.json | 12 +-- vsprojects/grpc/grpc.vcxproj | 6 +- vsprojects/grpc/grpc.vcxproj.filters | 12 +-- vsprojects/grpc_unsecure/grpc_unsecure.vcxproj | 6 +- .../grpc_unsecure/grpc_unsecure.vcxproj.filters | 12 +-- 19 files changed, 237 insertions(+), 240 deletions(-) delete mode 100644 src/core/channel/connectivity_state.c delete mode 100644 src/core/channel/connectivity_state.h create mode 100644 src/core/transport/connectivity_state.c create mode 100644 src/core/transport/connectivity_state.h (limited to 'src/core/channel/client_channel.c') diff --git a/BUILD b/BUILD index a21004c4ed..a02295a677 100644 --- a/BUILD +++ b/BUILD @@ -152,7 +152,6 @@ cc_library( "src/core/channel/channel_stack.h", "src/core/channel/client_channel.h", "src/core/channel/connected_channel.h", - "src/core/channel/connectivity_state.h", "src/core/channel/context.h", "src/core/channel/http_client_filter.h", "src/core/channel/http_server_filter.h", @@ -237,6 +236,7 @@ cc_library( "src/core/transport/chttp2/timeout_encoding.h", "src/core/transport/chttp2/varint.h", "src/core/transport/chttp2_transport.h", + "src/core/transport/connectivity_state.h", "src/core/transport/metadata.h", "src/core/transport/stream_op.h", "src/core/transport/transport.h", @@ -270,7 +270,6 @@ cc_library( "src/core/channel/channel_stack.c", "src/core/channel/client_channel.c", "src/core/channel/connected_channel.c", - "src/core/channel/connectivity_state.c", "src/core/channel/http_client_filter.c", "src/core/channel/http_server_filter.c", "src/core/channel/noop_filter.c", @@ -368,6 +367,7 @@ cc_library( "src/core/transport/chttp2/varint.c", "src/core/transport/chttp2/writing.c", "src/core/transport/chttp2_transport.c", + "src/core/transport/connectivity_state.c", "src/core/transport/metadata.c", "src/core/transport/stream_op.c", "src/core/transport/transport.c", @@ -404,7 +404,6 @@ cc_library( "src/core/channel/channel_stack.h", "src/core/channel/client_channel.h", "src/core/channel/connected_channel.h", - "src/core/channel/connectivity_state.h", "src/core/channel/context.h", "src/core/channel/http_client_filter.h", "src/core/channel/http_server_filter.h", @@ -489,6 +488,7 @@ cc_library( "src/core/transport/chttp2/timeout_encoding.h", "src/core/transport/chttp2/varint.h", "src/core/transport/chttp2_transport.h", + "src/core/transport/connectivity_state.h", "src/core/transport/metadata.h", "src/core/transport/stream_op.h", "src/core/transport/transport.h", @@ -500,7 +500,6 @@ cc_library( "src/core/channel/channel_stack.c", "src/core/channel/client_channel.c", "src/core/channel/connected_channel.c", - "src/core/channel/connectivity_state.c", "src/core/channel/http_client_filter.c", "src/core/channel/http_server_filter.c", "src/core/channel/noop_filter.c", @@ -598,6 +597,7 @@ cc_library( "src/core/transport/chttp2/varint.c", "src/core/transport/chttp2/writing.c", "src/core/transport/chttp2_transport.c", + "src/core/transport/connectivity_state.c", "src/core/transport/metadata.c", "src/core/transport/stream_op.c", "src/core/transport/transport.c", @@ -940,7 +940,6 @@ objc_library( "src/core/channel/channel_stack.c", "src/core/channel/client_channel.c", "src/core/channel/connected_channel.c", - "src/core/channel/connectivity_state.c", "src/core/channel/http_client_filter.c", "src/core/channel/http_server_filter.c", "src/core/channel/noop_filter.c", @@ -1038,6 +1037,7 @@ objc_library( "src/core/transport/chttp2/varint.c", "src/core/transport/chttp2/writing.c", "src/core/transport/chttp2_transport.c", + "src/core/transport/connectivity_state.c", "src/core/transport/metadata.c", "src/core/transport/stream_op.c", "src/core/transport/transport.c", @@ -1058,7 +1058,6 @@ objc_library( "src/core/channel/channel_stack.h", "src/core/channel/client_channel.h", "src/core/channel/connected_channel.h", - "src/core/channel/connectivity_state.h", "src/core/channel/context.h", "src/core/channel/http_client_filter.h", "src/core/channel/http_server_filter.h", @@ -1143,6 +1142,7 @@ objc_library( "src/core/transport/chttp2/timeout_encoding.h", "src/core/transport/chttp2/varint.h", "src/core/transport/chttp2_transport.h", + "src/core/transport/connectivity_state.h", "src/core/transport/metadata.h", "src/core/transport/stream_op.h", "src/core/transport/transport.h", diff --git a/Makefile b/Makefile index 87c36da6a3..1038158524 100644 --- a/Makefile +++ b/Makefile @@ -3024,7 +3024,6 @@ LIBGRPC_SRC = \ src/core/channel/channel_stack.c \ src/core/channel/client_channel.c \ src/core/channel/connected_channel.c \ - src/core/channel/connectivity_state.c \ src/core/channel/http_client_filter.c \ src/core/channel/http_server_filter.c \ src/core/channel/noop_filter.c \ @@ -3122,6 +3121,7 @@ LIBGRPC_SRC = \ src/core/transport/chttp2/varint.c \ src/core/transport/chttp2/writing.c \ src/core/transport/chttp2_transport.c \ + src/core/transport/connectivity_state.c \ src/core/transport/metadata.c \ src/core/transport/stream_op.c \ src/core/transport/transport.c \ @@ -3284,7 +3284,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/channel/channel_stack.c \ src/core/channel/client_channel.c \ src/core/channel/connected_channel.c \ - src/core/channel/connectivity_state.c \ src/core/channel/http_client_filter.c \ src/core/channel/http_server_filter.c \ src/core/channel/noop_filter.c \ @@ -3382,6 +3381,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/transport/chttp2/varint.c \ src/core/transport/chttp2/writing.c \ src/core/transport/chttp2_transport.c \ + src/core/transport/connectivity_state.c \ src/core/transport/metadata.c \ src/core/transport/stream_op.c \ src/core/transport/transport.c \ diff --git a/build.json b/build.json index 541d5a3dfc..c77b7340ba 100644 --- a/build.json +++ b/build.json @@ -113,7 +113,6 @@ "src/core/channel/channel_stack.h", "src/core/channel/client_channel.h", "src/core/channel/connected_channel.h", - "src/core/channel/connectivity_state.h", "src/core/channel/context.h", "src/core/channel/http_client_filter.h", "src/core/channel/http_server_filter.h", @@ -198,6 +197,7 @@ "src/core/transport/chttp2/timeout_encoding.h", "src/core/transport/chttp2/varint.h", "src/core/transport/chttp2_transport.h", + "src/core/transport/connectivity_state.h", "src/core/transport/metadata.h", "src/core/transport/stream_op.h", "src/core/transport/transport.h", @@ -209,7 +209,6 @@ "src/core/channel/channel_stack.c", "src/core/channel/client_channel.c", "src/core/channel/connected_channel.c", - "src/core/channel/connectivity_state.c", "src/core/channel/http_client_filter.c", "src/core/channel/http_server_filter.c", "src/core/channel/noop_filter.c", @@ -307,6 +306,7 @@ "src/core/transport/chttp2/varint.c", "src/core/transport/chttp2/writing.c", "src/core/transport/chttp2_transport.c", + "src/core/transport/connectivity_state.c", "src/core/transport/metadata.c", "src/core/transport/stream_op.c", "src/core/transport/transport.c", diff --git a/gRPC.podspec b/gRPC.podspec index ed82732bd8..a292056d56 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -154,7 +154,6 @@ Pod::Spec.new do |s| 'src/core/channel/channel_stack.h', 'src/core/channel/client_channel.h', 'src/core/channel/connected_channel.h', - 'src/core/channel/connectivity_state.h', 'src/core/channel/context.h', 'src/core/channel/http_client_filter.h', 'src/core/channel/http_server_filter.h', @@ -239,6 +238,7 @@ Pod::Spec.new do |s| 'src/core/transport/chttp2/timeout_encoding.h', 'src/core/transport/chttp2/varint.h', 'src/core/transport/chttp2_transport.h', + 'src/core/transport/connectivity_state.h', 'src/core/transport/metadata.h', 'src/core/transport/stream_op.h', 'src/core/transport/transport.h', @@ -279,7 +279,6 @@ Pod::Spec.new do |s| 'src/core/channel/channel_stack.c', 'src/core/channel/client_channel.c', 'src/core/channel/connected_channel.c', - 'src/core/channel/connectivity_state.c', 'src/core/channel/http_client_filter.c', 'src/core/channel/http_server_filter.c', 'src/core/channel/noop_filter.c', @@ -377,6 +376,7 @@ Pod::Spec.new do |s| 'src/core/transport/chttp2/varint.c', 'src/core/transport/chttp2/writing.c', 'src/core/transport/chttp2_transport.c', + 'src/core/transport/connectivity_state.c', 'src/core/transport/metadata.c', 'src/core/transport/stream_op.c', 'src/core/transport/transport.c', @@ -412,7 +412,6 @@ Pod::Spec.new do |s| 'src/core/channel/channel_stack.h', 'src/core/channel/client_channel.h', 'src/core/channel/connected_channel.h', - 'src/core/channel/connectivity_state.h', 'src/core/channel/context.h', 'src/core/channel/http_client_filter.h', 'src/core/channel/http_server_filter.h', @@ -497,6 +496,7 @@ Pod::Spec.new do |s| 'src/core/transport/chttp2/timeout_encoding.h', 'src/core/transport/chttp2/varint.h', 'src/core/transport/chttp2_transport.h', + 'src/core/transport/connectivity_state.h', 'src/core/transport/metadata.h', 'src/core/transport/stream_op.h', 'src/core/transport/transport.h', diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index b33ef7842f..e2f8debdfa 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -38,10 +38,10 @@ #include "src/core/channel/channel_args.h" #include "src/core/channel/connected_channel.h" -#include "src/core/channel/connectivity_state.h" #include "src/core/iomgr/iomgr.h" #include "src/core/iomgr/pollset_set.h" #include "src/core/support/string.h" +#include "src/core/transport/connectivity_state.h" #include #include #include diff --git a/src/core/channel/connectivity_state.c b/src/core/channel/connectivity_state.c deleted file mode 100644 index 0ee268ee59..0000000000 --- a/src/core/channel/connectivity_state.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "src/core/channel/connectivity_state.h" -#include - -void grpc_connectivity_state_init(grpc_connectivity_state_tracker *tracker, grpc_connectivity_state init_state) { - tracker->current_state = init_state; - tracker->watchers = NULL; -} - -void grpc_connectivity_state_destroy(grpc_connectivity_state_tracker *tracker) { - grpc_connectivity_state_watcher *w; - while ((w = tracker->watchers)) { - tracker->watchers = w->next; - - if (GRPC_CHANNEL_FATAL_FAILURE != *w->current) { - *w->current = GRPC_CHANNEL_FATAL_FAILURE; - grpc_iomgr_add_callback(w->notify); - } else { - grpc_iomgr_add_delayed_callback(w->notify, 0); - } - gpr_free(w); - } -} - -grpc_connectivity_state grpc_connectivity_state_check(grpc_connectivity_state_tracker *tracker) { - return tracker->current_state; -} - -int grpc_connectivity_state_notify_on_state_change(grpc_connectivity_state_tracker *tracker, grpc_connectivity_state *current, grpc_iomgr_closure *notify) { - if (tracker->current_state != *current) { - *current = tracker->current_state; - grpc_iomgr_add_callback(notify); - } else { - grpc_connectivity_state_watcher *w = gpr_malloc(sizeof(*w)); - w->current = current; - w->notify = notify; - w->next = tracker->watchers; - tracker->watchers = w; - } - return tracker->current_state == GRPC_CHANNEL_IDLE; -} - -void grpc_connectivity_state_set(grpc_connectivity_state_tracker *tracker, grpc_connectivity_state state) { - grpc_connectivity_state_watcher *new = NULL; - grpc_connectivity_state_watcher *w; - if (tracker->current_state == state) { - return; - } - tracker->current_state = state; - while ((w = tracker->watchers)) { - tracker->watchers = w->next; - - if (state != *w->current) { - *w->current = state; - grpc_iomgr_add_callback(w->notify); - gpr_free(w); - } else { - w->next = new; - new = w; - } - } - tracker->watchers = new; -} diff --git a/src/core/channel/connectivity_state.h b/src/core/channel/connectivity_state.h deleted file mode 100644 index ebc1acc559..0000000000 --- a/src/core/channel/connectivity_state.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef GRPC_INTERNAL_CORE_CHANNEL_CONNECTIVITY_STATE_H -#define GRPC_INTERNAL_CORE_CHANNEL_CONNECTIVITY_STATE_H - -#include -#include "src/core/iomgr/iomgr.h" - -typedef struct grpc_connectivity_state_watcher { - /** we keep watchers in a linked list */ - struct grpc_connectivity_state_watcher *next; - /** closure to notify on change */ - grpc_iomgr_closure *notify; - /** the current state as believed by the watcher */ - grpc_connectivity_state *current; -} grpc_connectivity_state_watcher; - -typedef struct { - /** current connectivity state */ - grpc_connectivity_state current_state; - /** all our watchers */ - grpc_connectivity_state_watcher *watchers; -} grpc_connectivity_state_tracker; - -void grpc_connectivity_state_init(grpc_connectivity_state_tracker *tracker, grpc_connectivity_state init_state); -void grpc_connectivity_state_destroy(grpc_connectivity_state_tracker *tracker); - -void grpc_connectivity_state_set(grpc_connectivity_state_tracker *tracker, grpc_connectivity_state state); - -grpc_connectivity_state grpc_connectivity_state_check(grpc_connectivity_state_tracker *tracker); - -/** Return 1 if the channel should start connecting, 0 otherwise */ -int grpc_connectivity_state_notify_on_state_change(grpc_connectivity_state_tracker *tracker, grpc_connectivity_state *current, grpc_iomgr_closure *notify); - -#endif /* GRPC_INTERNAL_CORE_CHANNEL_CONNECTIVITY_STATE_H */ diff --git a/src/core/client_config/lb_policies/pick_first.c b/src/core/client_config/lb_policies/pick_first.c index 9d6c264e37..cdc7e75140 100644 --- a/src/core/client_config/lb_policies/pick_first.c +++ b/src/core/client_config/lb_policies/pick_first.c @@ -36,7 +36,7 @@ #include #include -#include "src/core/channel/connectivity_state.h" +#include "src/core/transport/connectivity_state.h" typedef struct pending_pick { struct pending_pick *next; diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c index b4da9cda3f..2f5843b2a4 100644 --- a/src/core/client_config/subchannel.c +++ b/src/core/client_config/subchannel.c @@ -39,7 +39,7 @@ #include "src/core/channel/channel_args.h" #include "src/core/channel/connected_channel.h" -#include "src/core/channel/connectivity_state.h" +#include "src/core/transport/connectivity_state.h" typedef struct { /* all fields protected by subchannel->mu */ diff --git a/src/core/transport/chttp2/internal.h b/src/core/transport/chttp2/internal.h index 93235aef55..7e2e75f97d 100644 --- a/src/core/transport/chttp2/internal.h +++ b/src/core/transport/chttp2/internal.h @@ -34,7 +34,6 @@ #ifndef GRPC_INTERNAL_CORE_CHTTP2_INTERNAL_H #define GRPC_INTERNAL_CORE_CHTTP2_INTERNAL_H -#include "src/core/transport/transport_impl.h" #include "src/core/iomgr/endpoint.h" #include "src/core/transport/chttp2/frame.h" #include "src/core/transport/chttp2/frame_data.h" @@ -47,6 +46,8 @@ #include "src/core/transport/chttp2/incoming_metadata.h" #include "src/core/transport/chttp2/stream_encoder.h" #include "src/core/transport/chttp2/stream_map.h" +#include "src/core/transport/connectivity_state.h" +#include "src/core/transport/transport_impl.h" typedef struct grpc_chttp2_transport grpc_chttp2_transport; typedef struct grpc_chttp2_stream grpc_chttp2_stream; @@ -335,8 +336,7 @@ struct grpc_chttp2_transport { void *accept_stream_user_data; /** connectivity tracking */ - grpc_iomgr_closure *on_connectivity_changed; - grpc_connectivity_state *connectivity; + grpc_connectivity_state_tracker state_tracker; } channel_callback; }; diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c index 11dd60bbb9..8f909dff37 100644 --- a/src/core/transport/chttp2_transport.c +++ b/src/core/transport/chttp2_transport.c @@ -37,18 +37,19 @@ #include #include +#include +#include +#include +#include +#include + #include "src/core/profiling/timers.h" #include "src/core/support/string.h" #include "src/core/transport/chttp2/http2_errors.h" +#include "src/core/transport/chttp2/internal.h" #include "src/core/transport/chttp2/status_conversion.h" #include "src/core/transport/chttp2/timeout_encoding.h" -#include "src/core/transport/chttp2/internal.h" #include "src/core/transport/transport_impl.h" -#include -#include -#include -#include -#include /* #define REFCOUNTING_DEBUG */ @@ -81,7 +82,6 @@ static const grpc_transport_vtable vtable; static void lock(grpc_chttp2_transport *t); static void unlock(grpc_chttp2_transport *t); -static void unlock_check_channel_callbacks(grpc_chttp2_transport *t); static void unlock_check_read_write_state(grpc_chttp2_transport *t); /* forward declarations of various callbacks that we'll build closures around */ @@ -149,6 +149,7 @@ static void destruct_transport(grpc_chttp2_transport *t) { grpc_chttp2_stream_map_destroy(&t->parsing_stream_map); grpc_chttp2_stream_map_destroy(&t->new_stream_map); + grpc_connectivity_state_destroy(&t->channel_callback.state_tracker); gpr_mu_unlock(&t->mu); gpr_mu_destroy(&t->mu); @@ -229,6 +230,8 @@ static void init_transport(grpc_chttp2_transport *t, t->parsing.deframe_state = is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0; t->writing.is_client = is_client; + grpc_connectivity_state_init(&t->channel_callback.state_tracker, + GRPC_CHANNEL_READY); gpr_slice_buffer_init(&t->global.qbuf); @@ -325,6 +328,8 @@ static void destroy_transport(grpc_transport *gt) { static void close_transport_locked(grpc_chttp2_transport *t) { if (!t->closed) { t->closed = 1; + grpc_connectivity_state_set(&t->channel_callback.state_tracker, + GRPC_CHANNEL_FATAL_FAILURE); if (t->ep) { grpc_endpoint_shutdown(t->ep); } @@ -445,8 +450,6 @@ static void unlock(grpc_chttp2_transport *t) { REF_TRANSPORT(t, "writing"); grpc_chttp2_schedule_closure(&t->global, &t->writing_action, 1); } - /* unlock_check_parser(t); */ - unlock_check_channel_callbacks(t); run_closures = t->global.pending_closures; t->global.pending_closures = NULL; @@ -520,6 +523,9 @@ void grpc_chttp2_add_incoming_goaway( gpr_free(msg); gpr_slice_unref(goaway_text); transport_global->seen_goaway = 1; + grpc_connectivity_state_set( + &TRANSPORT_FROM_GLOBAL(transport_global)->channel_callback.state_tracker, + GRPC_CHANNEL_FATAL_FAILURE); } static void maybe_start_some_streams( @@ -544,9 +550,9 @@ static void maybe_start_some_streams( transport_global->next_stream_id += 2; if (transport_global->next_stream_id >= MAX_CLIENT_STREAM_ID) { - grpc_chttp2_add_incoming_goaway( - transport_global, GRPC_CHTTP2_NO_ERROR, - gpr_slice_from_copied_string("Exceeded sequence number limit")); + grpc_connectivity_state_set(&TRANSPORT_FROM_GLOBAL(transport_global) + ->channel_callback.state_tracker, + GRPC_CHANNEL_TRANSIENT_FAILURE); } stream_global->outgoing_window = @@ -669,10 +675,9 @@ static void perform_transport_op(grpc_transport *gt, grpc_transport_op *op) { } if (op->on_connectivity_state_change) { - GPR_ASSERT(t->channel_callback.on_connectivity_changed == NULL); - t->channel_callback.on_connectivity_changed = - op->on_connectivity_state_change; - t->channel_callback.connectivity = op->connectivity_state; + grpc_connectivity_state_notify_on_state_change( + &t->channel_callback.state_tracker, op->connectivity_state, + op->on_connectivity_state_change); } if (op->send_goaway) { @@ -928,24 +933,6 @@ static void reading_action(void *pt, int iomgr_success_ignored) { * CALLBACK LOOP */ -static void unlock_check_channel_callbacks(grpc_chttp2_transport *t) { - if (t->channel_callback.on_connectivity_changed != NULL) { - grpc_connectivity_state current; - if (t->closed || t->global.seen_goaway) { - current = GRPC_CHANNEL_FATAL_FAILURE; - } else { - current = GRPC_CHANNEL_READY; - } - if (current != *t->channel_callback.connectivity) { - *t->channel_callback.connectivity = current; - grpc_chttp2_schedule_closure( - &t->global, t->channel_callback.on_connectivity_changed, 1); - t->channel_callback.on_connectivity_changed = NULL; - t->channel_callback.connectivity = NULL; - } - } -} - void grpc_chttp2_schedule_closure( grpc_chttp2_transport_global *transport_global, grpc_iomgr_closure *closure, int success) { diff --git a/src/core/transport/connectivity_state.c b/src/core/transport/connectivity_state.c new file mode 100644 index 0000000000..5cbd67ef3c --- /dev/null +++ b/src/core/transport/connectivity_state.c @@ -0,0 +1,100 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "src/core/transport/connectivity_state.h" +#include + +void grpc_connectivity_state_init(grpc_connectivity_state_tracker *tracker, + grpc_connectivity_state init_state) { + tracker->current_state = init_state; + tracker->watchers = NULL; +} + +void grpc_connectivity_state_destroy(grpc_connectivity_state_tracker *tracker) { + grpc_connectivity_state_watcher *w; + while ((w = tracker->watchers)) { + tracker->watchers = w->next; + + if (GRPC_CHANNEL_FATAL_FAILURE != *w->current) { + *w->current = GRPC_CHANNEL_FATAL_FAILURE; + grpc_iomgr_add_callback(w->notify); + } else { + grpc_iomgr_add_delayed_callback(w->notify, 0); + } + gpr_free(w); + } +} + +grpc_connectivity_state grpc_connectivity_state_check( + grpc_connectivity_state_tracker *tracker) { + return tracker->current_state; +} + +int grpc_connectivity_state_notify_on_state_change( + grpc_connectivity_state_tracker *tracker, grpc_connectivity_state *current, + grpc_iomgr_closure *notify) { + if (tracker->current_state != *current) { + *current = tracker->current_state; + grpc_iomgr_add_callback(notify); + } else { + grpc_connectivity_state_watcher *w = gpr_malloc(sizeof(*w)); + w->current = current; + w->notify = notify; + w->next = tracker->watchers; + tracker->watchers = w; + } + return tracker->current_state == GRPC_CHANNEL_IDLE; +} + +void grpc_connectivity_state_set(grpc_connectivity_state_tracker *tracker, + grpc_connectivity_state state) { + grpc_connectivity_state_watcher *new = NULL; + grpc_connectivity_state_watcher *w; + if (tracker->current_state == state) { + return; + } + tracker->current_state = state; + while ((w = tracker->watchers)) { + tracker->watchers = w->next; + + if (state != *w->current) { + *w->current = state; + grpc_iomgr_add_callback(w->notify); + gpr_free(w); + } else { + w->next = new; + new = w; + } + } + tracker->watchers = new; +} diff --git a/src/core/transport/connectivity_state.h b/src/core/transport/connectivity_state.h new file mode 100644 index 0000000000..9a8c57525f --- /dev/null +++ b/src/core/transport/connectivity_state.h @@ -0,0 +1,71 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CONNECTIVITY_STATE_H +#define GRPC_INTERNAL_CORE_TRANSPORT_CONNECTIVITY_STATE_H + +#include +#include "src/core/iomgr/iomgr.h" + +typedef struct grpc_connectivity_state_watcher { + /** we keep watchers in a linked list */ + struct grpc_connectivity_state_watcher *next; + /** closure to notify on change */ + grpc_iomgr_closure *notify; + /** the current state as believed by the watcher */ + grpc_connectivity_state *current; +} grpc_connectivity_state_watcher; + +typedef struct { + /** current connectivity state */ + grpc_connectivity_state current_state; + /** all our watchers */ + grpc_connectivity_state_watcher *watchers; +} grpc_connectivity_state_tracker; + +void grpc_connectivity_state_init(grpc_connectivity_state_tracker *tracker, + grpc_connectivity_state init_state); +void grpc_connectivity_state_destroy(grpc_connectivity_state_tracker *tracker); + +void grpc_connectivity_state_set(grpc_connectivity_state_tracker *tracker, + grpc_connectivity_state state); + +grpc_connectivity_state grpc_connectivity_state_check( + grpc_connectivity_state_tracker *tracker); + +/** Return 1 if the channel should start connecting, 0 otherwise */ +int grpc_connectivity_state_notify_on_state_change( + grpc_connectivity_state_tracker *tracker, grpc_connectivity_state *current, + grpc_iomgr_closure *notify); + +#endif /* GRPC_INTERNAL_CORE_TRANSPORT_CONNECTIVITY_STATE_H */ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 0da1f388c5..e2701eca3a 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -789,7 +789,6 @@ src/core/channel/channel_args.h \ src/core/channel/channel_stack.h \ src/core/channel/client_channel.h \ src/core/channel/connected_channel.h \ -src/core/channel/connectivity_state.h \ src/core/channel/context.h \ src/core/channel/http_client_filter.h \ src/core/channel/http_server_filter.h \ @@ -874,6 +873,7 @@ src/core/transport/chttp2/stream_map.h \ src/core/transport/chttp2/timeout_encoding.h \ src/core/transport/chttp2/varint.h \ src/core/transport/chttp2_transport.h \ +src/core/transport/connectivity_state.h \ src/core/transport/metadata.h \ src/core/transport/stream_op.h \ src/core/transport/transport.h \ @@ -907,7 +907,6 @@ src/core/channel/channel_args.c \ src/core/channel/channel_stack.c \ src/core/channel/client_channel.c \ src/core/channel/connected_channel.c \ -src/core/channel/connectivity_state.c \ src/core/channel/http_client_filter.c \ src/core/channel/http_server_filter.c \ src/core/channel/noop_filter.c \ @@ -1005,6 +1004,7 @@ src/core/transport/chttp2/timeout_encoding.c \ src/core/transport/chttp2/varint.c \ src/core/transport/chttp2/writing.c \ src/core/transport/chttp2_transport.c \ +src/core/transport/connectivity_state.c \ src/core/transport/metadata.c \ src/core/transport/stream_op.c \ src/core/transport/transport.c \ diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 9bb9a4a397..3a858277fa 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -8680,7 +8680,6 @@ "src/core/channel/channel_stack.h", "src/core/channel/client_channel.h", "src/core/channel/connected_channel.h", - "src/core/channel/connectivity_state.h", "src/core/channel/context.h", "src/core/channel/http_client_filter.h", "src/core/channel/http_server_filter.h", @@ -8777,6 +8776,7 @@ "src/core/transport/chttp2/timeout_encoding.h", "src/core/transport/chttp2/varint.h", "src/core/transport/chttp2_transport.h", + "src/core/transport/connectivity_state.h", "src/core/transport/metadata.h", "src/core/transport/stream_op.h", "src/core/transport/transport.h", @@ -8810,8 +8810,6 @@ "src/core/channel/client_channel.h", "src/core/channel/connected_channel.c", "src/core/channel/connected_channel.h", - "src/core/channel/connectivity_state.c", - "src/core/channel/connectivity_state.h", "src/core/channel/context.h", "src/core/channel/http_client_filter.c", "src/core/channel/http_client_filter.h", @@ -9025,6 +9023,8 @@ "src/core/transport/chttp2/writing.c", "src/core/transport/chttp2_transport.c", "src/core/transport/chttp2_transport.h", + "src/core/transport/connectivity_state.c", + "src/core/transport/connectivity_state.h", "src/core/transport/metadata.c", "src/core/transport/metadata.h", "src/core/transport/stream_op.c", @@ -9129,7 +9129,6 @@ "src/core/channel/channel_stack.h", "src/core/channel/client_channel.h", "src/core/channel/connected_channel.h", - "src/core/channel/connectivity_state.h", "src/core/channel/context.h", "src/core/channel/http_client_filter.h", "src/core/channel/http_server_filter.h", @@ -9214,6 +9213,7 @@ "src/core/transport/chttp2/timeout_encoding.h", "src/core/transport/chttp2/varint.h", "src/core/transport/chttp2_transport.h", + "src/core/transport/connectivity_state.h", "src/core/transport/metadata.h", "src/core/transport/stream_op.h", "src/core/transport/transport.h", @@ -9242,8 +9242,6 @@ "src/core/channel/client_channel.h", "src/core/channel/connected_channel.c", "src/core/channel/connected_channel.h", - "src/core/channel/connectivity_state.c", - "src/core/channel/connectivity_state.h", "src/core/channel/context.h", "src/core/channel/http_client_filter.c", "src/core/channel/http_client_filter.h", @@ -9426,6 +9424,8 @@ "src/core/transport/chttp2/writing.c", "src/core/transport/chttp2_transport.c", "src/core/transport/chttp2_transport.h", + "src/core/transport/connectivity_state.c", + "src/core/transport/connectivity_state.h", "src/core/transport/metadata.c", "src/core/transport/metadata.h", "src/core/transport/stream_op.c", diff --git a/vsprojects/grpc/grpc.vcxproj b/vsprojects/grpc/grpc.vcxproj index 25ba0936a1..14ddf95f81 100644 --- a/vsprojects/grpc/grpc.vcxproj +++ b/vsprojects/grpc/grpc.vcxproj @@ -178,7 +178,6 @@ - @@ -263,6 +262,7 @@ + @@ -326,8 +326,6 @@ - - @@ -522,6 +520,8 @@ + + diff --git a/vsprojects/grpc/grpc.vcxproj.filters b/vsprojects/grpc/grpc.vcxproj.filters index 6148abe66e..591fe1bb03 100644 --- a/vsprojects/grpc/grpc.vcxproj.filters +++ b/vsprojects/grpc/grpc.vcxproj.filters @@ -85,9 +85,6 @@ src\core\channel - - src\core\channel - src\core\channel @@ -379,6 +376,9 @@ src\core\transport + + src\core\transport + src\core\transport @@ -488,9 +488,6 @@ src\core\channel - - src\core\channel - src\core\channel @@ -743,6 +740,9 @@ src\core\transport + + src\core\transport + src\core\transport diff --git a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj index a7f06f0c9d..4ead6f8d98 100644 --- a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj @@ -160,7 +160,6 @@ - @@ -245,6 +244,7 @@ + @@ -264,8 +264,6 @@ - - @@ -460,6 +458,8 @@ + + diff --git a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters index cfb1d24c58..45ca1f7c33 100644 --- a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -19,9 +19,6 @@ src\core\channel - - src\core\channel - src\core\channel @@ -313,6 +310,9 @@ src\core\transport + + src\core\transport + src\core\transport @@ -371,9 +371,6 @@ src\core\channel - - src\core\channel - src\core\channel @@ -626,6 +623,9 @@ src\core\transport + + src\core\transport + src\core\transport -- cgit v1.2.3 From 98465035671778ea65891a28bc2c01776a6418cc Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 29 Jun 2015 14:36:42 -0700 Subject: Debugging --- src/core/channel/channel_stack.c | 4 +- src/core/channel/channel_stack.h | 3 +- src/core/channel/client_channel.c | 62 ++++++++++++++++------ src/core/channel/connected_channel.c | 2 +- src/core/channel/http_client_filter.c | 2 +- src/core/channel/http_server_filter.c | 2 +- src/core/channel/noop_filter.c | 2 +- src/core/client_config/resolver.c | 26 ++++++++- src/core/client_config/resolver.h | 25 +++++++-- src/core/client_config/resolvers/dns_resolver.c | 33 +++++------- .../client_config/resolvers/unix_resolver_posix.c | 23 ++------ src/core/client_config/subchannel.c | 13 ++++- src/core/client_config/subchannel.h | 2 + src/core/iomgr/iomgr.c | 11 ++++ src/core/security/client_auth_filter.c | 2 +- src/core/security/server_auth_filter.c | 2 +- src/core/surface/channel.c | 12 ++++- src/core/surface/channel_create.c | 4 +- src/core/surface/lame_client.c | 2 +- src/core/surface/server.c | 2 +- src/core/transport/connectivity_state.c | 4 ++ test/core/channel/channel_stack_test.c | 4 +- test/core/end2end/tests/request_with_flags.c | 7 ++- 23 files changed, 168 insertions(+), 81 deletions(-) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/channel_stack.c b/src/core/channel/channel_stack.c index ff1077ce4c..0810a61cd0 100644 --- a/src/core/channel/channel_stack.c +++ b/src/core/channel/channel_stack.c @@ -102,7 +102,7 @@ grpc_call_element *grpc_call_stack_element(grpc_call_stack *call_stack, } void grpc_channel_stack_init(const grpc_channel_filter **filters, - size_t filter_count, const grpc_channel_args *args, + size_t filter_count, grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *metadata_context, grpc_channel_stack *stack) { size_t call_size = @@ -122,7 +122,7 @@ void grpc_channel_stack_init(const grpc_channel_filter **filters, for (i = 0; i < filter_count; i++) { elems[i].filter = filters[i]; elems[i].channel_data = user_data; - elems[i].filter->init_channel_elem(&elems[i], args, metadata_context, + elems[i].filter->init_channel_elem(&elems[i], master, args, metadata_context, i == 0, i == (filter_count - 1)); user_data += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data); call_size += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_call_data); diff --git a/src/core/channel/channel_stack.h b/src/core/channel/channel_stack.h index 5ac2372f3a..6db98815df 100644 --- a/src/core/channel/channel_stack.h +++ b/src/core/channel/channel_stack.h @@ -97,6 +97,7 @@ typedef struct { useful for asserting correct configuration by upper layer code. The filter does not need to do any chaining */ void (*init_channel_elem)(grpc_channel_element *elem, + grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *metadata_context, int is_first, int is_last); @@ -151,7 +152,7 @@ size_t grpc_channel_stack_size(const grpc_channel_filter **filters, size_t filter_count); /* Initialize a channel stack given some filters */ void grpc_channel_stack_init(const grpc_channel_filter **filters, - size_t filter_count, const grpc_channel_args *args, + size_t filter_count, grpc_channel *master,const grpc_channel_args *args, grpc_mdctx *metadata_context, grpc_channel_stack *stack); /* Destroy a channel stack */ diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index e2f8debdfa..ee0d2cd9bd 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -38,6 +38,7 @@ #include "src/core/channel/channel_args.h" #include "src/core/channel/connected_channel.h" +#include "src/core/surface/channel.h" #include "src/core/iomgr/iomgr.h" #include "src/core/iomgr/pollset_set.h" #include "src/core/support/string.h" @@ -56,6 +57,8 @@ typedef struct { grpc_mdctx *mdctx; /** resolver for this channel */ grpc_resolver *resolver; + /** master channel */ + grpc_channel *master; /** mutex protecting client configuration, resolution state */ gpr_mu mu_config; @@ -321,10 +324,6 @@ static void cc_start_transport_stream_op(grpc_call_element *elem, perform_transport_stream_op(elem, op, 0); } -static void update_state_locked(channel_data *chand) { - gpr_log(GPR_ERROR, "update_state_locked not implemented"); -} - static void cc_on_config_changed(void *arg, int iomgr_success) { channel_data *chand = arg; grpc_lb_policy *lb_policy = NULL; @@ -350,31 +349,42 @@ static void cc_on_config_changed(void *arg, int iomgr_success) { } gpr_mu_unlock(&chand->mu_config); - while (wakeup_closures) { - grpc_iomgr_closure *next = wakeup_closures->next; - grpc_iomgr_add_callback(wakeup_closures); - wakeup_closures = next; - } - if (old_lb_policy) { GRPC_LB_POLICY_UNREF(old_lb_policy, "channel"); } - if (iomgr_success) { + gpr_mu_lock(&chand->mu_config); + if (iomgr_success && chand->resolver) { + grpc_resolver *resolver = chand->resolver; + GRPC_RESOLVER_REF(resolver, "channel-next"); + gpr_mu_unlock(&chand->mu_config); + GRPC_CHANNEL_INTERNAL_REF(chand->master, "resolver"); grpc_resolver_next(chand->resolver, &chand->incoming_configuration, &chand->on_config_changed); + GRPC_RESOLVER_UNREF(resolver, "channel-next"); } else { - gpr_mu_lock(&chand->mu_config); old_resolver = chand->resolver; chand->resolver = NULL; - update_state_locked(chand); + grpc_connectivity_state_set(&chand->state_tracker, GRPC_CHANNEL_FATAL_FAILURE); gpr_mu_unlock(&chand->mu_config); - grpc_resolver_unref(old_resolver); + if (old_resolver != NULL) { + grpc_resolver_shutdown(old_resolver); + GRPC_RESOLVER_UNREF(old_resolver, "channel"); + } + } + + while (wakeup_closures) { + grpc_iomgr_closure *next = wakeup_closures->next; + grpc_iomgr_add_callback(wakeup_closures); + wakeup_closures = next; } + + GRPC_CHANNEL_INTERNAL_UNREF(chand->master, "resolver"); } static void cc_start_transport_op(grpc_channel_element *elem, grpc_transport_op *op) { grpc_lb_policy *lb_policy = NULL; channel_data *chand = elem->channel_data; + grpc_resolver *destroy_resolver = NULL; grpc_iomgr_closure *on_consumed = op->on_consumed; op->on_consumed = NULL; @@ -388,6 +398,13 @@ static void cc_start_transport_op(grpc_channel_element *elem, grpc_transport_op op->connectivity_state = NULL; } + if (op->disconnect && chand->resolver != NULL) { + grpc_connectivity_state_set(&chand->state_tracker, GRPC_CHANNEL_FATAL_FAILURE); + destroy_resolver = chand->resolver; + chand->resolver = NULL; + op->disconnect = 0; + } + if (!is_empty(op, sizeof(*op))) { lb_policy = chand->lb_policy; if (lb_policy) { @@ -396,6 +413,11 @@ static void cc_start_transport_op(grpc_channel_element *elem, grpc_transport_op } gpr_mu_unlock(&chand->mu_config); + if (destroy_resolver) { + grpc_resolver_shutdown(destroy_resolver); + GRPC_RESOLVER_UNREF(destroy_resolver, "channel"); + } + if (lb_policy) { grpc_lb_policy_broadcast(lb_policy, op); GRPC_LB_POLICY_UNREF(lb_policy, "broadcast"); @@ -432,6 +454,7 @@ static void destroy_call_elem(grpc_call_element *elem) { remove it from the in-flight requests tracked by the child_entry we picked */ gpr_mu_lock(&calld->mu_state); + gpr_log(GPR_DEBUG, "call_elem destroy @ state %d", calld->state); switch (calld->state) { case CALL_ACTIVE: subchannel_call = calld->subchannel_call; @@ -452,7 +475,7 @@ static void destroy_call_elem(grpc_call_element *elem) { } /* Constructor for channel_data */ -static void init_channel_elem(grpc_channel_element *elem, +static void init_channel_elem(grpc_channel_element *elem,grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *metadata_context, int is_first, int is_last) { @@ -465,7 +488,10 @@ static void init_channel_elem(grpc_channel_element *elem, gpr_mu_init(&chand->mu_config); chand->mdctx = metadata_context; + chand->master = master; grpc_iomgr_closure_init(&chand->on_config_changed, cc_on_config_changed, chand); + + grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE); } /* Destructor for channel_data */ @@ -473,7 +499,8 @@ static void destroy_channel_elem(grpc_channel_element *elem) { channel_data *chand = elem->channel_data; if (chand->resolver != NULL) { - grpc_resolver_unref(chand->resolver); + grpc_resolver_shutdown(chand->resolver); + GRPC_RESOLVER_UNREF(chand->resolver, "channel"); } if (chand->lb_policy != NULL) { GRPC_LB_POLICY_UNREF(chand->lb_policy, "channel"); @@ -494,6 +521,7 @@ void grpc_client_channel_set_resolver(grpc_channel_stack *channel_stack, channel_data *chand = elem->channel_data; GPR_ASSERT(!chand->resolver); chand->resolver = resolver; - grpc_resolver_ref(resolver); + GRPC_CHANNEL_INTERNAL_REF(chand->master, "resolver"); + GRPC_RESOLVER_REF(resolver, "channel"); grpc_resolver_next(resolver, &chand->incoming_configuration, &chand->on_config_changed); } diff --git a/src/core/channel/connected_channel.c b/src/core/channel/connected_channel.c index 84caecb6b3..99c8a643f6 100644 --- a/src/core/channel/connected_channel.c +++ b/src/core/channel/connected_channel.c @@ -103,7 +103,7 @@ static void destroy_call_elem(grpc_call_element *elem) { } /* Constructor for channel_data */ -static void init_channel_elem(grpc_channel_element *elem, +static void init_channel_elem(grpc_channel_element *elem,grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *mdctx, int is_first, int is_last) { channel_data *cd = (channel_data *)elem->channel_data; diff --git a/src/core/channel/http_client_filter.c b/src/core/channel/http_client_filter.c index 5dec734c8c..3d1fc6a020 100644 --- a/src/core/channel/http_client_filter.c +++ b/src/core/channel/http_client_filter.c @@ -170,7 +170,7 @@ static const char *scheme_from_args(const grpc_channel_args *args) { } /* Constructor for channel_data */ -static void init_channel_elem(grpc_channel_element *elem, +static void init_channel_elem(grpc_channel_element *elem,grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *mdctx, int is_first, int is_last) { /* grab pointers to our data from the channel element */ diff --git a/src/core/channel/http_server_filter.c b/src/core/channel/http_server_filter.c index dac53e9bf1..3b1128bef9 100644 --- a/src/core/channel/http_server_filter.c +++ b/src/core/channel/http_server_filter.c @@ -229,7 +229,7 @@ static void init_call_elem(grpc_call_element *elem, static void destroy_call_elem(grpc_call_element *elem) {} /* Constructor for channel_data */ -static void init_channel_elem(grpc_channel_element *elem, +static void init_channel_elem(grpc_channel_element *elem,grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *mdctx, int is_first, int is_last) { /* grab pointers to our data from the channel element */ diff --git a/src/core/channel/noop_filter.c b/src/core/channel/noop_filter.c index 1478f04a3c..0d9c2e82a8 100644 --- a/src/core/channel/noop_filter.c +++ b/src/core/channel/noop_filter.c @@ -95,7 +95,7 @@ static void destroy_call_elem(grpc_call_element *elem) { } /* Constructor for channel_data */ -static void init_channel_elem(grpc_channel_element *elem, +static void init_channel_elem(grpc_channel_element *elem,grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *mdctx, int is_first, int is_last) { /* grab pointers to our data from the channel element */ diff --git a/src/core/client_config/resolver.c b/src/core/client_config/resolver.c index 11ba27e58d..bbc0ec4e81 100644 --- a/src/core/client_config/resolver.c +++ b/src/core/client_config/resolver.c @@ -33,12 +33,34 @@ #include "src/core/client_config/resolver.h" +void grpc_resolver_init(grpc_resolver *resolver, + const grpc_resolver_vtable *vtable) { + resolver->vtable = vtable; + gpr_ref_init(&resolver->refs, 1); +} + +#ifdef GRPC_RESOLVER_REFCOUNT_DEBUG +void grpc_resolver_ref(grpc_resolver *resolver, const char *file, int line, + const char *reason) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "RESOLVER:%p ref %d -> %d %s", + resolver, (int)resolver->refs.count, (int)resolver->refs.count + 1, reason); +#else void grpc_resolver_ref(grpc_resolver *resolver) { - resolver->vtable->ref(resolver); +#endif + gpr_ref(&resolver->refs); } +#ifdef GRPC_RESOLVER_REFCOUNT_DEBUG +void grpc_resolver_unref(grpc_resolver *resolver, const char *file, int line, + const char *reason) { + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "RESOLVER:%p unref %d -> %d %s", + resolver, (int)resolver->refs.count, (int)resolver->refs.count - 1, reason); +#else void grpc_resolver_unref(grpc_resolver *resolver) { - resolver->vtable->unref(resolver); +#endif + if (gpr_unref(&resolver->refs)) { + resolver->vtable->destroy(resolver); + } } void grpc_resolver_shutdown(grpc_resolver *resolver) { diff --git a/src/core/client_config/resolver.h b/src/core/client_config/resolver.h index 7776870c08..16b5964eb6 100644 --- a/src/core/client_config/resolver.h +++ b/src/core/client_config/resolver.h @@ -45,11 +45,11 @@ typedef struct grpc_resolver_vtable grpc_resolver_vtable; objects */ struct grpc_resolver { const grpc_resolver_vtable *vtable; + gpr_refcount refs; }; struct grpc_resolver_vtable { - void (*ref)(grpc_resolver *resolver); - void (*unref)(grpc_resolver *resolver); + void (*destroy)(grpc_resolver *resolver); void (*shutdown)(grpc_resolver *resolver); void (*channel_saw_error)(grpc_resolver *resolver, struct sockaddr *failing_address, @@ -58,8 +58,25 @@ struct grpc_resolver_vtable { grpc_iomgr_closure *on_complete); }; -void grpc_resolver_ref(grpc_resolver *resolver); -void grpc_resolver_unref(grpc_resolver *resolver); +#ifdef GRPC_RESOLVER_REFCOUNT_DEBUG +#define GRPC_RESOLVER_REF(p, r) \ + grpc_resolver_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_RESOLVER_UNREF(p, r) \ + grpc_resolver_unref((p), __FILE__, __LINE__, (r)) +void grpc_resolver_ref(grpc_resolver *policy, const char *file, int line, + const char *reason); +void grpc_resolver_unref(grpc_resolver *policy, const char *file, int line, + const char *reason); +#else +#define GRPC_RESOLVER_REF(p, r) grpc_resolver_ref((p)) +#define GRPC_RESOLVER_UNREF(p, r) grpc_resolver_unref((p)) +void grpc_resolver_ref(grpc_resolver *policy); +void grpc_resolver_unref(grpc_resolver *policy); +#endif + +void grpc_resolver_init(grpc_resolver *resolver, + const grpc_resolver_vtable *vtable); + void grpc_resolver_shutdown(grpc_resolver *resolver); /** Notification that the channel has seen an error on some address. diff --git a/src/core/client_config/resolvers/dns_resolver.c b/src/core/client_config/resolvers/dns_resolver.c index 8693bcf5eb..c64491ae51 100644 --- a/src/core/client_config/resolvers/dns_resolver.c +++ b/src/core/client_config/resolvers/dns_resolver.c @@ -73,13 +73,11 @@ typedef struct { grpc_client_config *resolved_config; } dns_resolver; -static void dns_destroy(dns_resolver *r); +static void dns_destroy(grpc_resolver *r); static void dns_start_resolving_locked(dns_resolver *r); static void dns_maybe_finish_next_locked(dns_resolver *r); -static void dns_ref(grpc_resolver *r); -static void dns_unref(grpc_resolver *r); static void dns_shutdown(grpc_resolver *r); static void dns_channel_saw_error(grpc_resolver *r, struct sockaddr *failing_address, @@ -88,26 +86,13 @@ static void dns_next(grpc_resolver *r, grpc_client_config **target_config, grpc_iomgr_closure *on_complete); static const grpc_resolver_vtable dns_resolver_vtable = { - dns_ref, dns_unref, dns_shutdown, dns_channel_saw_error, dns_next}; - -static void dns_ref(grpc_resolver *resolver) { - dns_resolver *r = (dns_resolver *)resolver; - gpr_ref(&r->refs); -} - -static void dns_unref(grpc_resolver *resolver) { - dns_resolver *r = (dns_resolver *)resolver; - if (gpr_unref(&r->refs)) { - dns_destroy(r); - } -} + dns_destroy, dns_shutdown, dns_channel_saw_error, dns_next}; static void dns_shutdown(grpc_resolver *resolver) { dns_resolver *r = (dns_resolver *)resolver; gpr_mu_lock(&r->mu); if (r->next_completion != NULL) { *r->target_config = NULL; - /* TODO(ctiller): add delayed callback */ grpc_iomgr_add_callback(r->next_completion); r->next_completion = NULL; } @@ -160,8 +145,12 @@ static void dns_on_resolved(void *arg, grpc_resolved_addresses *addresses) { lb_policy = r->lb_policy_factory(subchannels, addresses->naddrs); grpc_client_config_set_lb_policy(config, lb_policy); GRPC_LB_POLICY_UNREF(lb_policy, "construction"); + grpc_resolved_addresses_destroy(addresses); + gpr_free(subchannels); } gpr_mu_lock(&r->mu); + GPR_ASSERT(r->resolving); + r->resolving = 0; if (r->resolved_config) { grpc_client_config_unref(r->resolved_config); } @@ -170,11 +159,12 @@ static void dns_on_resolved(void *arg, grpc_resolved_addresses *addresses) { dns_maybe_finish_next_locked(r); gpr_mu_unlock(&r->mu); - dns_unref(&r->base); + GRPC_RESOLVER_UNREF(&r->base, "dns-resolving"); } static void dns_start_resolving_locked(dns_resolver *r) { - dns_ref(&r->base); + GRPC_RESOLVER_REF(&r->base, "dns-resolving"); + GPR_ASSERT(!r->resolving); r->resolving = 1; grpc_resolve_address(r->name, r->default_port, dns_on_resolved, r); } @@ -190,7 +180,8 @@ static void dns_maybe_finish_next_locked(dns_resolver *r) { } } -static void dns_destroy(dns_resolver *r) { +static void dns_destroy(grpc_resolver *gr) { + dns_resolver *r = (dns_resolver *)gr; gpr_mu_destroy(&r->mu); if (r->resolved_config) { grpc_client_config_unref(r->resolved_config); @@ -220,7 +211,7 @@ static grpc_resolver *dns_create( memset(r, 0, sizeof(*r)); gpr_ref_init(&r->refs, 1); gpr_mu_init(&r->mu); - r->base.vtable = &dns_resolver_vtable; + grpc_resolver_init(&r->base, &dns_resolver_vtable); r->name = gpr_strdup(path); r->default_port = gpr_strdup(default_port); r->subchannel_factory = subchannel_factory; diff --git a/src/core/client_config/resolvers/unix_resolver_posix.c b/src/core/client_config/resolvers/unix_resolver_posix.c index f7498548b1..7f2008685c 100644 --- a/src/core/client_config/resolvers/unix_resolver_posix.c +++ b/src/core/client_config/resolvers/unix_resolver_posix.c @@ -71,12 +71,10 @@ typedef struct { grpc_client_config **target_config; } unix_resolver; -static void unix_destroy(unix_resolver *r); +static void unix_destroy(grpc_resolver *r); static void unix_maybe_finish_next_locked(unix_resolver *r); -static void unix_ref(grpc_resolver *r); -static void unix_unref(grpc_resolver *r); static void unix_shutdown(grpc_resolver *r); static void unix_channel_saw_error(grpc_resolver *r, struct sockaddr *failing_address, @@ -85,19 +83,7 @@ static void unix_next(grpc_resolver *r, grpc_client_config **target_config, grpc_iomgr_closure *on_complete); static const grpc_resolver_vtable unix_resolver_vtable = { - unix_ref, unix_unref, unix_shutdown, unix_channel_saw_error, unix_next}; - -static void unix_ref(grpc_resolver *resolver) { - unix_resolver *r = (unix_resolver *)resolver; - gpr_ref(&r->refs); -} - -static void unix_unref(grpc_resolver *resolver) { - unix_resolver *r = (unix_resolver *)resolver; - if (gpr_unref(&r->refs)) { - unix_destroy(r); - } -} + unix_destroy, unix_shutdown, unix_channel_saw_error, unix_next}; static void unix_shutdown(grpc_resolver *resolver) { unix_resolver *r = (unix_resolver *)resolver; @@ -149,7 +135,8 @@ static void unix_maybe_finish_next_locked(unix_resolver *r) { } } -static void unix_destroy(unix_resolver *r) { +static void unix_destroy(grpc_resolver *gr) { + unix_resolver *r = (unix_resolver*)gr; gpr_mu_destroy(&r->mu); grpc_subchannel_factory_unref(r->subchannel_factory); gpr_free(r); @@ -171,7 +158,7 @@ static grpc_resolver *unix_create( memset(r, 0, sizeof(*r)); gpr_ref_init(&r->refs, 1); gpr_mu_init(&r->mu); - r->base.vtable = &unix_resolver_vtable; + grpc_resolver_init(&r->base, &unix_resolver_vtable); r->subchannel_factory = subchannel_factory; r->lb_policy_factory = lb_policy_factory; diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c index a0d21d99eb..6f4bf2ebe8 100644 --- a/src/core/client_config/subchannel.c +++ b/src/core/client_config/subchannel.c @@ -78,6 +78,8 @@ struct grpc_subchannel { size_t addr_len; /** metadata context */ grpc_mdctx *mdctx; + /** master channel */ + grpc_channel *master; /** set during connection */ grpc_connect_out_args connecting_result; @@ -217,6 +219,7 @@ grpc_subchannel *grpc_subchannel_create(grpc_connector *connector, c->addr_len = args->addr_len; c->args = grpc_channel_args_copy(args->args); c->mdctx = args->mdctx; + c->master = args->master; grpc_mdctx_ref(c->mdctx); grpc_pollset_set_init(&c->pollset_set); grpc_iomgr_closure_init(&c->connected, subchannel_connected, c); @@ -267,6 +270,7 @@ void grpc_subchannel_create_call(grpc_subchannel *c, w4c->initial_op = *initial_op; w4c->target = target; w4c->subchannel = c; + /* released when clearing w4c */ subchannel_ref_locked(c); grpc_iomgr_closure_init(&w4c->continuation, continue_creating_call, w4c); c->waiting = w4c; @@ -274,6 +278,7 @@ void grpc_subchannel_create_call(grpc_subchannel *c, if (!c->connecting) { c->connecting = 1; connectivity_state_changed_locked(c); + /* released by connection */ subchannel_ref_locked(c); gpr_mu_unlock(&c->mu); @@ -301,6 +306,7 @@ void grpc_subchannel_notify_on_state_change(grpc_subchannel *c, notify)) { do_connect = 1; c->connecting = 1; + /* released by connection */ subchannel_ref_locked(c); grpc_connectivity_state_set(&c->state_tracker, compute_connectivity_locked(c)); @@ -313,7 +319,8 @@ void grpc_subchannel_notify_on_state_change(grpc_subchannel *c, void grpc_subchannel_process_transport_op(grpc_subchannel *c, grpc_transport_op *op) { - abort(); /* not implemented */ + gpr_log(GPR_ERROR, "grpc_subchannel_process_transport_op not implemented"); + abort(); } static void on_state_changed(void *p, int iomgr_success) { @@ -357,6 +364,7 @@ static void on_state_changed(void *p, int iomgr_success) { break; case GRPC_CHANNEL_TRANSIENT_FAILURE: /* things are starting to go wrong, reconnect but don't deactivate */ + /* released by connection */ subchannel_ref_locked(c); do_connect = 1; c->connecting = 1; @@ -406,8 +414,9 @@ static void publish_transport(grpc_subchannel *c) { stk = (grpc_channel_stack *)(con + 1); con->refs = 0; con->subchannel = c; - grpc_channel_stack_init(filters, num_filters, c->args, c->mdctx, stk); + grpc_channel_stack_init(filters, num_filters, c->master, c->args, c->mdctx, stk); grpc_connected_channel_bind_transport(stk, c->connecting_result.transport); + gpr_free(c->connecting_result.filters); memset(&c->connecting_result, 0, sizeof(c->connecting_result)); /* initialize state watcher */ diff --git a/src/core/client_config/subchannel.h b/src/core/client_config/subchannel.h index b777e51d20..766258846a 100644 --- a/src/core/client_config/subchannel.h +++ b/src/core/client_config/subchannel.h @@ -90,6 +90,8 @@ struct grpc_subchannel_args { size_t addr_len; /** metadata context to use */ grpc_mdctx *mdctx; + /** master channel */ + grpc_channel *master; }; /** create a subchannel given a connector */ diff --git a/src/core/iomgr/iomgr.c b/src/core/iomgr/iomgr.c index 2765706de8..8fbddd73b0 100644 --- a/src/core/iomgr/iomgr.c +++ b/src/core/iomgr/iomgr.c @@ -201,10 +201,21 @@ void grpc_iomgr_closure_init(grpc_iomgr_closure *closure, grpc_iomgr_cb_func cb, closure->next = NULL; } +static void assert_not_scheduled_locked(grpc_iomgr_closure *closure) { +#ifndef NDEBUG + grpc_iomgr_closure *c; + + for (c = g_cbs_head; c; c = c->next) { + GPR_ASSERT(c != closure); + } +#endif +} + void grpc_iomgr_add_delayed_callback(grpc_iomgr_closure *closure, int success) { closure->success = success; GPR_ASSERT(closure->cb); gpr_mu_lock(&g_mu); + assert_not_scheduled_locked(closure); closure->next = NULL; if (!g_cbs_tail) { g_cbs_head = g_cbs_tail = closure; diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c index 2c05f73df5..0bd370e457 100644 --- a/src/core/security/client_auth_filter.c +++ b/src/core/security/client_auth_filter.c @@ -280,7 +280,7 @@ static void destroy_call_elem(grpc_call_element *elem) { } /* Constructor for channel_data */ -static void init_channel_elem(grpc_channel_element *elem, +static void init_channel_elem(grpc_channel_element *elem,grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *metadata_context, int is_first, int is_last) { diff --git a/src/core/security/server_auth_filter.c b/src/core/security/server_auth_filter.c index cf5ce4010e..a92b46c85f 100644 --- a/src/core/security/server_auth_filter.c +++ b/src/core/security/server_auth_filter.c @@ -88,7 +88,7 @@ static void destroy_call_elem(grpc_call_element *elem) { } /* Constructor for channel_data */ -static void init_channel_elem(grpc_channel_element *elem, +static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *mdctx, int is_first, int is_last) { grpc_security_connector *sc = grpc_find_security_connector_in_args(args); diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c index 4857912b4f..e85eaf2c05 100644 --- a/src/core/surface/channel.c +++ b/src/core/surface/channel.c @@ -109,8 +109,6 @@ grpc_channel *grpc_channel_create_from_filters( } channel->path_string = grpc_mdstr_from_string(mdctx, ":path"); 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; @@ -131,6 +129,9 @@ grpc_channel *grpc_channel_create_from_filters( } } + grpc_channel_stack_init(filters, num_filters, channel, args, channel->metadata_context, + CHANNEL_STACK_FROM_CHANNEL(channel)); + return channel; } @@ -237,6 +238,13 @@ void grpc_channel_internal_unref(grpc_channel *channel) { } void grpc_channel_destroy(grpc_channel *channel) { + grpc_transport_op op; + grpc_channel_element *elem; + memset(&op, 0, sizeof(op)); + op.disconnect = 1; + elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CHANNEL(channel), 0); + elem->filter->start_transport_op(elem, &op); + GRPC_CHANNEL_INTERNAL_UNREF(channel, "channel"); } diff --git a/src/core/surface/channel_create.c b/src/core/surface/channel_create.c index 494a44725a..0d756a131e 100644 --- a/src/core/surface/channel_create.c +++ b/src/core/surface/channel_create.c @@ -155,6 +155,7 @@ grpc_channel *grpc_channel_create(const char *target, f = gpr_malloc(sizeof(*f)); f->base.vtable = &subchannel_factory_vtable; gpr_ref_init(&f->refs, 1); + grpc_mdctx_ref(mdctx); f->mdctx = mdctx; resolver = grpc_resolver_create(target, &f->base); if (!resolver) { @@ -163,7 +164,8 @@ grpc_channel *grpc_channel_create(const char *target, channel = grpc_channel_create_from_filters(filters, n, args, mdctx, 1); grpc_client_channel_set_resolver(grpc_channel_get_channel_stack(channel), resolver); - grpc_resolver_unref(resolver); + GRPC_RESOLVER_UNREF(resolver, "create"); + grpc_subchannel_factory_unref(&f->base); return channel; } diff --git a/src/core/surface/lame_client.c b/src/core/surface/lame_client.c index 5235d3f7f4..c6ac679871 100644 --- a/src/core/surface/lame_client.c +++ b/src/core/surface/lame_client.c @@ -105,7 +105,7 @@ static void init_call_elem(grpc_call_element *elem, static void destroy_call_elem(grpc_call_element *elem) {} -static void init_channel_elem(grpc_channel_element *elem, +static void init_channel_elem(grpc_channel_element *elem,grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *mdctx, int is_first, int is_last) { channel_data *chand = elem->channel_data; diff --git a/src/core/surface/server.c b/src/core/surface/server.c index 6d06725bf3..f7d385c7af 100644 --- a/src/core/surface/server.c +++ b/src/core/surface/server.c @@ -709,7 +709,7 @@ static void destroy_call_elem(grpc_call_element *elem) { server_unref(chand->server); } -static void init_channel_elem(grpc_channel_element *elem, +static void init_channel_elem(grpc_channel_element *elem,grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *metadata_context, int is_first, int is_last) { diff --git a/src/core/transport/connectivity_state.c b/src/core/transport/connectivity_state.c index 5cbd67ef3c..8df08af32f 100644 --- a/src/core/transport/connectivity_state.c +++ b/src/core/transport/connectivity_state.c @@ -33,15 +33,18 @@ #include "src/core/transport/connectivity_state.h" #include +#include void grpc_connectivity_state_init(grpc_connectivity_state_tracker *tracker, grpc_connectivity_state init_state) { tracker->current_state = init_state; tracker->watchers = NULL; + /*gpr_log(GPR_DEBUG, "CS:%p:init:%d", tracker, init_state);*/ } void grpc_connectivity_state_destroy(grpc_connectivity_state_tracker *tracker) { grpc_connectivity_state_watcher *w; + /*gpr_log(GPR_DEBUG, "CS:%p:destroy", tracker);*/ while ((w = tracker->watchers)) { tracker->watchers = w->next; @@ -80,6 +83,7 @@ void grpc_connectivity_state_set(grpc_connectivity_state_tracker *tracker, grpc_connectivity_state state) { grpc_connectivity_state_watcher *new = NULL; grpc_connectivity_state_watcher *w; + /*gpr_log(GPR_DEBUG, "CS:%p:set:%d", tracker, state);*/ if (tracker->current_state == state) { return; } diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c index ba778c3775..55a15a1a54 100644 --- a/test/core/channel/channel_stack_test.c +++ b/test/core/channel/channel_stack_test.c @@ -39,7 +39,7 @@ #include #include "test/core/util/test_config.h" -static void channel_init_func(grpc_channel_element *elem, +static void channel_init_func(grpc_channel_element *elem,grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *metadata_context, int is_first, int is_last) { @@ -98,7 +98,7 @@ static void test_create_channel_stack(void) { chan_args.args = &arg; channel_stack = gpr_malloc(grpc_channel_stack_size(&filters, 1)); - grpc_channel_stack_init(&filters, 1, &chan_args, metadata_context, + grpc_channel_stack_init(&filters, 1, NULL, &chan_args, metadata_context, channel_stack); GPR_ASSERT(channel_stack->count == 1); channel_elem = grpc_channel_stack_element(channel_stack, 0); diff --git a/test/core/end2end/tests/request_with_flags.c b/test/core/end2end/tests/request_with_flags.c index fac0602328..0bfedca0ab 100644 --- a/test/core/end2end/tests/request_with_flags.c +++ b/test/core/end2end/tests/request_with_flags.c @@ -105,7 +105,7 @@ static void test_invoke_request_with_flags( gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world"); grpc_byte_buffer *request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1); - gpr_timespec deadline = five_seconds_time(); + gpr_timespec deadline = GRPC_TIMEOUT_MILLIS_TO_DEADLINE(10); grpc_end2end_test_fixture f = begin_test(config, "test_invoke_request_with_flags", NULL, NULL); cq_verifier *cqv = cq_verifier_create(f.cq); @@ -156,6 +156,11 @@ static void test_invoke_request_with_flags( expectation = call_start_batch_expected_result; GPR_ASSERT(expectation == grpc_call_start_batch(c, ops, op - ops, tag(1))); + if (expectation == GRPC_CALL_OK) { + cq_expect_completion(cqv, tag(1), 1); + cq_verify(cqv); + } + gpr_free(details); grpc_metadata_array_destroy(&initial_metadata_recv); grpc_metadata_array_destroy(&trailing_metadata_recv); -- cgit v1.2.3 From c396753a367677a4f2a111a850c2290dd27e2047 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 29 Jun 2015 14:59:38 -0700 Subject: Refcounting fixes --- src/core/channel/client_channel.c | 2 +- src/core/client_config/lb_policies/pick_first.c | 8 +-- src/core/client_config/subchannel.c | 77 ++++++++++++++++--------- src/core/client_config/subchannel.h | 24 ++++++-- 4 files changed, 76 insertions(+), 35 deletions(-) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index ee0d2cd9bd..d3d2f42ec1 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -459,7 +459,7 @@ static void destroy_call_elem(grpc_call_element *elem) { case CALL_ACTIVE: subchannel_call = calld->subchannel_call; gpr_mu_unlock(&calld->mu_state); - grpc_subchannel_call_unref(subchannel_call); + GRPC_SUBCHANNEL_CALL_UNREF(subchannel_call, "client_channel"); break; case CALL_CREATED: case CALL_CANCELLED: diff --git a/src/core/client_config/lb_policies/pick_first.c b/src/core/client_config/lb_policies/pick_first.c index c94408200b..a8e5b5cc4a 100644 --- a/src/core/client_config/lb_policies/pick_first.c +++ b/src/core/client_config/lb_policies/pick_first.c @@ -77,7 +77,7 @@ void pf_destroy(grpc_lb_policy *pol) { pick_first_lb_policy *p = (pick_first_lb_policy *)pol; size_t i; for (i = 0; i < p->num_subchannels; i++) { - grpc_subchannel_unref(p->subchannels[i]); + GRPC_SUBCHANNEL_UNREF(p->subchannels[i], "pick_first"); } gpr_free(p->subchannels); gpr_mu_destroy(&p->mu); @@ -180,7 +180,7 @@ loop: p->checking_connectivity = grpc_subchannel_check_connectivity( p->subchannels[p->checking_subchannel]); p->num_subchannels--; - grpc_subchannel_unref(p->subchannels[p->num_subchannels]); + GRPC_SUBCHANNEL_UNREF(p->subchannels[p->num_subchannels], "pick_first"); add_interested_parties_locked(p); if (p->num_subchannels == 0) { abort(); @@ -206,13 +206,13 @@ static void pf_broadcast(grpc_lb_policy *pol, grpc_transport_op *op) { subchannels = gpr_malloc(n * sizeof(*subchannels)); for (i = 0; i < n; i++) { subchannels[i] = p->subchannels[i]; - grpc_subchannel_ref(subchannels[i]); + GRPC_SUBCHANNEL_REF(subchannels[i], "pf_broadcast"); } gpr_mu_unlock(&p->mu); for (i = 0; i < n; i++) { grpc_subchannel_process_transport_op(subchannels[i], op); - grpc_subchannel_unref(subchannels[i]); + GRPC_SUBCHANNEL_UNREF(subchannels[i], "pf_broadcast"); } gpr_free(subchannels); } diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c index 6f4bf2ebe8..3d065761ab 100644 --- a/src/core/client_config/subchannel.c +++ b/src/core/client_config/subchannel.c @@ -123,13 +123,29 @@ static grpc_connectivity_state compute_connectivity_locked(grpc_subchannel *c); static gpr_timespec compute_connect_deadline(grpc_subchannel *c); static void subchannel_connected(void *subchannel, int iomgr_success); -static void subchannel_ref_locked(grpc_subchannel *c); -static int subchannel_unref_locked(grpc_subchannel *c) GRPC_MUST_USE_RESULT; -static void connection_ref_locked(connection *c); -static grpc_subchannel *connection_unref_locked(connection *c) +static void subchannel_ref_locked(grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +static int subchannel_unref_locked(grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) GRPC_MUST_USE_RESULT; +static void connection_ref_locked(connection *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +static grpc_subchannel *connection_unref_locked(connection *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) GRPC_MUST_USE_RESULT; static void subchannel_destroy(grpc_subchannel *c); +#ifdef GRPC_SUBCHANNEL_REFCOUNT_DEBUG +#define SUBCHANNEL_REF_LOCKED(p, r) subchannel_ref_locked((p), __FILE__, __LINE__, (r)) +#define SUBCHANNEL_UNREF_LOCKED(p, r) subchannel_unref_locked((p), __FILE__, __LINE__, (r)) +#define CONNECTION_REF_LOCKED(p, r) connection_ref_locked((p), __FILE__, __LINE__, (r)) +#define CONNECTION_UNREF_LOCKED(p, r) connection_unref_locked((p), __FILE__, __LINE__, (r)) +#define REF_PASS_ARGS , file, line, reason +#define REF_LOG(name, p) gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "%s: %p ref %d -> %d %s", (name), (p), (p)->refs, (p)->refs + 1, reason) +#define UNREF_LOG(name, p) gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "%s: %p unref %d -> %d %s", (name), (p), (p)->refs, (p)->refs - 1, reason) +#else +#define SUBCHANNEL_REF_LOCKED(p, r) subchannel_ref_locked((p)) +#define SUBCHANNEL_UNREF_LOCKED(p, r) subchannel_unref_locked((p)) +#define CONNECTION_REF_LOCKED(p, r) connection_ref_locked((p), __FILE__, __LINE__, (r)) +#define CONNECTION_UNREF_LOCKED(p, r) connection_unref_locked((p), __FILE__, __LINE__, (r)) +#define REF_PASS_ARGS +#endif + /* * connection implementation */ @@ -140,14 +156,16 @@ static void connection_destroy(connection *c) { gpr_free(c); } -static void connection_ref_locked(connection *c) { - subchannel_ref_locked(c->subchannel); +static void connection_ref_locked(connection *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + REF_LOG("CONNECTION", c); + subchannel_ref_locked(c->subchannel REF_PASS_ARGS); ++c->refs; } -static grpc_subchannel *connection_unref_locked(connection *c) { +static grpc_subchannel *connection_unref_locked(connection *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { grpc_subchannel *destroy = NULL; - if (subchannel_unref_locked(c->subchannel)) { + UNREF_LOG("CONNECTION", c); + if (subchannel_unref_locked(c->subchannel REF_PASS_ARGS)) { destroy = c->subchannel; } if (--c->refs == 0 && c->subchannel->active != c) { @@ -160,22 +178,26 @@ static grpc_subchannel *connection_unref_locked(connection *c) { * grpc_subchannel implementation */ -static void subchannel_ref_locked(grpc_subchannel *c) { ++c->refs; } +static void subchannel_ref_locked(grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + REF_LOG("SUBCHANNEL", c); + ++c->refs; +} -static int subchannel_unref_locked(grpc_subchannel *c) { +static int subchannel_unref_locked(grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + UNREF_LOG("SUBCHANNEL", c); return --c->refs == 0; } -void grpc_subchannel_ref(grpc_subchannel *c) { +void grpc_subchannel_ref(grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { gpr_mu_lock(&c->mu); - subchannel_ref_locked(c); + subchannel_ref_locked(c REF_PASS_ARGS); gpr_mu_unlock(&c->mu); } -void grpc_subchannel_unref(grpc_subchannel *c) { +void grpc_subchannel_unref(grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { int destroy; gpr_mu_lock(&c->mu); - destroy = subchannel_unref_locked(c); + destroy = subchannel_unref_locked(c REF_PASS_ARGS); gpr_mu_unlock(&c->mu); if (destroy) subchannel_destroy(c); } @@ -190,6 +212,7 @@ static void subchannel_destroy(grpc_subchannel *c) { grpc_mdctx_unref(c->mdctx); grpc_pollset_set_destroy(&c->pollset_set); grpc_connectivity_state_destroy(&c->state_tracker); + grpc_connector_unref(c->connector); gpr_free(c); } @@ -246,7 +269,7 @@ static void continue_creating_call(void *arg, int iomgr_success) { waiting_for_connect *w4c = arg; grpc_subchannel_create_call(w4c->subchannel, &w4c->initial_op, w4c->target, w4c->notify); - grpc_subchannel_unref(w4c->subchannel); + GRPC_SUBCHANNEL_UNREF(w4c->subchannel, "waiting_for_connect"); gpr_free(w4c); } @@ -258,7 +281,7 @@ void grpc_subchannel_create_call(grpc_subchannel *c, gpr_mu_lock(&c->mu); if (c->active != NULL) { con = c->active; - connection_ref_locked(con); + CONNECTION_REF_LOCKED(con, "call"); gpr_mu_unlock(&c->mu); *target = create_call(con, initial_op); @@ -271,7 +294,7 @@ void grpc_subchannel_create_call(grpc_subchannel *c, w4c->target = target; w4c->subchannel = c; /* released when clearing w4c */ - subchannel_ref_locked(c); + SUBCHANNEL_REF_LOCKED(c, "waiting_for_connect"); grpc_iomgr_closure_init(&w4c->continuation, continue_creating_call, w4c); c->waiting = w4c; grpc_subchannel_add_interested_party(c, initial_op->bind_pollset); @@ -279,7 +302,7 @@ void grpc_subchannel_create_call(grpc_subchannel *c, c->connecting = 1; connectivity_state_changed_locked(c); /* released by connection */ - subchannel_ref_locked(c); + SUBCHANNEL_REF_LOCKED(c, "connecting"); gpr_mu_unlock(&c->mu); start_connect(c); @@ -307,7 +330,7 @@ void grpc_subchannel_notify_on_state_change(grpc_subchannel *c, do_connect = 1; c->connecting = 1; /* released by connection */ - subchannel_ref_locked(c); + SUBCHANNEL_REF_LOCKED(c, "connecting"); grpc_connectivity_state_set(&c->state_tracker, compute_connectivity_locked(c)); } @@ -365,7 +388,7 @@ static void on_state_changed(void *p, int iomgr_success) { case GRPC_CHANNEL_TRANSIENT_FAILURE: /* things are starting to go wrong, reconnect but don't deactivate */ /* released by connection */ - subchannel_ref_locked(c); + SUBCHANNEL_REF_LOCKED(c, "connection"); do_connect = 1; c->connecting = 1; break; @@ -374,7 +397,7 @@ static void on_state_changed(void *p, int iomgr_success) { done: grpc_connectivity_state_set(&c->state_tracker, compute_connectivity_locked(c)); - destroy = subchannel_unref_locked(c); + destroy = SUBCHANNEL_UNREF_LOCKED(c, "connection"); gpr_free(sw); gpr_mu_unlock(mu); if (do_connect) { @@ -468,7 +491,7 @@ static void subchannel_connected(void *arg, int iomgr_success) { } else { int destroy; gpr_mu_lock(&c->mu); - destroy = subchannel_unref_locked(c); + destroy = SUBCHANNEL_UNREF_LOCKED(c, "connection"); gpr_mu_unlock(&c->mu); if (destroy) subchannel_destroy(c); /* TODO(ctiller): retry after sleeping */ @@ -499,18 +522,20 @@ static void connectivity_state_changed_locked(grpc_subchannel *c) { * grpc_subchannel_call implementation */ -void grpc_subchannel_call_ref(grpc_subchannel_call *c) { gpr_ref(&c->refs); } +void grpc_subchannel_call_ref(grpc_subchannel_call *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_ref(&c->refs); +} -void grpc_subchannel_call_unref(grpc_subchannel_call *c) { +void grpc_subchannel_call_unref(grpc_subchannel_call *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { if (gpr_unref(&c->refs)) { gpr_mu *mu = &c->connection->subchannel->mu; grpc_subchannel *destroy; grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(c)); gpr_mu_lock(mu); - destroy = connection_unref_locked(c->connection); + destroy = CONNECTION_UNREF_LOCKED(c->connection, "call"); gpr_mu_unlock(mu); gpr_free(c); - if (destroy) { + if (destroy != NULL) { subchannel_destroy(destroy); } } diff --git a/src/core/client_config/subchannel.h b/src/core/client_config/subchannel.h index 766258846a..97a64c488d 100644 --- a/src/core/client_config/subchannel.h +++ b/src/core/client_config/subchannel.h @@ -43,10 +43,26 @@ typedef struct grpc_subchannel grpc_subchannel; typedef struct grpc_subchannel_call grpc_subchannel_call; typedef struct grpc_subchannel_args grpc_subchannel_args; -void grpc_subchannel_ref(grpc_subchannel *channel); -void grpc_subchannel_unref(grpc_subchannel *channel); -void grpc_subchannel_call_ref(grpc_subchannel_call *call); -void grpc_subchannel_call_unref(grpc_subchannel_call *call); +#define GRPC_SUBCHANNEL_REFCOUNT_DEBUG + +#ifdef GRPC_SUBCHANNEL_REFCOUNT_DEBUG +#define GRPC_SUBCHANNEL_REF(p, r) grpc_subchannel_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_UNREF(p, r) grpc_subchannel_unref((p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_CALL_REF(p, r) grpc_subchannel_call_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_CALL_UNREF(p, r) grpc_subchannel_call_unref((p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_REF_EXTRA_ARGS , const char *file, int line, const char *reason +#else +#define GRPC_SUBCHANNEL_REF(p, r) grpc_subchannel_ref((p)) +#define GRPC_SUBCHANNEL_UNREF(p, r) grpc_subchannel_unref((p)) +#define GRPC_SUBCHANNEL_CALL_REF(p, r) grpc_subchannel_call_ref((p)) +#define GRPC_SUBCHANNEL_CALL_UNREF(p, r) grpc_subchannel_call_unref((p)) +#define GRPC_SUBCHANNEL_REF_EXTRA_ARGS +#endif + +void grpc_subchannel_ref(grpc_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +void grpc_subchannel_unref(grpc_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +void grpc_subchannel_call_ref(grpc_subchannel_call *call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +void grpc_subchannel_call_unref(grpc_subchannel_call *call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); /** construct a call (possibly asynchronously) */ void grpc_subchannel_create_call(grpc_subchannel *subchannel, -- cgit v1.2.3 From b6fbf1d986331c8959e60a172fe922d9f864b03f Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 29 Jun 2015 15:25:49 -0700 Subject: Fix refcounting --- src/core/channel/client_channel.c | 1 - src/core/client_config/subchannel.c | 50 +++++++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 6 deletions(-) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index d3d2f42ec1..6b60dc07cf 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -402,7 +402,6 @@ static void cc_start_transport_op(grpc_channel_element *elem, grpc_transport_op grpc_connectivity_state_set(&chand->state_tracker, GRPC_CHANNEL_FATAL_FAILURE); destroy_resolver = chand->resolver; chand->resolver = NULL; - op->disconnect = 0; } if (!is_empty(op, sizeof(*op))) { diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c index 3d065761ab..eadeb0ef55 100644 --- a/src/core/client_config/subchannel.c +++ b/src/core/client_config/subchannel.c @@ -80,6 +80,8 @@ struct grpc_subchannel { grpc_mdctx *mdctx; /** master channel */ grpc_channel *master; + /** have we seen a disconnection? */ + int disconnected; /** set during connection */ grpc_connect_out_args connecting_result; @@ -152,6 +154,7 @@ static void subchannel_destroy(grpc_subchannel *c); static void connection_destroy(connection *c) { GPR_ASSERT(c->refs == 0); + gpr_log(GPR_DEBUG, "CONNECTION_DESTROY %p", c); grpc_channel_stack_destroy(CHANNEL_STACK_FROM_CONNECTION(c)); gpr_free(c); } @@ -342,8 +345,32 @@ void grpc_subchannel_notify_on_state_change(grpc_subchannel *c, void grpc_subchannel_process_transport_op(grpc_subchannel *c, grpc_transport_op *op) { - gpr_log(GPR_ERROR, "grpc_subchannel_process_transport_op not implemented"); - abort(); + connection *con = NULL; + grpc_subchannel *destroy; + gpr_mu_lock(&c->mu); + if (op->disconnect) { + c->disconnected = 1; + grpc_connectivity_state_set(&c->state_tracker, + compute_connectivity_locked(c)); + } + if (c->active != NULL) { + con = c->active; + CONNECTION_REF_LOCKED(con, "transport-op"); + } + gpr_mu_unlock(&c->mu); + + if (con != NULL) { + grpc_channel_stack *channel_stack = CHANNEL_STACK_FROM_CONNECTION(con); + grpc_channel_element *top_elem = grpc_channel_stack_element(channel_stack, 0); + top_elem->filter->start_transport_op(top_elem, op); + + gpr_mu_lock(&c->mu); + destroy = CONNECTION_UNREF_LOCKED(con, "transport-op"); + gpr_mu_unlock(&c->mu); + if (destroy) { + subchannel_destroy(destroy); + } + } } static void on_state_changed(void *p, int iomgr_success) { @@ -388,7 +415,7 @@ static void on_state_changed(void *p, int iomgr_success) { case GRPC_CHANNEL_TRANSIENT_FAILURE: /* things are starting to go wrong, reconnect but don't deactivate */ /* released by connection */ - SUBCHANNEL_REF_LOCKED(c, "connection"); + SUBCHANNEL_REF_LOCKED(c, "connecting"); do_connect = 1; c->connecting = 1; break; @@ -397,7 +424,7 @@ static void on_state_changed(void *p, int iomgr_success) { done: grpc_connectivity_state_set(&c->state_tracker, compute_connectivity_locked(c)); - destroy = SUBCHANNEL_UNREF_LOCKED(c, "connection"); + destroy = SUBCHANNEL_UNREF_LOCKED(c, "state_watcher"); gpr_free(sw); gpr_mu_unlock(mu); if (do_connect) { @@ -450,6 +477,14 @@ static void publish_transport(grpc_subchannel *c) { gpr_mu_lock(&c->mu); + if (c->disconnected) { + gpr_mu_unlock(&c->mu); + gpr_free(sw); + gpr_free(filters); + grpc_channel_stack_destroy(stk); + return; + } + /* publish */ if (c->active != NULL && c->active->refs == 0) { destroy_connection = c->active; @@ -464,6 +499,8 @@ static void publish_transport(grpc_subchannel *c) { memset(&op, 0, sizeof(op)); op.connectivity_state = &sw->connectivity_state; op.on_connectivity_state_change = &sw->closure; + SUBCHANNEL_REF_LOCKED(c, "state_watcher"); + GPR_ASSERT(!SUBCHANNEL_UNREF_LOCKED(c, "connecting")); elem = grpc_channel_stack_element(CHANNEL_STACK_FROM_CONNECTION(c->active), 0); elem->filter->start_transport_op(elem, &op); @@ -491,7 +528,7 @@ static void subchannel_connected(void *arg, int iomgr_success) { } else { int destroy; gpr_mu_lock(&c->mu); - destroy = SUBCHANNEL_UNREF_LOCKED(c, "connection"); + destroy = SUBCHANNEL_UNREF_LOCKED(c, "connecting"); gpr_mu_unlock(&c->mu); if (destroy) subchannel_destroy(c); /* TODO(ctiller): retry after sleeping */ @@ -504,6 +541,9 @@ static gpr_timespec compute_connect_deadline(grpc_subchannel *c) { } static grpc_connectivity_state compute_connectivity_locked(grpc_subchannel *c) { + if (c->disconnected) { + return GRPC_CHANNEL_FATAL_FAILURE; + } if (c->connecting) { return GRPC_CHANNEL_CONNECTING; } -- cgit v1.2.3 From abf36389d446bc6ac2f5a067d9ae8174123b7686 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 29 Jun 2015 16:13:27 -0700 Subject: Make SSL work --- src/core/channel/client_channel.c | 7 +++---- src/core/client_config/resolvers/dns_resolver.c | 4 +++- src/core/client_config/subchannel.c | 21 +++++++++------------ src/core/client_config/subchannel.h | 2 +- 4 files changed, 16 insertions(+), 18 deletions(-) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index 6b60dc07cf..d465a970b9 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -198,7 +198,7 @@ static void started_call(void *arg, int iomgr_success) { static void picked_target(void *arg, int iomgr_success) { call_data *calld = arg; - grpc_transport_stream_op op; + grpc_pollset *pollset; if (calld->picked_channel == NULL) { /* treat this like a cancellation */ @@ -212,11 +212,10 @@ static void picked_target(void *arg, int iomgr_success) { } else { GPR_ASSERT(calld->state == CALL_WAITING_FOR_PICK); calld->state = CALL_WAITING_FOR_CALL; - op = calld->waiting_op; - memset(&calld->waiting_op, 0, sizeof(calld->waiting_op)); + pollset = calld->waiting_op.bind_pollset; gpr_mu_unlock(&calld->mu_state); grpc_iomgr_closure_init(&calld->async_setup_task, started_call, calld); - grpc_subchannel_create_call(calld->picked_channel, &op, + grpc_subchannel_create_call(calld->picked_channel, pollset, &calld->subchannel_call, &calld->async_setup_task); } diff --git a/src/core/client_config/resolvers/dns_resolver.c b/src/core/client_config/resolvers/dns_resolver.c index c64491ae51..ac401bc4d3 100644 --- a/src/core/client_config/resolvers/dns_resolver.c +++ b/src/core/client_config/resolvers/dns_resolver.c @@ -173,7 +173,9 @@ static void dns_maybe_finish_next_locked(dns_resolver *r) { if (r->next_completion != NULL && r->resolved_version != r->published_version) { *r->target_config = r->resolved_config; - grpc_client_config_ref(r->resolved_config); + if (r->resolved_config) { + grpc_client_config_ref(r->resolved_config); + } grpc_iomgr_add_callback(r->next_completion); r->next_completion = NULL; r->published_version = r->resolved_version; diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c index eadeb0ef55..b5e991a594 100644 --- a/src/core/client_config/subchannel.c +++ b/src/core/client_config/subchannel.c @@ -59,7 +59,7 @@ typedef struct { typedef struct waiting_for_connect { struct waiting_for_connect *next; grpc_iomgr_closure *notify; - grpc_transport_stream_op initial_op; + grpc_pollset *pollset; grpc_subchannel_call **target; grpc_subchannel *subchannel; grpc_iomgr_closure continuation; @@ -118,8 +118,7 @@ struct grpc_subchannel_call { #define SUBCHANNEL_CALL_TO_CALL_STACK(call) ((grpc_call_stack *)((call) + 1)) #define CHANNEL_STACK_FROM_CONNECTION(con) ((grpc_channel_stack *)((con) + 1)) -static grpc_subchannel_call *create_call(connection *con, - grpc_transport_stream_op *initial_op); +static grpc_subchannel_call *create_call(connection *con); static void connectivity_state_changed_locked(grpc_subchannel *c); static grpc_connectivity_state compute_connectivity_locked(grpc_subchannel *c); static gpr_timespec compute_connect_deadline(grpc_subchannel *c); @@ -270,14 +269,13 @@ static void start_connect(grpc_subchannel *c) { static void continue_creating_call(void *arg, int iomgr_success) { waiting_for_connect *w4c = arg; - grpc_subchannel_create_call(w4c->subchannel, &w4c->initial_op, w4c->target, + grpc_subchannel_create_call(w4c->subchannel, w4c->pollset, w4c->target, w4c->notify); GRPC_SUBCHANNEL_UNREF(w4c->subchannel, "waiting_for_connect"); gpr_free(w4c); } -void grpc_subchannel_create_call(grpc_subchannel *c, - grpc_transport_stream_op *initial_op, +void grpc_subchannel_create_call(grpc_subchannel *c, grpc_pollset *pollset, grpc_subchannel_call **target, grpc_iomgr_closure *notify) { connection *con; @@ -287,20 +285,20 @@ void grpc_subchannel_create_call(grpc_subchannel *c, CONNECTION_REF_LOCKED(con, "call"); gpr_mu_unlock(&c->mu); - *target = create_call(con, initial_op); + *target = create_call(con); notify->cb(notify->cb_arg, 1); } else { waiting_for_connect *w4c = gpr_malloc(sizeof(*w4c)); w4c->next = c->waiting; w4c->notify = notify; - w4c->initial_op = *initial_op; + w4c->pollset = pollset; w4c->target = target; w4c->subchannel = c; /* released when clearing w4c */ SUBCHANNEL_REF_LOCKED(c, "waiting_for_connect"); grpc_iomgr_closure_init(&w4c->continuation, continue_creating_call, w4c); c->waiting = w4c; - grpc_subchannel_add_interested_party(c, initial_op->bind_pollset); + grpc_subchannel_add_interested_party(c, pollset); if (!c->connecting) { c->connecting = 1; connectivity_state_changed_locked(c); @@ -588,14 +586,13 @@ void grpc_subchannel_call_process_op(grpc_subchannel_call *call, top_elem->filter->start_transport_stream_op(top_elem, op); } -grpc_subchannel_call *create_call(connection *con, - grpc_transport_stream_op *initial_op) { +grpc_subchannel_call *create_call(connection *con) { grpc_channel_stack *chanstk = CHANNEL_STACK_FROM_CONNECTION(con); grpc_subchannel_call *call = gpr_malloc(sizeof(grpc_subchannel_call) + chanstk->call_stack_size); grpc_call_stack *callstk = SUBCHANNEL_CALL_TO_CALL_STACK(call); call->connection = con; gpr_ref_init(&call->refs, 1); - grpc_call_stack_init(chanstk, NULL, initial_op, callstk); + grpc_call_stack_init(chanstk, NULL, NULL, callstk); return call; } diff --git a/src/core/client_config/subchannel.h b/src/core/client_config/subchannel.h index 97a64c488d..03bd4f63e0 100644 --- a/src/core/client_config/subchannel.h +++ b/src/core/client_config/subchannel.h @@ -66,7 +66,7 @@ void grpc_subchannel_call_unref(grpc_subchannel_call *call GRPC_SUBCHANNEL_REF_E /** construct a call (possibly asynchronously) */ void grpc_subchannel_create_call(grpc_subchannel *subchannel, - grpc_transport_stream_op *initial_op, + grpc_pollset *pollset, grpc_subchannel_call **target, grpc_iomgr_closure *notify); -- cgit v1.2.3 From 49924e0e62d29499874e93f5dcf5976edcf610f4 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 29 Jun 2015 22:42:33 -0700 Subject: Better handling of cancellation, uri parse errors, and disconnection --- src/core/channel/client_channel.c | 4 ++++ src/core/client_config/resolver_registry.c | 7 ++++-- src/core/client_config/subchannel.c | 14 +----------- src/core/client_config/uri_parser.c | 36 ++++++++++++++++-------------- src/core/client_config/uri_parser.h | 2 +- src/core/surface/server.c | 23 ++++++++++++++++--- src/core/transport/chttp2_transport.c | 4 ++-- test/core/client_config/uri_parser_test.c | 4 ++-- 8 files changed, 54 insertions(+), 40 deletions(-) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index d465a970b9..e62a262bab 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -242,6 +242,7 @@ static void perform_transport_stream_op(grpc_call_element *elem, grpc_transport_ channel_data *chand = elem->channel_data; grpc_subchannel_call *subchannel_call; grpc_lb_policy *lb_policy; + grpc_transport_stream_op op2; GPR_ASSERT(elem->filter == &grpc_client_channel_filter); GRPC_CALL_LOG_OP(GPR_INFO, elem, op); @@ -263,8 +264,11 @@ static void perform_transport_stream_op(grpc_call_element *elem, grpc_transport_ if (!continuation) { if (op->cancel_with_status != GRPC_STATUS_OK) { calld->state = CALL_CANCELLED; + op2 = calld->waiting_op; + memset(&calld->waiting_op, 0, sizeof(calld->waiting_op)); gpr_mu_unlock(&calld->mu_state); handle_op_after_cancellation(elem, op); + handle_op_after_cancellation(elem, &op2); } else { GPR_ASSERT((calld->waiting_op.send_ops == NULL) != (op->send_ops == NULL)); diff --git a/src/core/client_config/resolver_registry.c b/src/core/client_config/resolver_registry.c index abdb5f9377..16be2da994 100644 --- a/src/core/client_config/resolver_registry.c +++ b/src/core/client_config/resolver_registry.c @@ -100,18 +100,21 @@ grpc_resolver *grpc_resolver_create( grpc_resolver_factory *factory = NULL; grpc_resolver *resolver; - uri = grpc_uri_parse(name); + uri = grpc_uri_parse(name, 1); factory = lookup_factory(uri); if (factory == NULL && g_default_resolver_scheme != NULL) { grpc_uri_destroy(uri); gpr_asprintf(&tmp, "%s%s", g_default_resolver_scheme, name); - uri = grpc_uri_parse(tmp); + uri = grpc_uri_parse(tmp, 1); factory = lookup_factory(uri); if (factory == NULL) { + grpc_uri_destroy(grpc_uri_parse(name, 0)); + grpc_uri_destroy(grpc_uri_parse(tmp, 0)); gpr_log(GPR_ERROR, "don't know how to resolve '%s' or '%s'", name, tmp); } gpr_free(tmp); } else if (factory == NULL) { + grpc_uri_destroy(grpc_uri_parse(name, 0)); gpr_log(GPR_ERROR, "don't know how to resolve '%s'", name); } resolver = diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c index c8c562f29d..cae6db0110 100644 --- a/src/core/client_config/subchannel.c +++ b/src/core/client_config/subchannel.c @@ -409,7 +409,6 @@ static void on_state_changed(void *p, int iomgr_success) { grpc_transport_op op; grpc_channel_element *elem; connection *destroy_connection = NULL; - int do_connect = 0; gpr_mu_lock(mu); @@ -436,6 +435,7 @@ static void on_state_changed(void *p, int iomgr_success) { gpr_mu_unlock(mu); return; case GRPC_CHANNEL_FATAL_FAILURE: + case GRPC_CHANNEL_TRANSIENT_FAILURE: /* things have gone wrong, deactivate and enter idle */ if (sw->subchannel->active->refs == 0) { destroy_connection = sw->subchannel->active; @@ -444,15 +444,6 @@ static void on_state_changed(void *p, int iomgr_success) { grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE); break; - case GRPC_CHANNEL_TRANSIENT_FAILURE: - /* things are starting to go wrong, reconnect but don't deactivate */ - /* released by connection */ - SUBCHANNEL_REF_LOCKED(c, "connecting"); - grpc_connectivity_state_set(&c->state_tracker, - GRPC_CHANNEL_TRANSIENT_FAILURE); - do_connect = 1; - c->connecting = 1; - break; } done: @@ -460,9 +451,6 @@ done: destroy = SUBCHANNEL_UNREF_LOCKED(c, "state_watcher"); gpr_free(sw); gpr_mu_unlock(mu); - if (do_connect) { - start_connect(c); - } if (destroy) { subchannel_destroy(c); } diff --git a/src/core/client_config/uri_parser.c b/src/core/client_config/uri_parser.c index 43b5b47f55..c5faab5eba 100644 --- a/src/core/client_config/uri_parser.c +++ b/src/core/client_config/uri_parser.c @@ -39,20 +39,22 @@ #include #include -static grpc_uri *bad_uri(const char *uri_text, int pos, const char *section) { +static grpc_uri *bad_uri(const char *uri_text, int pos, const char *section, int suppress_errors) { char *line_prefix; int pfx_len; - gpr_asprintf(&line_prefix, "bad uri.%s: '", section); - pfx_len = strlen(line_prefix) + pos; - gpr_log(GPR_ERROR, "%s%s'", line_prefix, uri_text); - gpr_free(line_prefix); + if (!suppress_errors) { + gpr_asprintf(&line_prefix, "bad uri.%s: '", section); + pfx_len = strlen(line_prefix) + pos; + gpr_log(GPR_ERROR, "%s%s'", line_prefix, uri_text); + gpr_free(line_prefix); - line_prefix = gpr_malloc(pfx_len + 1); - memset(line_prefix, ' ', pfx_len); - line_prefix[pfx_len] = 0; - gpr_log(GPR_ERROR, "%s^ here", line_prefix); - gpr_free(line_prefix); + line_prefix = gpr_malloc(pfx_len + 1); + memset(line_prefix, ' ', pfx_len); + line_prefix[pfx_len] = 0; + gpr_log(GPR_ERROR, "%s^ here", line_prefix); + gpr_free(line_prefix); + } return NULL; } @@ -64,7 +66,7 @@ static char *copy_fragment(const char *src, int begin, int end) { return out; } -grpc_uri *grpc_uri_parse(const char *uri_text) { +grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors) { grpc_uri *uri; int scheme_begin = 0; int scheme_end = -1; @@ -90,7 +92,7 @@ grpc_uri *grpc_uri_parse(const char *uri_text) { break; } if (scheme_end == -1) { - return bad_uri(uri_text, i, "scheme"); + return bad_uri(uri_text, i, "scheme", suppress_errors); } if (uri_text[scheme_end + 1] == '/' && uri_text[scheme_end + 2] == '/') { @@ -100,17 +102,17 @@ grpc_uri *grpc_uri_parse(const char *uri_text) { authority_end = i; } if (uri_text[i] == '?') { - return bad_uri(uri_text, i, "query_not_supported"); + return bad_uri(uri_text, i, "query_not_supported", suppress_errors); } if (uri_text[i] == '#') { - return bad_uri(uri_text, i, "fragment_not_supported"); + return bad_uri(uri_text, i, "fragment_not_supported", suppress_errors); } } if (authority_end == -1 && uri_text[i] == 0) { authority_end = i; } if (authority_end == -1) { - return bad_uri(uri_text, i, "authority"); + return bad_uri(uri_text, i, "authority", suppress_errors); } /* TODO(ctiller): parse the authority correctly */ path_begin = authority_end; @@ -120,10 +122,10 @@ grpc_uri *grpc_uri_parse(const char *uri_text) { for (i = path_begin; uri_text[i] != 0; i++) { if (uri_text[i] == '?') { - return bad_uri(uri_text, i, "query_not_supported"); + return bad_uri(uri_text, i, "query_not_supported", suppress_errors); } if (uri_text[i] == '#') { - return bad_uri(uri_text, i, "fragment_not_supported"); + return bad_uri(uri_text, i, "fragment_not_supported", suppress_errors); } } path_end = i; diff --git a/src/core/client_config/uri_parser.h b/src/core/client_config/uri_parser.h index b6821f9621..ce4e6aecb0 100644 --- a/src/core/client_config/uri_parser.h +++ b/src/core/client_config/uri_parser.h @@ -41,7 +41,7 @@ typedef struct { } grpc_uri; /** parse a uri, return NULL on failure */ -grpc_uri *grpc_uri_parse(const char *uri_text); +grpc_uri *grpc_uri_parse(const char *uri_text, int suppress_errors); /** destroy a uri */ void grpc_uri_destroy(grpc_uri *uri); diff --git a/src/core/surface/server.c b/src/core/surface/server.c index 383c3d921d..703eeaf2bd 100644 --- a/src/core/surface/server.c +++ b/src/core/surface/server.c @@ -204,7 +204,9 @@ struct call_data { typedef struct { grpc_channel **channels; + grpc_channel **disconnects; size_t num_channels; + size_t num_disconnects; } channel_broadcaster; #define SERVER_FROM_CALL_ELEM(elem) \ @@ -223,18 +225,28 @@ static void maybe_finish_shutdown(grpc_server *server); static void channel_broadcaster_init(grpc_server *s, channel_broadcaster *cb) { channel_data *c; size_t count = 0; + size_t dc_count = 0; for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) { count ++; + if (c->num_calls == 0) { + dc_count ++; + } } cb->num_channels = count; + cb->num_disconnects = dc_count; cb->channels = gpr_malloc(sizeof(*cb->channels) * cb->num_channels); + cb->disconnects = gpr_malloc(sizeof(*cb->channels) * cb->num_disconnects); count = 0; + dc_count = 0; for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) { - cb->channels[count] = c->channel; + cb->channels[count++] = c->channel; GRPC_CHANNEL_INTERNAL_REF(c->channel, "broadcast"); - count ++; + if (c->num_calls == 0) { + cb->disconnects[dc_count++] = c->channel; + GRPC_CHANNEL_INTERNAL_REF(c->channel, "broadcast-disconnect"); + } } } @@ -274,10 +286,15 @@ static void channel_broadcaster_shutdown(channel_broadcaster *cb, int send_goawa size_t i; for (i = 0; i < cb->num_channels; i++) { - send_shutdown(cb->channels[i], send_goaway, send_disconnect); + send_shutdown(cb->channels[i], 1, 0); GRPC_CHANNEL_INTERNAL_UNREF(cb->channels[i], "broadcast"); } + for (i = 0; i < cb->num_disconnects; i++) { + send_shutdown(cb->disconnects[i], 0, 1); + GRPC_CHANNEL_INTERNAL_UNREF(cb->channels[i], "broadcast-disconnect"); + } gpr_free(cb->channels); + gpr_free(cb->disconnects); } /* call list */ diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c index 08a767f1d5..e32071e692 100644 --- a/src/core/transport/chttp2_transport.c +++ b/src/core/transport/chttp2_transport.c @@ -553,8 +553,7 @@ static void maybe_start_some_streams( transport_global->next_stream_id += 2; if (transport_global->next_stream_id >= MAX_CLIENT_STREAM_ID) { - connectivity_state_set(transport_global, - GRPC_CHANNEL_TRANSIENT_FAILURE); + connectivity_state_set(transport_global, GRPC_CHANNEL_TRANSIENT_FAILURE); } stream_global->outgoing_window = @@ -940,6 +939,7 @@ static void schedule_closure_for_connectivity(void *a, grpc_iomgr_closure *closu } static void connectivity_state_set(grpc_chttp2_transport_global *transport_global, grpc_connectivity_state state) { + GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_DEBUG, "set connectivity_state=%d", state)); grpc_connectivity_state_set_with_scheduler( &TRANSPORT_FROM_GLOBAL(transport_global)->channel_callback.state_tracker, state, diff --git a/test/core/client_config/uri_parser_test.c b/test/core/client_config/uri_parser_test.c index 26566d0924..287a9d1add 100644 --- a/test/core/client_config/uri_parser_test.c +++ b/test/core/client_config/uri_parser_test.c @@ -41,7 +41,7 @@ static void test_succeeds(const char *uri_text, const char *scheme, const char *authority, const char *path) { - grpc_uri *uri = grpc_uri_parse(uri_text); + grpc_uri *uri = grpc_uri_parse(uri_text, 0); GPR_ASSERT(uri); GPR_ASSERT(0 == strcmp(scheme, uri->scheme)); GPR_ASSERT(0 == strcmp(authority, uri->authority)); @@ -50,7 +50,7 @@ static void test_succeeds(const char *uri_text, const char *scheme, } static void test_fails(const char *uri_text) { - GPR_ASSERT(NULL == grpc_uri_parse(uri_text)); + GPR_ASSERT(NULL == grpc_uri_parse(uri_text, 0)); } int main(int argc, char **argv) { -- cgit v1.2.3 From bb32ba32ce5f0606b6e9f3d5ea092b4c89e2ef6e Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 30 Jun 2015 09:31:48 -0700 Subject: Fix use-after-free --- src/core/channel/client_channel.c | 48 +++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 14 deletions(-) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index e62a262bab..2b6f162072 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -237,6 +237,32 @@ static void pick_target(grpc_lb_policy *lb_policy, call_data *calld) { initial_metadata, &calld->picked_channel, &calld->async_setup_task); } +static void merge_into_waiting_op(grpc_call_element *elem, grpc_transport_stream_op *new_op) { + call_data *calld = elem->call_data; + grpc_transport_stream_op *waiting_op = &calld->waiting_op; + GPR_ASSERT((waiting_op->send_ops == NULL) != + (new_op->send_ops == NULL)); + GPR_ASSERT((waiting_op->recv_ops == NULL) != + (new_op->recv_ops == NULL)); + if (new_op->send_ops != NULL) { + waiting_op->send_ops = new_op->send_ops; + waiting_op->is_last_send = new_op->is_last_send; + waiting_op->on_done_send = new_op->on_done_send; + } + if (new_op->recv_ops != NULL) { + waiting_op->recv_ops = new_op->recv_ops; + waiting_op->recv_state = new_op->recv_state; + waiting_op->on_done_recv = new_op->on_done_recv; + } + if (waiting_op->on_consumed == NULL) { + waiting_op->on_consumed = new_op->on_consumed; + new_op->on_consumed = NULL; + } + if (new_op->cancel_with_status != GRPC_STATUS_OK) { + waiting_op->cancel_with_status = new_op->cancel_with_status; + } +} + static void perform_transport_stream_op(grpc_call_element *elem, grpc_transport_stream_op *op, int continuation) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; @@ -266,24 +292,18 @@ static void perform_transport_stream_op(grpc_call_element *elem, grpc_transport_ calld->state = CALL_CANCELLED; op2 = calld->waiting_op; memset(&calld->waiting_op, 0, sizeof(calld->waiting_op)); + if (op->on_consumed) { + calld->waiting_op.on_consumed = op->on_consumed; + op->on_consumed = NULL; + } else if (op2.on_consumed) { + calld->waiting_op.on_consumed = op2.on_consumed; + op2.on_consumed = NULL; + } gpr_mu_unlock(&calld->mu_state); handle_op_after_cancellation(elem, op); handle_op_after_cancellation(elem, &op2); } else { - GPR_ASSERT((calld->waiting_op.send_ops == NULL) != - (op->send_ops == NULL)); - GPR_ASSERT((calld->waiting_op.recv_ops == NULL) != - (op->recv_ops == NULL)); - if (op->send_ops != NULL) { - calld->waiting_op.send_ops = op->send_ops; - calld->waiting_op.is_last_send = op->is_last_send; - calld->waiting_op.on_done_send = op->on_done_send; - } - if (op->recv_ops != NULL) { - calld->waiting_op.recv_ops = op->recv_ops; - calld->waiting_op.recv_state = op->recv_state; - calld->waiting_op.on_done_recv = op->on_done_recv; - } + merge_into_waiting_op(elem, op); gpr_mu_unlock(&calld->mu_state); if (op->on_consumed != NULL) { op->on_consumed->cb(op->on_consumed->cb_arg, 0); -- cgit v1.2.3 From 6fa9148d51a5b4a9b6fb8502191b2aac87e0d57b Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 30 Jun 2015 10:05:03 -0700 Subject: Spam cleanup --- src/core/channel/client_channel.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index 2b6f162072..cb36fdc029 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -476,7 +476,6 @@ static void destroy_call_elem(grpc_call_element *elem) { remove it from the in-flight requests tracked by the child_entry we picked */ gpr_mu_lock(&calld->mu_state); - gpr_log(GPR_DEBUG, "call_elem destroy @ state %d", calld->state); switch (calld->state) { case CALL_ACTIVE: subchannel_call = calld->subchannel_call; -- cgit v1.2.3 From 079a11bb9b253e91c89e625950ea09879d2d6f8e Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 30 Jun 2015 10:07:15 -0700 Subject: clang-format affected files --- include/grpc/grpc.h | 4 +- src/core/channel/census_filter.c | 24 ++++++-- src/core/channel/channel_args.c | 4 +- src/core/channel/channel_args.h | 9 +-- src/core/channel/channel_stack.c | 8 ++- src/core/channel/channel_stack.h | 8 +-- src/core/channel/client_channel.c | 67 ++++++++++++++-------- src/core/channel/client_channel.h | 2 +- src/core/channel/connected_channel.c | 2 +- src/core/channel/connected_channel.h | 2 +- src/core/channel/http_client_filter.c | 2 +- src/core/channel/http_server_filter.c | 2 +- src/core/channel/noop_filter.c | 2 +- src/core/client_config/resolver.c | 12 ++-- src/core/client_config/resolver.h | 9 ++- .../client_config/resolvers/unix_resolver_posix.c | 2 +- src/core/client_config/subchannel.c | 58 ++++++++++++------- src/core/client_config/subchannel.h | 27 ++++++--- src/core/client_config/uri_parser.c | 3 +- src/core/iomgr/fd_posix.c | 3 +- src/core/security/client_auth_filter.c | 4 +- src/core/security/server_auth_filter.c | 9 ++- src/core/security/server_secure_chttp2.c | 12 ++-- src/core/surface/call.c | 17 +++--- src/core/surface/channel.c | 4 +- src/core/surface/channel_create.c | 29 ++++++---- src/core/surface/lame_client.c | 2 +- src/core/surface/secure_channel_create.c | 29 ++++++---- src/core/surface/server.c | 23 ++++---- src/core/transport/chttp2_transport.c | 58 ++++++++++--------- src/core/transport/connectivity_state.c | 6 +- src/core/transport/connectivity_state.h | 3 +- src/core/transport/transport.c | 5 +- src/core/transport/transport.h | 11 ++-- src/core/transport/transport_impl.h | 2 +- test/core/bad_client/bad_client.c | 11 ++-- test/core/channel/channel_stack_test.c | 7 ++- test/core/end2end/fixtures/chttp2_socket_pair.c | 24 ++++---- .../chttp2_socket_pair_one_byte_at_a_time.c | 24 ++++---- .../fixtures/chttp2_socket_pair_with_grpc_trace.c | 24 ++++---- test/core/end2end/multiple_server_queues_test.c | 2 +- test/core/iomgr/fd_conservation_posix_test.c | 12 ++-- 42 files changed, 325 insertions(+), 243 deletions(-) (limited to 'src/core/channel/client_channel.c') diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index 147343049b..782923d599 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -441,7 +441,7 @@ void grpc_channel_destroy(grpc_channel *channel); has been made. */ /* Called by clients to cancel an RPC on the server. - Can be called multiple times, from any thread. + Can be called multiple times, from any thread. THREAD-SAFETY grpc_call_cancel and grpc_call_cancel_with_status are thread-safe, and can be called at any point before grpc_call_destroy is called.*/ @@ -457,7 +457,7 @@ grpc_call_error grpc_call_cancel_with_status(grpc_call *call, grpc_status_code status, const char *description); -/* Destroy a call. +/* Destroy a call. THREAD SAFETY: grpc_call_destroy is thread-compatible */ void grpc_call_destroy(grpc_call *call); diff --git a/src/core/channel/census_filter.c b/src/core/channel/census_filter.c index ea0bece587..83b7682848 100644 --- a/src/core/channel/census_filter.c +++ b/src/core/channel/census_filter.c @@ -202,11 +202,23 @@ static void destroy_channel_elem(grpc_channel_element* elem) { } const grpc_channel_filter grpc_client_census_filter = { - client_start_transport_op, channel_op, sizeof(call_data), - client_init_call_elem, client_destroy_call_elem, sizeof(channel_data), - init_channel_elem, destroy_channel_elem, "census-client"}; + client_start_transport_op, + channel_op, + sizeof(call_data), + client_init_call_elem, + client_destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + "census-client"}; const grpc_channel_filter grpc_server_census_filter = { - server_start_transport_op, channel_op, sizeof(call_data), - server_init_call_elem, server_destroy_call_elem, sizeof(channel_data), - init_channel_elem, destroy_channel_elem, "census-server"}; + server_start_transport_op, + channel_op, + sizeof(call_data), + server_init_call_elem, + server_destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + "census-server"}; diff --git a/src/core/channel/channel_args.c b/src/core/channel/channel_args.c index 371da4210e..140f8bd656 100644 --- a/src/core/channel/channel_args.c +++ b/src/core/channel/channel_args.c @@ -139,8 +139,8 @@ grpc_compression_level grpc_channel_args_get_compression_level( return GRPC_COMPRESS_LEVEL_NONE; } -void grpc_channel_args_set_compression_level( - grpc_channel_args **a, grpc_compression_level level) { +void grpc_channel_args_set_compression_level(grpc_channel_args **a, + grpc_compression_level level) { grpc_arg tmp; tmp.type = GRPC_ARG_INTEGER; tmp.key = GRPC_COMPRESSION_LEVEL_ARG; diff --git a/src/core/channel/channel_args.h b/src/core/channel/channel_args.h index 27ad57b3e8..17849b7e59 100644 --- a/src/core/channel/channel_args.h +++ b/src/core/channel/channel_args.h @@ -47,7 +47,8 @@ grpc_channel_args *grpc_channel_args_copy_and_add(const grpc_channel_args *src, size_t num_to_add); /** Copy args from a then args from b into a new channel args */ -grpc_channel_args *grpc_channel_args_merge(const grpc_channel_args *a, const grpc_channel_args *b); +grpc_channel_args *grpc_channel_args_merge(const grpc_channel_args *a, + const grpc_channel_args *b); /** Destroy arguments created by grpc_channel_args_copy */ void grpc_channel_args_destroy(grpc_channel_args *a); @@ -62,7 +63,7 @@ grpc_compression_level grpc_channel_args_get_compression_level( /** Sets the compression level in \a a to \a level. Setting it to * GRPC_COMPRESS_LEVEL_NONE disables compression for the channel. */ -void grpc_channel_args_set_compression_level( - grpc_channel_args **a, grpc_compression_level level); +void grpc_channel_args_set_compression_level(grpc_channel_args **a, + grpc_compression_level level); -#endif /* GRPC_INTERNAL_CORE_CHANNEL_CHANNEL_ARGS_H */ +#endif /* GRPC_INTERNAL_CORE_CHANNEL_CHANNEL_ARGS_H */ diff --git a/src/core/channel/channel_stack.c b/src/core/channel/channel_stack.c index 0810a61cd0..e38dcb58b7 100644 --- a/src/core/channel/channel_stack.c +++ b/src/core/channel/channel_stack.c @@ -102,7 +102,8 @@ grpc_call_element *grpc_call_stack_element(grpc_call_stack *call_stack, } void grpc_channel_stack_init(const grpc_channel_filter **filters, - size_t filter_count, grpc_channel *master, const grpc_channel_args *args, + size_t filter_count, grpc_channel *master, + const grpc_channel_args *args, grpc_mdctx *metadata_context, grpc_channel_stack *stack) { size_t call_size = @@ -122,8 +123,9 @@ void grpc_channel_stack_init(const grpc_channel_filter **filters, for (i = 0; i < filter_count; i++) { elems[i].filter = filters[i]; elems[i].channel_data = user_data; - elems[i].filter->init_channel_elem(&elems[i], master, args, metadata_context, - i == 0, i == (filter_count - 1)); + elems[i].filter->init_channel_elem(&elems[i], master, args, + metadata_context, i == 0, + i == (filter_count - 1)); user_data += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data); call_size += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_call_data); } diff --git a/src/core/channel/channel_stack.h b/src/core/channel/channel_stack.h index 6db98815df..785be8925b 100644 --- a/src/core/channel/channel_stack.h +++ b/src/core/channel/channel_stack.h @@ -65,7 +65,7 @@ typedef struct { /* Called to eg. send/receive data on a call. See grpc_call_next_op on how to call the next element in the stack */ void (*start_transport_stream_op)(grpc_call_element *elem, - grpc_transport_stream_op *op); + grpc_transport_stream_op *op); /* Called to handle channel level operations - e.g. new calls, or transport closure. See grpc_channel_next_op on how to call the next element in the stack */ @@ -96,8 +96,7 @@ typedef struct { is_first, is_last designate this elements position in the stack, and are useful for asserting correct configuration by upper layer code. The filter does not need to do any chaining */ - void (*init_channel_elem)(grpc_channel_element *elem, - grpc_channel *master, + void (*init_channel_elem)(grpc_channel_element *elem, grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *metadata_context, int is_first, int is_last); @@ -152,7 +151,8 @@ size_t grpc_channel_stack_size(const grpc_channel_filter **filters, size_t filter_count); /* Initialize a channel stack given some filters */ void grpc_channel_stack_init(const grpc_channel_filter **filters, - size_t filter_count, grpc_channel *master,const grpc_channel_args *args, + size_t filter_count, grpc_channel *master, + const grpc_channel_args *args, grpc_mdctx *metadata_context, grpc_channel_stack *stack); /* Destroy a channel stack */ diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index cb36fdc029..6815ec8718 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -138,7 +138,9 @@ typedef struct { grpc_call_element *elem; } waiting_call; -static void perform_transport_stream_op(grpc_call_element *elem, grpc_transport_stream_op *op, int continuation); +static void perform_transport_stream_op(grpc_call_element *elem, + grpc_transport_stream_op *op, + int continuation); static void continue_with_pick(void *arg, int iomgr_success) { waiting_call *wc = arg; @@ -147,7 +149,8 @@ static void continue_with_pick(void *arg, int iomgr_success) { gpr_free(wc); } -static void add_to_lb_policy_wait_queue_locked_state_config(grpc_call_element *elem) { +static void add_to_lb_policy_wait_queue_locked_state_config( + grpc_call_element *elem) { channel_data *chand = elem->channel_data; waiting_call *wc = gpr_malloc(sizeof(*wc)); grpc_iomgr_closure_init(&wc->closure, continue_with_pick, wc); @@ -182,7 +185,8 @@ static void started_call(void *arg, int iomgr_success) { calld->state = CALL_ACTIVE; gpr_mu_unlock(&calld->mu_state); if (have_waiting) { - grpc_subchannel_call_process_op(calld->subchannel_call, &calld->waiting_op); + grpc_subchannel_call_process_op(calld->subchannel_call, + &calld->waiting_op); } } else { calld->state = CALL_CANCELLED; @@ -233,17 +237,16 @@ static void pick_target(grpc_lb_policy *lb_policy, call_data *calld) { initial_metadata = &op->send_ops->ops[0].data.metadata; grpc_iomgr_closure_init(&calld->async_setup_task, picked_target, calld); - grpc_lb_policy_pick(lb_policy, op->bind_pollset, - initial_metadata, &calld->picked_channel, &calld->async_setup_task); + grpc_lb_policy_pick(lb_policy, op->bind_pollset, initial_metadata, + &calld->picked_channel, &calld->async_setup_task); } -static void merge_into_waiting_op(grpc_call_element *elem, grpc_transport_stream_op *new_op) { +static void merge_into_waiting_op(grpc_call_element *elem, + grpc_transport_stream_op *new_op) { call_data *calld = elem->call_data; grpc_transport_stream_op *waiting_op = &calld->waiting_op; - GPR_ASSERT((waiting_op->send_ops == NULL) != - (new_op->send_ops == NULL)); - GPR_ASSERT((waiting_op->recv_ops == NULL) != - (new_op->recv_ops == NULL)); + GPR_ASSERT((waiting_op->send_ops == NULL) != (new_op->send_ops == NULL)); + GPR_ASSERT((waiting_op->recv_ops == NULL) != (new_op->recv_ops == NULL)); if (new_op->send_ops != NULL) { waiting_op->send_ops = new_op->send_ops; waiting_op->is_last_send = new_op->is_last_send; @@ -263,7 +266,9 @@ static void merge_into_waiting_op(grpc_call_element *elem, grpc_transport_stream } } -static void perform_transport_stream_op(grpc_call_element *elem, grpc_transport_stream_op *op, int continuation) { +static void perform_transport_stream_op(grpc_call_element *elem, + grpc_transport_stream_op *op, + int continuation) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; grpc_subchannel_call *subchannel_call; @@ -311,7 +316,7 @@ static void perform_transport_stream_op(grpc_call_element *elem, grpc_transport_ } break; } - /* fall through */ + /* fall through */ case CALL_CREATED: if (op->cancel_with_status != GRPC_STATUS_OK) { calld->state = CALL_CANCELLED; @@ -343,7 +348,7 @@ static void perform_transport_stream_op(grpc_call_element *elem, grpc_transport_ } static void cc_start_transport_stream_op(grpc_call_element *elem, - grpc_transport_stream_op *op) { + grpc_transport_stream_op *op) { perform_transport_stream_op(elem, op, 0); } @@ -382,12 +387,14 @@ static void cc_on_config_changed(void *arg, int iomgr_success) { GRPC_RESOLVER_REF(resolver, "channel-next"); gpr_mu_unlock(&chand->mu_config); GRPC_CHANNEL_INTERNAL_REF(chand->master, "resolver"); - grpc_resolver_next(chand->resolver, &chand->incoming_configuration, &chand->on_config_changed); + grpc_resolver_next(chand->resolver, &chand->incoming_configuration, + &chand->on_config_changed); GRPC_RESOLVER_UNREF(resolver, "channel-next"); } else { old_resolver = chand->resolver; chand->resolver = NULL; - grpc_connectivity_state_set(&chand->state_tracker, GRPC_CHANNEL_FATAL_FAILURE); + grpc_connectivity_state_set(&chand->state_tracker, + GRPC_CHANNEL_FATAL_FAILURE); gpr_mu_unlock(&chand->mu_config); if (old_resolver != NULL) { grpc_resolver_shutdown(old_resolver); @@ -404,7 +411,8 @@ static void cc_on_config_changed(void *arg, int iomgr_success) { GRPC_CHANNEL_INTERNAL_UNREF(chand->master, "resolver"); } -static void cc_start_transport_op(grpc_channel_element *elem, grpc_transport_op *op) { +static void cc_start_transport_op(grpc_channel_element *elem, + grpc_transport_op *op) { grpc_lb_policy *lb_policy = NULL; channel_data *chand = elem->channel_data; grpc_resolver *destroy_resolver = NULL; @@ -416,13 +424,16 @@ static void cc_start_transport_op(grpc_channel_element *elem, grpc_transport_op gpr_mu_lock(&chand->mu_config); if (op->on_connectivity_state_change != NULL) { - grpc_connectivity_state_notify_on_state_change(&chand->state_tracker, op->connectivity_state, op->on_connectivity_state_change); + grpc_connectivity_state_notify_on_state_change( + &chand->state_tracker, op->connectivity_state, + op->on_connectivity_state_change); op->on_connectivity_state_change = NULL; op->connectivity_state = NULL; } if (op->disconnect && chand->resolver != NULL) { - grpc_connectivity_state_set(&chand->state_tracker, GRPC_CHANNEL_FATAL_FAILURE); + grpc_connectivity_state_set(&chand->state_tracker, + GRPC_CHANNEL_FATAL_FAILURE); destroy_resolver = chand->resolver; chand->resolver = NULL; } @@ -496,7 +507,7 @@ static void destroy_call_elem(grpc_call_element *elem) { } /* Constructor for channel_data */ -static void init_channel_elem(grpc_channel_element *elem,grpc_channel *master, +static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *metadata_context, int is_first, int is_last) { @@ -510,7 +521,8 @@ static void init_channel_elem(grpc_channel_element *elem,grpc_channel *master, gpr_mu_init(&chand->mu_config); chand->mdctx = metadata_context; chand->master = master; - grpc_iomgr_closure_init(&chand->on_config_changed, cc_on_config_changed, chand); + grpc_iomgr_closure_init(&chand->on_config_changed, cc_on_config_changed, + chand); grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE); } @@ -530,9 +542,15 @@ static void destroy_channel_elem(grpc_channel_element *elem) { } const grpc_channel_filter grpc_client_channel_filter = { - cc_start_transport_stream_op, cc_start_transport_op, sizeof(call_data), - init_call_elem, destroy_call_elem, sizeof(channel_data), - init_channel_elem, destroy_channel_elem, "client-channel", + cc_start_transport_stream_op, + cc_start_transport_op, + sizeof(call_data), + init_call_elem, + destroy_call_elem, + sizeof(channel_data), + init_channel_elem, + destroy_channel_elem, + "client-channel", }; void grpc_client_channel_set_resolver(grpc_channel_stack *channel_stack, @@ -544,5 +562,6 @@ void grpc_client_channel_set_resolver(grpc_channel_stack *channel_stack, chand->resolver = resolver; GRPC_CHANNEL_INTERNAL_REF(chand->master, "resolver"); GRPC_RESOLVER_REF(resolver, "channel"); - grpc_resolver_next(resolver, &chand->incoming_configuration, &chand->on_config_changed); + grpc_resolver_next(resolver, &chand->incoming_configuration, + &chand->on_config_changed); } diff --git a/src/core/channel/client_channel.h b/src/core/channel/client_channel.h index 5ab64b9c46..fd2be46145 100644 --- a/src/core/channel/client_channel.h +++ b/src/core/channel/client_channel.h @@ -52,4 +52,4 @@ extern const grpc_channel_filter grpc_client_channel_filter; void grpc_client_channel_set_resolver(grpc_channel_stack *channel_stack, grpc_resolver *resolver); -#endif /* GRPC_INTERNAL_CORE_CHANNEL_CLIENT_CHANNEL_H */ +#endif /* GRPC_INTERNAL_CORE_CHANNEL_CLIENT_CHANNEL_H */ diff --git a/src/core/channel/connected_channel.c b/src/core/channel/connected_channel.c index 99c8a643f6..34d07de519 100644 --- a/src/core/channel/connected_channel.c +++ b/src/core/channel/connected_channel.c @@ -103,7 +103,7 @@ static void destroy_call_elem(grpc_call_element *elem) { } /* Constructor for channel_data */ -static void init_channel_elem(grpc_channel_element *elem,grpc_channel *master, +static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *mdctx, int is_first, int is_last) { channel_data *cd = (channel_data *)elem->channel_data; diff --git a/src/core/channel/connected_channel.h b/src/core/channel/connected_channel.h index d1e2c195cb..b615b0d350 100644 --- a/src/core/channel/connected_channel.h +++ b/src/core/channel/connected_channel.h @@ -46,4 +46,4 @@ extern const grpc_channel_filter grpc_connected_channel_filter; void grpc_connected_channel_bind_transport(grpc_channel_stack *channel_stack, grpc_transport *transport); -#endif /* GRPC_INTERNAL_CORE_CHANNEL_CONNECTED_CHANNEL_H */ +#endif /* GRPC_INTERNAL_CORE_CHANNEL_CONNECTED_CHANNEL_H */ diff --git a/src/core/channel/http_client_filter.c b/src/core/channel/http_client_filter.c index 3d1fc6a020..581eb13f58 100644 --- a/src/core/channel/http_client_filter.c +++ b/src/core/channel/http_client_filter.c @@ -170,7 +170,7 @@ static const char *scheme_from_args(const grpc_channel_args *args) { } /* Constructor for channel_data */ -static void init_channel_elem(grpc_channel_element *elem,grpc_channel *master, +static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *mdctx, int is_first, int is_last) { /* grab pointers to our data from the channel element */ diff --git a/src/core/channel/http_server_filter.c b/src/core/channel/http_server_filter.c index 3b1128bef9..db0bf590c6 100644 --- a/src/core/channel/http_server_filter.c +++ b/src/core/channel/http_server_filter.c @@ -229,7 +229,7 @@ static void init_call_elem(grpc_call_element *elem, static void destroy_call_elem(grpc_call_element *elem) {} /* Constructor for channel_data */ -static void init_channel_elem(grpc_channel_element *elem,grpc_channel *master, +static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *mdctx, int is_first, int is_last) { /* grab pointers to our data from the channel element */ diff --git a/src/core/channel/noop_filter.c b/src/core/channel/noop_filter.c index 0d9c2e82a8..5117723617 100644 --- a/src/core/channel/noop_filter.c +++ b/src/core/channel/noop_filter.c @@ -95,7 +95,7 @@ static void destroy_call_elem(grpc_call_element *elem) { } /* Constructor for channel_data */ -static void init_channel_elem(grpc_channel_element *elem,grpc_channel *master, +static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *mdctx, int is_first, int is_last) { /* grab pointers to our data from the channel element */ diff --git a/src/core/client_config/resolver.c b/src/core/client_config/resolver.c index bbc0ec4e81..91e42bb684 100644 --- a/src/core/client_config/resolver.c +++ b/src/core/client_config/resolver.c @@ -34,16 +34,17 @@ #include "src/core/client_config/resolver.h" void grpc_resolver_init(grpc_resolver *resolver, - const grpc_resolver_vtable *vtable) { + const grpc_resolver_vtable *vtable) { resolver->vtable = vtable; gpr_ref_init(&resolver->refs, 1); } #ifdef GRPC_RESOLVER_REFCOUNT_DEBUG void grpc_resolver_ref(grpc_resolver *resolver, const char *file, int line, - const char *reason) { + const char *reason) { gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "RESOLVER:%p ref %d -> %d %s", - resolver, (int)resolver->refs.count, (int)resolver->refs.count + 1, reason); + resolver, (int)resolver->refs.count, (int)resolver->refs.count + 1, + reason); #else void grpc_resolver_ref(grpc_resolver *resolver) { #endif @@ -52,9 +53,10 @@ void grpc_resolver_ref(grpc_resolver *resolver) { #ifdef GRPC_RESOLVER_REFCOUNT_DEBUG void grpc_resolver_unref(grpc_resolver *resolver, const char *file, int line, - const char *reason) { + const char *reason) { gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "RESOLVER:%p unref %d -> %d %s", - resolver, (int)resolver->refs.count, (int)resolver->refs.count - 1, reason); + resolver, (int)resolver->refs.count, (int)resolver->refs.count - 1, + reason); #else void grpc_resolver_unref(grpc_resolver *resolver) { #endif diff --git a/src/core/client_config/resolver.h b/src/core/client_config/resolver.h index 16b5964eb6..8ad87d789b 100644 --- a/src/core/client_config/resolver.h +++ b/src/core/client_config/resolver.h @@ -59,14 +59,13 @@ struct grpc_resolver_vtable { }; #ifdef GRPC_RESOLVER_REFCOUNT_DEBUG -#define GRPC_RESOLVER_REF(p, r) \ - grpc_resolver_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_RESOLVER_REF(p, r) grpc_resolver_ref((p), __FILE__, __LINE__, (r)) #define GRPC_RESOLVER_UNREF(p, r) \ grpc_resolver_unref((p), __FILE__, __LINE__, (r)) void grpc_resolver_ref(grpc_resolver *policy, const char *file, int line, - const char *reason); + const char *reason); void grpc_resolver_unref(grpc_resolver *policy, const char *file, int line, - const char *reason); + const char *reason); #else #define GRPC_RESOLVER_REF(p, r) grpc_resolver_ref((p)) #define GRPC_RESOLVER_UNREF(p, r) grpc_resolver_unref((p)) @@ -75,7 +74,7 @@ void grpc_resolver_unref(grpc_resolver *policy); #endif void grpc_resolver_init(grpc_resolver *resolver, - const grpc_resolver_vtable *vtable); + const grpc_resolver_vtable *vtable); void grpc_resolver_shutdown(grpc_resolver *resolver); diff --git a/src/core/client_config/resolvers/unix_resolver_posix.c b/src/core/client_config/resolvers/unix_resolver_posix.c index 7f2008685c..be515d2689 100644 --- a/src/core/client_config/resolvers/unix_resolver_posix.c +++ b/src/core/client_config/resolvers/unix_resolver_posix.c @@ -136,7 +136,7 @@ static void unix_maybe_finish_next_locked(unix_resolver *r) { } static void unix_destroy(grpc_resolver *gr) { - unix_resolver *r = (unix_resolver*)gr; + unix_resolver *r = (unix_resolver *)gr; gpr_mu_destroy(&r->mu); grpc_subchannel_factory_unref(r->subchannel_factory); gpr_free(r); diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c index d16786a7ad..cde14b9222 100644 --- a/src/core/client_config/subchannel.c +++ b/src/core/client_config/subchannel.c @@ -134,21 +134,31 @@ static grpc_connectivity_state compute_connectivity_locked(grpc_subchannel *c); static gpr_timespec compute_connect_deadline(grpc_subchannel *c); static void subchannel_connected(void *subchannel, int iomgr_success); -static void subchannel_ref_locked(grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -static int subchannel_unref_locked(grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) GRPC_MUST_USE_RESULT; +static void subchannel_ref_locked( + grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +static int subchannel_unref_locked( + grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) GRPC_MUST_USE_RESULT; static void connection_ref_locked(connection *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -static grpc_subchannel *connection_unref_locked(connection *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) - GRPC_MUST_USE_RESULT; +static grpc_subchannel *connection_unref_locked( + connection *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) GRPC_MUST_USE_RESULT; static void subchannel_destroy(grpc_subchannel *c); #ifdef GRPC_SUBCHANNEL_REFCOUNT_DEBUG -#define SUBCHANNEL_REF_LOCKED(p, r) subchannel_ref_locked((p), __FILE__, __LINE__, (r)) -#define SUBCHANNEL_UNREF_LOCKED(p, r) subchannel_unref_locked((p), __FILE__, __LINE__, (r)) -#define CONNECTION_REF_LOCKED(p, r) connection_ref_locked((p), __FILE__, __LINE__, (r)) -#define CONNECTION_UNREF_LOCKED(p, r) connection_unref_locked((p), __FILE__, __LINE__, (r)) +#define SUBCHANNEL_REF_LOCKED(p, r) \ + subchannel_ref_locked((p), __FILE__, __LINE__, (r)) +#define SUBCHANNEL_UNREF_LOCKED(p, r) \ + subchannel_unref_locked((p), __FILE__, __LINE__, (r)) +#define CONNECTION_REF_LOCKED(p, r) \ + connection_ref_locked((p), __FILE__, __LINE__, (r)) +#define CONNECTION_UNREF_LOCKED(p, r) \ + connection_unref_locked((p), __FILE__, __LINE__, (r)) #define REF_PASS_ARGS , file, line, reason -#define REF_LOG(name, p) gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "%s: %p ref %d -> %d %s", (name), (p), (p)->refs, (p)->refs + 1, reason) -#define UNREF_LOG(name, p) gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "%s: %p unref %d -> %d %s", (name), (p), (p)->refs, (p)->refs - 1, reason) +#define REF_LOG(name, p) \ + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "%s: %p ref %d -> %d %s", \ + (name), (p), (p)->refs, (p)->refs + 1, reason) +#define UNREF_LOG(name, p) \ + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, "%s: %p unref %d -> %d %s", \ + (name), (p), (p)->refs, (p)->refs - 1, reason) #else #define SUBCHANNEL_REF_LOCKED(p, r) subchannel_ref_locked((p)) #define SUBCHANNEL_UNREF_LOCKED(p, r) subchannel_unref_locked((p)) @@ -174,13 +184,15 @@ static void connection_destroy(connection *c) { gpr_free(c); } -static void connection_ref_locked(connection *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { +static void connection_ref_locked( + connection *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { REF_LOG("CONNECTION", c); subchannel_ref_locked(c->subchannel REF_PASS_ARGS); ++c->refs; } -static grpc_subchannel *connection_unref_locked(connection *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { +static grpc_subchannel *connection_unref_locked( + connection *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { grpc_subchannel *destroy = NULL; UNREF_LOG("CONNECTION", c); if (subchannel_unref_locked(c->subchannel REF_PASS_ARGS)) { @@ -196,12 +208,14 @@ static grpc_subchannel *connection_unref_locked(connection *c GRPC_SUBCHANNEL_RE * grpc_subchannel implementation */ -static void subchannel_ref_locked(grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { +static void subchannel_ref_locked( + grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { REF_LOG("SUBCHANNEL", c); - ++c->refs; + ++c->refs; } -static int subchannel_unref_locked(grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { +static int subchannel_unref_locked( + grpc_subchannel *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { UNREF_LOG("SUBCHANNEL", c); return --c->refs == 0; } @@ -385,7 +399,8 @@ void grpc_subchannel_process_transport_op(grpc_subchannel *c, if (con != NULL) { grpc_channel_stack *channel_stack = CHANNEL_STACK_FROM_CONNECTION(con); - grpc_channel_element *top_elem = grpc_channel_stack_element(channel_stack, 0); + grpc_channel_element *top_elem = + grpc_channel_stack_element(channel_stack, 0); top_elem->filter->start_transport_op(top_elem, op); gpr_mu_lock(&c->mu); @@ -485,7 +500,8 @@ static void publish_transport(grpc_subchannel *c) { stk = (grpc_channel_stack *)(con + 1); con->refs = 0; con->subchannel = c; - grpc_channel_stack_init(filters, num_filters, c->master, c->args, c->mdctx, stk); + grpc_channel_stack_init(filters, num_filters, c->master, c->args, c->mdctx, + stk); grpc_connected_channel_bind_transport(stk, c->connecting_result.transport); gpr_free(c->connecting_result.filters); memset(&c->connecting_result, 0, sizeof(c->connecting_result)); @@ -601,11 +617,13 @@ static void connectivity_state_changed_locked(grpc_subchannel *c) { * grpc_subchannel_call implementation */ -void grpc_subchannel_call_ref(grpc_subchannel_call *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { - gpr_ref(&c->refs); +void grpc_subchannel_call_ref( + grpc_subchannel_call *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { + gpr_ref(&c->refs); } -void grpc_subchannel_call_unref(grpc_subchannel_call *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { +void grpc_subchannel_call_unref( + grpc_subchannel_call *c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) { if (gpr_unref(&c->refs)) { gpr_mu *mu = &c->connection->subchannel->mu; grpc_subchannel *destroy; diff --git a/src/core/client_config/subchannel.h b/src/core/client_config/subchannel.h index 5435ef703b..a23a623277 100644 --- a/src/core/client_config/subchannel.h +++ b/src/core/client_config/subchannel.h @@ -44,11 +44,16 @@ typedef struct grpc_subchannel_call grpc_subchannel_call; typedef struct grpc_subchannel_args grpc_subchannel_args; #ifdef GRPC_SUBCHANNEL_REFCOUNT_DEBUG -#define GRPC_SUBCHANNEL_REF(p, r) grpc_subchannel_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_UNREF(p, r) grpc_subchannel_unref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_CALL_REF(p, r) grpc_subchannel_call_ref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_CALL_UNREF(p, r) grpc_subchannel_call_unref((p), __FILE__, __LINE__, (r)) -#define GRPC_SUBCHANNEL_REF_EXTRA_ARGS , const char *file, int line, const char *reason +#define GRPC_SUBCHANNEL_REF(p, r) \ + grpc_subchannel_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_UNREF(p, r) \ + grpc_subchannel_unref((p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_CALL_REF(p, r) \ + grpc_subchannel_call_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_CALL_UNREF(p, r) \ + grpc_subchannel_call_unref((p), __FILE__, __LINE__, (r)) +#define GRPC_SUBCHANNEL_REF_EXTRA_ARGS \ + , const char *file, int line, const char *reason #else #define GRPC_SUBCHANNEL_REF(p, r) grpc_subchannel_ref((p)) #define GRPC_SUBCHANNEL_UNREF(p, r) grpc_subchannel_unref((p)) @@ -57,10 +62,14 @@ typedef struct grpc_subchannel_args grpc_subchannel_args; #define GRPC_SUBCHANNEL_REF_EXTRA_ARGS #endif -void grpc_subchannel_ref(grpc_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -void grpc_subchannel_unref(grpc_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -void grpc_subchannel_call_ref(grpc_subchannel_call *call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); -void grpc_subchannel_call_unref(grpc_subchannel_call *call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +void grpc_subchannel_ref( + grpc_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +void grpc_subchannel_unref( + grpc_subchannel *channel GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +void grpc_subchannel_call_ref( + grpc_subchannel_call *call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); +void grpc_subchannel_call_unref( + grpc_subchannel_call *call GRPC_SUBCHANNEL_REF_EXTRA_ARGS); /** construct a call (possibly asynchronously) */ void grpc_subchannel_create_call(grpc_subchannel *subchannel, diff --git a/src/core/client_config/uri_parser.c b/src/core/client_config/uri_parser.c index c5faab5eba..776a255923 100644 --- a/src/core/client_config/uri_parser.c +++ b/src/core/client_config/uri_parser.c @@ -39,7 +39,8 @@ #include #include -static grpc_uri *bad_uri(const char *uri_text, int pos, const char *section, int suppress_errors) { +static grpc_uri *bad_uri(const char *uri_text, int pos, const char *section, + int suppress_errors) { char *line_prefix; int pfx_len; diff --git a/src/core/iomgr/fd_posix.c b/src/core/iomgr/fd_posix.c index 446081954d..afecccae17 100644 --- a/src/core/iomgr/fd_posix.c +++ b/src/core/iomgr/fd_posix.c @@ -199,7 +199,8 @@ static void wake_all_watchers_locked(grpc_fd *fd) { } static int has_watchers(grpc_fd *fd) { - return fd->read_watcher != NULL || fd->write_watcher != NULL || fd->inactive_watcher_root.next != &fd->inactive_watcher_root; + return fd->read_watcher != NULL || fd->write_watcher != NULL || + fd->inactive_watcher_root.next != &fd->inactive_watcher_root; } void grpc_fd_orphan(grpc_fd *fd, grpc_iomgr_closure *on_done, diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c index 93bf846978..5d04ec49b2 100644 --- a/src/core/security/client_auth_filter.c +++ b/src/core/security/client_auth_filter.c @@ -280,7 +280,7 @@ static void destroy_call_elem(grpc_call_element *elem) { } /* Constructor for channel_data */ -static void init_channel_elem(grpc_channel_element *elem,grpc_channel *master, +static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *metadata_context, int is_first, int is_last) { @@ -326,6 +326,6 @@ static void destroy_channel_elem(grpc_channel_element *elem) { } const grpc_channel_filter grpc_client_auth_filter = { - auth_start_transport_op, grpc_channel_next_op, sizeof(call_data), + auth_start_transport_op, grpc_channel_next_op, sizeof(call_data), init_call_elem, destroy_call_elem, sizeof(channel_data), init_channel_elem, destroy_channel_elem, "client-auth"}; diff --git a/src/core/security/server_auth_filter.c b/src/core/security/server_auth_filter.c index a92b46c85f..a0dbeb58cd 100644 --- a/src/core/security/server_auth_filter.c +++ b/src/core/security/server_auth_filter.c @@ -84,8 +84,7 @@ static void init_call_elem(grpc_call_element *elem, } /* Destructor for call_data */ -static void destroy_call_elem(grpc_call_element *elem) { -} +static void destroy_call_elem(grpc_call_element *elem) {} /* Constructor for channel_data */ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, @@ -115,6 +114,6 @@ static void destroy_channel_elem(grpc_channel_element *elem) { } const grpc_channel_filter grpc_server_auth_filter = { - auth_start_transport_op, grpc_channel_next_op, sizeof(call_data), init_call_elem, - destroy_call_elem, sizeof(channel_data), init_channel_elem, - destroy_channel_elem, "server-auth"}; + auth_start_transport_op, grpc_channel_next_op, sizeof(call_data), + init_call_elem, destroy_call_elem, sizeof(channel_data), + init_channel_elem, destroy_channel_elem, "server-auth"}; diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c index 018ec3d1d7..2e49e370f7 100644 --- a/src/core/security/server_secure_chttp2.c +++ b/src/core/security/server_secure_chttp2.c @@ -75,9 +75,8 @@ static void state_unref(grpc_server_secure_state *state) { } } -static void setup_transport(void *statep, - grpc_transport *transport, - grpc_mdctx *mdctx) { +static void setup_transport(void *statep, grpc_transport *transport, + grpc_mdctx *mdctx) { static grpc_channel_filter const *extra_filters[] = { &grpc_server_auth_filter, &grpc_http_server_filter}; grpc_server_secure_state *state = statep; @@ -85,8 +84,7 @@ static void setup_transport(void *statep, grpc_channel_args *args_copy = grpc_channel_args_copy_and_add( grpc_server_get_channel_args(state->server), &connector_arg, 1); grpc_server_setup_transport(state->server, transport, extra_filters, - GPR_ARRAY_SIZE(extra_filters), mdctx, - args_copy); + GPR_ARRAY_SIZE(extra_filters), mdctx, args_copy); grpc_channel_args_destroy(args_copy); } @@ -101,8 +99,8 @@ static void on_secure_transport_setup_done(void *statep, if (!state->is_shutdown) { mdctx = grpc_mdctx_create(); transport = grpc_create_chttp2_transport( - grpc_server_get_channel_args(state->server), - secure_endpoint, NULL, 0, mdctx, 0); + grpc_server_get_channel_args(state->server), secure_endpoint, NULL, 0, + mdctx, 0); setup_transport(state, transport, mdctx); } else { /* We need to consume this here, because the server may already have gone diff --git a/src/core/surface/call.c b/src/core/surface/call.c index 84ae038e46..8550056bcb 100644 --- a/src/core/surface/call.c +++ b/src/core/surface/call.c @@ -462,8 +462,7 @@ static int need_more_data(grpc_call *call) { (is_op_live(call, GRPC_IOREQ_RECV_CLOSE) && grpc_bbq_empty(&call->incoming_queue)) || (call->write_state == WRITE_STATE_INITIAL && !call->is_client) || - (call->cancel_with_status != GRPC_STATUS_OK) || - call->destroy_called; + (call->cancel_with_status != GRPC_STATUS_OK) || call->destroy_called; } static void unlock(grpc_call *call) { @@ -1151,7 +1150,8 @@ static void execute_op(grpc_call *call, grpc_transport_stream_op *op) { } else { finished_loose_op_allocated_args *args = gpr_malloc(sizeof(*args)); args->call = call; - grpc_iomgr_closure_init(&args->closure, finished_loose_op_allocated, args); + grpc_iomgr_closure_init(&args->closure, finished_loose_op_allocated, + args); op->on_consumed = &args->closure; } } @@ -1223,13 +1223,13 @@ static gpr_uint32 decode_compression(grpc_mdelem *md) { } else { gpr_uint32 parsed_clevel_bytes; if (gpr_parse_bytes_to_uint32(grpc_mdstr_as_c_string(md->value), - GPR_SLICE_LENGTH(md->value->slice), - &parsed_clevel_bytes)) { + GPR_SLICE_LENGTH(md->value->slice), + &parsed_clevel_bytes)) { /* the following cast is safe, as a gpr_uint32 should be able to hold all * possible values of the grpc_compression_level enum */ - clevel = (grpc_compression_level) parsed_clevel_bytes; + clevel = (grpc_compression_level)parsed_clevel_bytes; } else { - clevel = GRPC_COMPRESS_LEVEL_NONE; /* could not parse, no compression */ + clevel = GRPC_COMPRESS_LEVEL_NONE; /* could not parse, no compression */ } grpc_mdelem_set_user_data(md, destroy_compression, (void *)(gpr_intptr)(clevel + COMPRESS_OFFSET)); @@ -1252,7 +1252,8 @@ static void recv_metadata(grpc_call *call, grpc_metadata_batch *md) { set_status_code(call, STATUS_FROM_WIRE, decode_status(md)); } else if (key == grpc_channel_get_message_string(call->channel)) { set_status_details(call, STATUS_FROM_WIRE, grpc_mdstr_ref(md->value)); - } else if (key == grpc_channel_get_compresssion_level_string(call->channel)) { + } else if (key == + grpc_channel_get_compresssion_level_string(call->channel)) { set_decode_compression_level(call, decode_compression(md)); } else { dest = &call->buffered_metadata[is_trailing]; diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c index e85eaf2c05..f8151c121c 100644 --- a/src/core/surface/channel.c +++ b/src/core/surface/channel.c @@ -129,7 +129,8 @@ grpc_channel *grpc_channel_create_from_filters( } } - grpc_channel_stack_init(filters, num_filters, channel, args, channel->metadata_context, + grpc_channel_stack_init(filters, num_filters, channel, args, + channel->metadata_context, CHANNEL_STACK_FROM_CHANNEL(channel)); return channel; @@ -264,7 +265,6 @@ grpc_mdstr *grpc_channel_get_compresssion_level_string(grpc_channel *channel) { return channel->grpc_compression_level_string; } - grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel, int i) { if (i >= 0 && i < NUM_CACHED_STATUS_ELEMS) { return grpc_mdelem_ref(channel->grpc_status_elem[i]); diff --git a/src/core/surface/channel_create.c b/src/core/surface/channel_create.c index 20da830388..280927834b 100644 --- a/src/core/surface/channel_create.c +++ b/src/core/surface/channel_create.c @@ -71,10 +71,10 @@ static void connected(void *arg, grpc_endpoint *tcp) { connector *c = arg; grpc_iomgr_closure *notify; if (tcp != NULL) { - c->result->transport = - grpc_create_chttp2_transport(c->args.channel_args, tcp, NULL, 0, c->args.metadata_context, 1); + c->result->transport = grpc_create_chttp2_transport( + c->args.channel_args, tcp, NULL, 0, c->args.metadata_context, 1); GPR_ASSERT(c->result->transport); - c->result->filters = gpr_malloc(sizeof(grpc_channel_filter*)); + c->result->filters = gpr_malloc(sizeof(grpc_channel_filter *)); c->result->filters[0] = &grpc_http_client_filter; c->result->num_filters = 1; } else { @@ -85,19 +85,22 @@ static void connected(void *arg, grpc_endpoint *tcp) { grpc_iomgr_add_callback(notify); } -static void connector_connect( - grpc_connector *con, const grpc_connect_in_args *args, - grpc_connect_out_args *result, grpc_iomgr_closure *notify) { +static void connector_connect(grpc_connector *con, + const grpc_connect_in_args *args, + grpc_connect_out_args *result, + grpc_iomgr_closure *notify) { connector *c = (connector *)con; GPR_ASSERT(c->notify == NULL); GPR_ASSERT(notify->cb); c->notify = notify; c->args = *args; c->result = result; - grpc_tcp_client_connect(connected, c, args->interested_parties, args->addr, args->addr_len, args->deadline); + grpc_tcp_client_connect(connected, c, args->interested_parties, args->addr, + args->addr_len, args->deadline); } -static const grpc_connector_vtable connector_vtable = {connector_ref, connector_unref, connector_connect}; +static const grpc_connector_vtable connector_vtable = { + connector_ref, connector_unref, connector_connect}; typedef struct { grpc_subchannel_factory base; @@ -119,7 +122,8 @@ static void subchannel_factory_unref(grpc_subchannel_factory *scf) { } } -static grpc_subchannel *subchannel_factory_create_subchannel(grpc_subchannel_factory *scf, grpc_subchannel_args *args) { +static grpc_subchannel *subchannel_factory_create_subchannel( + grpc_subchannel_factory *scf, grpc_subchannel_args *args) { subchannel_factory *f = (subchannel_factory *)scf; connector *c = gpr_malloc(sizeof(*c)); grpc_channel_args *final_args = @@ -136,7 +140,9 @@ static grpc_subchannel *subchannel_factory_create_subchannel(grpc_subchannel_fac return s; } -static const grpc_subchannel_factory_vtable subchannel_factory_vtable = {subchannel_factory_ref, subchannel_factory_unref, subchannel_factory_create_subchannel}; +static const grpc_subchannel_factory_vtable subchannel_factory_vtable = { + subchannel_factory_ref, subchannel_factory_unref, + subchannel_factory_create_subchannel}; /* Create a client channel: Asynchronously: - resolve target @@ -170,7 +176,8 @@ grpc_channel *grpc_channel_create(const char *target, } channel = grpc_channel_create_from_filters(filters, n, args, mdctx, 1); - grpc_client_channel_set_resolver(grpc_channel_get_channel_stack(channel), resolver); + grpc_client_channel_set_resolver(grpc_channel_get_channel_stack(channel), + resolver); GRPC_RESOLVER_UNREF(resolver, "create"); grpc_subchannel_factory_unref(&f->base); diff --git a/src/core/surface/lame_client.c b/src/core/surface/lame_client.c index c6ac679871..3dd56fe5a9 100644 --- a/src/core/surface/lame_client.c +++ b/src/core/surface/lame_client.c @@ -105,7 +105,7 @@ static void init_call_elem(grpc_call_element *elem, static void destroy_call_elem(grpc_call_element *elem) {} -static void init_channel_elem(grpc_channel_element *elem,grpc_channel *master, +static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *mdctx, int is_first, int is_last) { channel_data *chand = elem->channel_data; diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c index d355079260..998acfc8cf 100644 --- a/src/core/surface/secure_channel_create.c +++ b/src/core/surface/secure_channel_create.c @@ -82,9 +82,9 @@ static void on_secure_transport_setup_done(void *arg, gpr_log(GPR_ERROR, "Secure transport setup failed with error %d.", status); memset(c->result, 0, sizeof(*c->result)); } else { - c->result->transport = grpc_create_chttp2_transport( - c->args.channel_args, secure_endpoint, - NULL, 0, c->args.metadata_context, 1); + c->result->transport = + grpc_create_chttp2_transport(c->args.channel_args, secure_endpoint, + NULL, 0, c->args.metadata_context, 1); c->result->filters = gpr_malloc(sizeof(grpc_channel_filter *) * 2); c->result->filters[0] = &grpc_client_auth_filter; c->result->filters[1] = &grpc_http_client_filter; @@ -109,19 +109,22 @@ static void connected(void *arg, grpc_endpoint *tcp) { } } -static void connector_connect( - grpc_connector *con, const grpc_connect_in_args *args, - grpc_connect_out_args *result, grpc_iomgr_closure *notify) { +static void connector_connect(grpc_connector *con, + const grpc_connect_in_args *args, + grpc_connect_out_args *result, + grpc_iomgr_closure *notify) { connector *c = (connector *)con; GPR_ASSERT(c->notify == NULL); GPR_ASSERT(notify->cb); c->notify = notify; c->args = *args; c->result = result; - grpc_tcp_client_connect(connected, c, args->interested_parties, args->addr, args->addr_len, args->deadline); + grpc_tcp_client_connect(connected, c, args->interested_parties, args->addr, + args->addr_len, args->deadline); } -static const grpc_connector_vtable connector_vtable = {connector_ref, connector_unref, connector_connect}; +static const grpc_connector_vtable connector_vtable = { + connector_ref, connector_unref, connector_connect}; typedef struct { grpc_subchannel_factory base; @@ -144,7 +147,8 @@ static void subchannel_factory_unref(grpc_subchannel_factory *scf) { } } -static grpc_subchannel *subchannel_factory_create_subchannel(grpc_subchannel_factory *scf, grpc_subchannel_args *args) { +static grpc_subchannel *subchannel_factory_create_subchannel( + grpc_subchannel_factory *scf, grpc_subchannel_args *args) { subchannel_factory *f = (subchannel_factory *)scf; connector *c = gpr_malloc(sizeof(*c)); grpc_channel_args *final_args = @@ -162,7 +166,9 @@ static grpc_subchannel *subchannel_factory_create_subchannel(grpc_subchannel_fac return s; } -static const grpc_subchannel_factory_vtable subchannel_factory_vtable = {subchannel_factory_ref, subchannel_factory_unref, subchannel_factory_create_subchannel}; +static const grpc_subchannel_factory_vtable subchannel_factory_vtable = { + subchannel_factory_ref, subchannel_factory_unref, + subchannel_factory_create_subchannel}; /* Create a secure client channel: Asynchronously: - resolve target @@ -219,7 +225,8 @@ grpc_channel *grpc_secure_channel_create(grpc_credentials *creds, } channel = grpc_channel_create_from_filters(filters, n, args_copy, mdctx, 1); - grpc_client_channel_set_resolver(grpc_channel_get_channel_stack(channel), resolver); + grpc_client_channel_set_resolver(grpc_channel_get_channel_stack(channel), + resolver); GRPC_RESOLVER_UNREF(resolver, "create"); grpc_channel_args_destroy(args_copy); diff --git a/src/core/surface/server.c b/src/core/surface/server.c index 703eeaf2bd..c883d08a02 100644 --- a/src/core/surface/server.c +++ b/src/core/surface/server.c @@ -151,7 +151,7 @@ struct grpc_server { before mu_call. This is currently used in shutdown processing (grpc_server_shutdown_and_notify and maybe_finish_shutdown) */ gpr_mu mu_global; /* mutex for server and channel state */ - gpr_mu mu_call; /* mutex for call-specific state */ + gpr_mu mu_call; /* mutex for call-specific state */ registered_method *registered_methods; requested_call_array requested_calls; @@ -226,11 +226,10 @@ static void channel_broadcaster_init(grpc_server *s, channel_broadcaster *cb) { channel_data *c; size_t count = 0; size_t dc_count = 0; - for (c = s->root_channel_data.next; c != &s->root_channel_data; - c = c->next) { - count ++; + for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) { + count++; if (c->num_calls == 0) { - dc_count ++; + dc_count++; } } cb->num_channels = count; @@ -239,8 +238,7 @@ static void channel_broadcaster_init(grpc_server *s, channel_broadcaster *cb) { cb->disconnects = gpr_malloc(sizeof(*cb->channels) * cb->num_disconnects); count = 0; dc_count = 0; - for (c = s->root_channel_data.next; c != &s->root_channel_data; - c = c->next) { + for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) { cb->channels[count++] = c->channel; GRPC_CHANNEL_INTERNAL_REF(c->channel, "broadcast"); if (c->num_calls == 0) { @@ -261,7 +259,8 @@ static void shutdown_cleanup(void *arg, int iomgr_status_ignored) { gpr_free(a); } -static void send_shutdown(grpc_channel *channel, int send_goaway, int send_disconnect) { +static void send_shutdown(grpc_channel *channel, int send_goaway, + int send_disconnect) { grpc_transport_op op; struct shutdown_cleanup_args *sc; grpc_channel_element *elem; @@ -277,12 +276,12 @@ static void send_shutdown(grpc_channel *channel, int send_goaway, int send_disco grpc_iomgr_closure_init(&sc->closure, shutdown_cleanup, sc); op.on_consumed = &sc->closure; - elem = grpc_channel_stack_element( - grpc_channel_get_channel_stack(channel), 0); + elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0); elem->filter->start_transport_op(elem, &op); } -static void channel_broadcaster_shutdown(channel_broadcaster *cb, int send_goaway, int send_disconnect) { +static void channel_broadcaster_shutdown(channel_broadcaster *cb, + int send_goaway, int send_disconnect) { size_t i; for (i = 0; i < cb->num_channels; i++) { @@ -721,7 +720,7 @@ static void destroy_call_elem(grpc_call_element *elem) { server_unref(chand->server); } -static void init_channel_elem(grpc_channel_element *elem,grpc_channel *master, +static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *metadata_context, int is_first, int is_last) { diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c index e32071e692..d8001d6c32 100644 --- a/src/core/transport/chttp2_transport.c +++ b/src/core/transport/chttp2_transport.c @@ -117,7 +117,9 @@ static void add_to_pollset_locked(grpc_chttp2_transport *t, static void maybe_start_some_streams( grpc_chttp2_transport_global *transport_global); -static void connectivity_state_set(grpc_chttp2_transport_global *transport_global, grpc_connectivity_state state); +static void connectivity_state_set( + grpc_chttp2_transport_global *transport_global, + grpc_connectivity_state state); /* * CONSTRUCTION/DESTRUCTION/REFCOUNTING @@ -330,8 +332,7 @@ static void destroy_transport(grpc_transport *gt) { static void close_transport_locked(grpc_chttp2_transport *t) { if (!t->closed) { t->closed = 1; - connectivity_state_set(&t->global, - GRPC_CHANNEL_FATAL_FAILURE); + connectivity_state_set(&t->global, GRPC_CHANNEL_FATAL_FAILURE); if (t->ep) { grpc_endpoint_shutdown(t->ep); } @@ -339,7 +340,8 @@ static void close_transport_locked(grpc_chttp2_transport *t) { } static int init_stream(grpc_transport *gt, grpc_stream *gs, - const void *server_data, grpc_transport_stream_op *initial_op) { + const void *server_data, + grpc_transport_stream_op *initial_op) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)gt; grpc_chttp2_stream *s = (grpc_chttp2_stream *)gs; @@ -521,14 +523,13 @@ static void writing_action(void *gt, int iomgr_success_ignored) { void grpc_chttp2_add_incoming_goaway( grpc_chttp2_transport_global *transport_global, gpr_uint32 goaway_error, gpr_slice goaway_text) { - char *msg = gpr_hexdump((char*)GPR_SLICE_START_PTR(goaway_text), GPR_SLICE_LENGTH(goaway_text), GPR_HEXDUMP_PLAINTEXT); + char *msg = gpr_hexdump((char *)GPR_SLICE_START_PTR(goaway_text), + GPR_SLICE_LENGTH(goaway_text), GPR_HEXDUMP_PLAINTEXT); gpr_log(GPR_DEBUG, "got goaway [%d]: %s", goaway_error, msg); gpr_free(msg); gpr_slice_unref(goaway_text); transport_global->seen_goaway = 1; - connectivity_state_set( - transport_global, - GRPC_CHANNEL_FATAL_FAILURE); + connectivity_state_set(transport_global, GRPC_CHANNEL_FATAL_FAILURE); } static void maybe_start_some_streams( @@ -735,9 +736,8 @@ static void remove_stream(grpc_chttp2_transport *t, gpr_uint32 id) { grpc_chttp2_parsing_become_skip_parser(&t->parsing); } - new_stream_count = - grpc_chttp2_stream_map_size(&t->parsing_stream_map) + - grpc_chttp2_stream_map_size(&t->new_stream_map); + new_stream_count = grpc_chttp2_stream_map_size(&t->parsing_stream_map) + + grpc_chttp2_stream_map_size(&t->new_stream_map); if (new_stream_count != t->global.concurrent_stream_count) { t->global.concurrent_stream_count = new_stream_count; maybe_start_some_streams(&t->global); @@ -772,11 +772,12 @@ static void unlock_check_read_write_state(grpc_chttp2_transport *t) { if (!stream_global->published_cancelled) { char buffer[GPR_LTOA_MIN_BUFSIZE]; gpr_ltoa(stream_global->cancelled_status, buffer); - grpc_chttp2_incoming_metadata_buffer_add(&stream_global->incoming_metadata, - grpc_mdelem_from_strings(t->metadata_context, "grpc-status", buffer)); + grpc_chttp2_incoming_metadata_buffer_add( + &stream_global->incoming_metadata, + grpc_mdelem_from_strings(t->metadata_context, "grpc-status", + buffer)); grpc_chttp2_incoming_metadata_buffer_place_metadata_batch_into( - &stream_global->incoming_metadata, - &stream_global->incoming_sopb); + &stream_global->incoming_metadata, &stream_global->incoming_sopb); stream_global->published_cancelled = 1; } } @@ -825,10 +826,10 @@ static void cancel_from_api(grpc_chttp2_transport_global *transport_global, stream_global->cancelled = 1; stream_global->cancelled_status = status; if (stream_global->id != 0) { - gpr_slice_buffer_add(&transport_global->qbuf, - grpc_chttp2_rst_stream_create( - stream_global->id, - grpc_chttp2_grpc_status_to_http2_error(status))); + gpr_slice_buffer_add( + &transport_global->qbuf, + grpc_chttp2_rst_stream_create( + stream_global->id, grpc_chttp2_grpc_status_to_http2_error(status))); } grpc_chttp2_list_add_read_write_state_changed(transport_global, stream_global); @@ -907,7 +908,8 @@ static void recv_data(void *tp, gpr_slice *slices, size_t nslices, /* merge stream lists */ grpc_chttp2_stream_map_move_into(&t->new_stream_map, &t->parsing_stream_map); - t->global.concurrent_stream_count = grpc_chttp2_stream_map_size(&t->parsing_stream_map); + t->global.concurrent_stream_count = + grpc_chttp2_stream_map_size(&t->parsing_stream_map); if (t->parsing.initial_window_update != 0) { grpc_chttp2_stream_map_for_each(&t->parsing_stream_map, update_global_window, t); @@ -934,17 +936,19 @@ static void reading_action(void *pt, int iomgr_success_ignored) { * CALLBACK LOOP */ -static void schedule_closure_for_connectivity(void *a, grpc_iomgr_closure *closure) { +static void schedule_closure_for_connectivity(void *a, + grpc_iomgr_closure *closure) { grpc_chttp2_schedule_closure(a, closure, 1); } -static void connectivity_state_set(grpc_chttp2_transport_global *transport_global, grpc_connectivity_state state) { - GRPC_CHTTP2_IF_TRACING(gpr_log(GPR_DEBUG, "set connectivity_state=%d", state)); +static void connectivity_state_set( + grpc_chttp2_transport_global *transport_global, + grpc_connectivity_state state) { + GRPC_CHTTP2_IF_TRACING( + gpr_log(GPR_DEBUG, "set connectivity_state=%d", state)); grpc_connectivity_state_set_with_scheduler( - &TRANSPORT_FROM_GLOBAL(transport_global)->channel_callback.state_tracker, - state, - schedule_closure_for_connectivity, - transport_global); + &TRANSPORT_FROM_GLOBAL(transport_global)->channel_callback.state_tracker, + state, schedule_closure_for_connectivity, transport_global); } void grpc_chttp2_schedule_closure( diff --git a/src/core/transport/connectivity_state.c b/src/core/transport/connectivity_state.c index 9a956a5a58..dabe46badd 100644 --- a/src/core/transport/connectivity_state.c +++ b/src/core/transport/connectivity_state.c @@ -81,8 +81,7 @@ int grpc_connectivity_state_notify_on_state_change( void grpc_connectivity_state_set_with_scheduler( grpc_connectivity_state_tracker *tracker, grpc_connectivity_state state, - void (*scheduler)(void *arg, grpc_iomgr_closure *closure), - void *arg) { + void (*scheduler)(void *arg, grpc_iomgr_closure *closure), void *arg) { grpc_connectivity_state_watcher *new = NULL; grpc_connectivity_state_watcher *w; /*gpr_log(GPR_DEBUG, "CS:%p:set:%d", tracker, state);*/ @@ -111,5 +110,6 @@ static void default_scheduler(void *ignored, grpc_iomgr_closure *closure) { void grpc_connectivity_state_set(grpc_connectivity_state_tracker *tracker, grpc_connectivity_state state) { - grpc_connectivity_state_set_with_scheduler(tracker, state, default_scheduler, NULL); + grpc_connectivity_state_set_with_scheduler(tracker, state, default_scheduler, + NULL); } diff --git a/src/core/transport/connectivity_state.h b/src/core/transport/connectivity_state.h index c6f903a1ea..bbdcbcb069 100644 --- a/src/core/transport/connectivity_state.h +++ b/src/core/transport/connectivity_state.h @@ -61,8 +61,7 @@ void grpc_connectivity_state_set(grpc_connectivity_state_tracker *tracker, grpc_connectivity_state state); void grpc_connectivity_state_set_with_scheduler( grpc_connectivity_state_tracker *tracker, grpc_connectivity_state state, - void (*scheduler)(void *arg, grpc_iomgr_closure *closure), - void *arg); + void (*scheduler)(void *arg, grpc_iomgr_closure *closure), void *arg); grpc_connectivity_state grpc_connectivity_state_check( grpc_connectivity_state_tracker *tracker); diff --git a/src/core/transport/transport.c b/src/core/transport/transport.c index c29217599e..1397e21933 100644 --- a/src/core/transport/transport.c +++ b/src/core/transport/transport.c @@ -49,8 +49,9 @@ int grpc_transport_init_stream(grpc_transport *transport, grpc_stream *stream, initial_op); } -void grpc_transport_perform_stream_op(grpc_transport *transport, grpc_stream *stream, - grpc_transport_stream_op *op) { +void grpc_transport_perform_stream_op(grpc_transport *transport, + grpc_stream *stream, + grpc_transport_stream_op *op) { transport->vtable->perform_stream_op(transport, stream, op); } diff --git a/src/core/transport/transport.h b/src/core/transport/transport.h index 24a02132e9..599edc871f 100644 --- a/src/core/transport/transport.h +++ b/src/core/transport/transport.h @@ -99,7 +99,8 @@ typedef struct grpc_transport_op { gpr_slice *goaway_message; /** set the callback for accepting new streams; this is a permanent callback, unlike the other one-shot closures */ - void (*set_accept_stream)(void *user_data, grpc_transport *transport, const void *server_data); + void (*set_accept_stream)(void *user_data, grpc_transport *transport, + const void *server_data); void *set_accept_stream_user_data; /** add this transport to a pollset */ grpc_pollset *bind_pollset; @@ -154,10 +155,12 @@ char *grpc_transport_stream_op_string(grpc_transport_stream_op *op); stream - the stream on which to send the operations. This must be non-NULL and previously initialized by the same transport. op - a grpc_transport_stream_op specifying the op to perform */ -void grpc_transport_perform_stream_op(grpc_transport *transport, grpc_stream *stream, - grpc_transport_stream_op *op); +void grpc_transport_perform_stream_op(grpc_transport *transport, + grpc_stream *stream, + grpc_transport_stream_op *op); -void grpc_transport_perform_op(grpc_transport *transport, grpc_transport_op *op); +void grpc_transport_perform_op(grpc_transport *transport, + grpc_transport_op *op); /* Send a ping on a transport diff --git a/src/core/transport/transport_impl.h b/src/core/transport/transport_impl.h index b18f957009..515721dfb6 100644 --- a/src/core/transport/transport_impl.h +++ b/src/core/transport/transport_impl.h @@ -48,7 +48,7 @@ typedef struct grpc_transport_vtable { /* implementation of grpc_transport_perform_stream_op */ void (*perform_stream_op)(grpc_transport *self, grpc_stream *stream, - grpc_transport_stream_op *op); + grpc_transport_stream_op *op); /* implementation of grpc_transport_perform_op */ void (*perform_op)(grpc_transport *self, grpc_transport_op *op); diff --git a/test/core/bad_client/bad_client.c b/test/core/bad_client/bad_client.c index 4b889995a1..0b0a682607 100644 --- a/test/core/bad_client/bad_client.c +++ b/test/core/bad_client/bad_client.c @@ -63,14 +63,14 @@ static void done_write(void *arg, grpc_endpoint_cb_status status) { gpr_event_set(&a->done_write, (void *)1); } -static void server_setup_transport( - void *ts, grpc_transport *transport, grpc_mdctx *mdctx) { +static void server_setup_transport(void *ts, grpc_transport *transport, + grpc_mdctx *mdctx) { thd_args *a = ts; static grpc_channel_filter const *extra_filters[] = { &grpc_http_server_filter}; grpc_server_setup_transport(a->server, transport, extra_filters, - GPR_ARRAY_SIZE(extra_filters), mdctx, - grpc_server_get_channel_args(a->server)); + GPR_ARRAY_SIZE(extra_filters), mdctx, + grpc_server_get_channel_args(a->server)); } void grpc_run_bad_client_test(grpc_bad_client_server_side_validator validator, @@ -105,8 +105,7 @@ void grpc_run_bad_client_test(grpc_bad_client_server_side_validator validator, a.validator = validator; grpc_server_register_completion_queue(a.server, a.cq); grpc_server_start(a.server); - transport = grpc_create_chttp2_transport(NULL, sfd.server, - NULL, 0, mdctx, 0); + transport = grpc_create_chttp2_transport(NULL, sfd.server, NULL, 0, mdctx, 0); server_setup_transport(&a, transport, mdctx); /* Bind everything into the same pollset */ diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c index 55a15a1a54..eca2a40c97 100644 --- a/test/core/channel/channel_stack_test.c +++ b/test/core/channel/channel_stack_test.c @@ -39,7 +39,7 @@ #include #include "test/core/util/test_config.h" -static void channel_init_func(grpc_channel_element *elem,grpc_channel *master, +static void channel_init_func(grpc_channel_element *elem, grpc_channel *master, const grpc_channel_args *args, grpc_mdctx *metadata_context, int is_first, int is_last) { @@ -75,8 +75,9 @@ static void channel_func(grpc_channel_element *elem, grpc_transport_op *op) { static void test_create_channel_stack(void) { const grpc_channel_filter filter = { - call_func, channel_func, sizeof(int), call_init_func, call_destroy_func, - sizeof(int), channel_init_func, channel_destroy_func, "some_test_filter"}; + call_func, channel_func, sizeof(int), + call_init_func, call_destroy_func, sizeof(int), + channel_init_func, channel_destroy_func, "some_test_filter"}; const grpc_channel_filter *filters = &filter; grpc_channel_stack *channel_stack; grpc_call_stack *call_stack; diff --git a/test/core/end2end/fixtures/chttp2_socket_pair.c b/test/core/end2end/fixtures/chttp2_socket_pair.c index 9f3b36d5e9..f42b9831c8 100644 --- a/test/core/end2end/fixtures/chttp2_socket_pair.c +++ b/test/core/end2end/fixtures/chttp2_socket_pair.c @@ -55,14 +55,14 @@ /* chttp2 transport that is immediately available (used for testing connected_channel without a client_channel */ -static void server_setup_transport( - void *ts, grpc_transport *transport, grpc_mdctx *mdctx) { +static void server_setup_transport(void *ts, grpc_transport *transport, + grpc_mdctx *mdctx) { grpc_end2end_test_fixture *f = ts; static grpc_channel_filter const *extra_filters[] = { &grpc_http_server_filter}; grpc_server_setup_transport(f->server, transport, extra_filters, - GPR_ARRAY_SIZE(extra_filters), mdctx, - grpc_server_get_channel_args(f->server)); + GPR_ARRAY_SIZE(extra_filters), mdctx, + grpc_server_get_channel_args(f->server)); } typedef struct { @@ -70,8 +70,8 @@ typedef struct { grpc_channel_args *client_args; } sp_client_setup; -static void client_setup_transport( - void *ts, grpc_transport *transport, grpc_mdctx *mdctx) { +static void client_setup_transport(void *ts, grpc_transport *transport, + grpc_mdctx *mdctx) { sp_client_setup *cs = ts; const grpc_channel_filter *filters[] = {&grpc_http_client_filter, @@ -82,8 +82,8 @@ static void client_setup_transport( cs->f->client = channel; - grpc_connected_channel_bind_transport( - grpc_channel_get_channel_stack(channel), transport); + grpc_connected_channel_bind_transport(grpc_channel_get_channel_stack(channel), + transport); } static grpc_end2end_test_fixture chttp2_create_fixture_socketpair( @@ -108,8 +108,8 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture *f, sp_client_setup cs; cs.client_args = client_args; cs.f = f; - transport = grpc_create_chttp2_transport(client_args, - sfd->client, NULL, 0, mdctx, 1); + transport = + grpc_create_chttp2_transport(client_args, sfd->client, NULL, 0, mdctx, 1); client_setup_transport(&cs, transport, mdctx); GPR_ASSERT(f->client); } @@ -123,8 +123,8 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture *f, f->server = grpc_server_create_from_filters(NULL, 0, server_args); grpc_server_register_completion_queue(f->server, f->cq); grpc_server_start(f->server); - transport = grpc_create_chttp2_transport(server_args, - sfd->server, NULL, 0, mdctx, 0); + transport = + grpc_create_chttp2_transport(server_args, sfd->server, NULL, 0, mdctx, 0); server_setup_transport(f, transport, mdctx); } diff --git a/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c b/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c index d53a49edbf..be520380a7 100644 --- a/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c +++ b/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c @@ -55,14 +55,14 @@ /* chttp2 transport that is immediately available (used for testing connected_channel without a client_channel */ -static void server_setup_transport( - void *ts, grpc_transport *transport, grpc_mdctx *mdctx) { +static void server_setup_transport(void *ts, grpc_transport *transport, + grpc_mdctx *mdctx) { grpc_end2end_test_fixture *f = ts; static grpc_channel_filter const *extra_filters[] = { &grpc_http_server_filter}; grpc_server_setup_transport(f->server, transport, extra_filters, - GPR_ARRAY_SIZE(extra_filters), mdctx, - grpc_server_get_channel_args(f->server)); + GPR_ARRAY_SIZE(extra_filters), mdctx, + grpc_server_get_channel_args(f->server)); } typedef struct { @@ -70,8 +70,8 @@ typedef struct { grpc_channel_args *client_args; } sp_client_setup; -static void client_setup_transport( - void *ts, grpc_transport *transport, grpc_mdctx *mdctx) { +static void client_setup_transport(void *ts, grpc_transport *transport, + grpc_mdctx *mdctx) { sp_client_setup *cs = ts; const grpc_channel_filter *filters[] = {&grpc_http_client_filter, @@ -82,8 +82,8 @@ static void client_setup_transport( cs->f->client = channel; - grpc_connected_channel_bind_transport( - grpc_channel_get_channel_stack(channel), transport); + grpc_connected_channel_bind_transport(grpc_channel_get_channel_stack(channel), + transport); } static grpc_end2end_test_fixture chttp2_create_fixture_socketpair( @@ -108,8 +108,8 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture *f, sp_client_setup cs; cs.client_args = client_args; cs.f = f; - transport = grpc_create_chttp2_transport(client_args, - sfd->client, NULL, 0, mdctx, 1); + transport = + grpc_create_chttp2_transport(client_args, sfd->client, NULL, 0, mdctx, 1); client_setup_transport(&cs, transport, mdctx); GPR_ASSERT(f->client); } @@ -123,8 +123,8 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture *f, f->server = grpc_server_create_from_filters(NULL, 0, server_args); grpc_server_register_completion_queue(f->server, f->cq); grpc_server_start(f->server); - transport = grpc_create_chttp2_transport(server_args, - sfd->server, NULL, 0, mdctx, 0); + transport = + grpc_create_chttp2_transport(server_args, sfd->server, NULL, 0, mdctx, 0); server_setup_transport(f, transport, mdctx); } diff --git a/test/core/end2end/fixtures/chttp2_socket_pair_with_grpc_trace.c b/test/core/end2end/fixtures/chttp2_socket_pair_with_grpc_trace.c index c63d8f3fe9..037281c5ad 100644 --- a/test/core/end2end/fixtures/chttp2_socket_pair_with_grpc_trace.c +++ b/test/core/end2end/fixtures/chttp2_socket_pair_with_grpc_trace.c @@ -56,14 +56,14 @@ /* chttp2 transport that is immediately available (used for testing connected_channel without a client_channel */ -static void server_setup_transport( - void *ts, grpc_transport *transport, grpc_mdctx *mdctx) { +static void server_setup_transport(void *ts, grpc_transport *transport, + grpc_mdctx *mdctx) { grpc_end2end_test_fixture *f = ts; static grpc_channel_filter const *extra_filters[] = { &grpc_http_server_filter}; grpc_server_setup_transport(f->server, transport, extra_filters, - GPR_ARRAY_SIZE(extra_filters), mdctx, - grpc_server_get_channel_args(f->server)); + GPR_ARRAY_SIZE(extra_filters), mdctx, + grpc_server_get_channel_args(f->server)); } typedef struct { @@ -71,8 +71,8 @@ typedef struct { grpc_channel_args *client_args; } sp_client_setup; -static void client_setup_transport( - void *ts, grpc_transport *transport, grpc_mdctx *mdctx) { +static void client_setup_transport(void *ts, grpc_transport *transport, + grpc_mdctx *mdctx) { sp_client_setup *cs = ts; const grpc_channel_filter *filters[] = {&grpc_http_client_filter, @@ -83,8 +83,8 @@ static void client_setup_transport( cs->f->client = channel; - grpc_connected_channel_bind_transport( - grpc_channel_get_channel_stack(channel), transport); + grpc_connected_channel_bind_transport(grpc_channel_get_channel_stack(channel), + transport); } static grpc_end2end_test_fixture chttp2_create_fixture_socketpair( @@ -109,8 +109,8 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture *f, sp_client_setup cs; cs.client_args = client_args; cs.f = f; - transport = grpc_create_chttp2_transport(client_args, - sfd->client, NULL, 0, mdctx, 1); + transport = + grpc_create_chttp2_transport(client_args, sfd->client, NULL, 0, mdctx, 1); client_setup_transport(&cs, transport, mdctx); GPR_ASSERT(f->client); } @@ -124,8 +124,8 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture *f, f->server = grpc_server_create_from_filters(NULL, 0, server_args); grpc_server_register_completion_queue(f->server, f->cq); grpc_server_start(f->server); - transport = grpc_create_chttp2_transport(server_args, - sfd->server, NULL, 0, mdctx, 0); + transport = + grpc_create_chttp2_transport(server_args, sfd->server, NULL, 0, mdctx, 0); server_setup_transport(f, transport, mdctx); } diff --git a/test/core/end2end/multiple_server_queues_test.c b/test/core/end2end/multiple_server_queues_test.c index 2d79f5adbd..32f37b0973 100644 --- a/test/core/end2end/multiple_server_queues_test.c +++ b/test/core/end2end/multiple_server_queues_test.c @@ -49,7 +49,7 @@ int main(int argc, char **argv) { grpc_server_register_completion_queue(server, cq2); grpc_server_start(server); grpc_server_shutdown_and_notify(server, cq2, NULL); - grpc_completion_queue_next(cq2, gpr_inf_future); /* cue queue hang */ + grpc_completion_queue_next(cq2, gpr_inf_future); /* cue queue hang */ grpc_completion_queue_shutdown(cq1); grpc_completion_queue_shutdown(cq2); grpc_completion_queue_next(cq1, gpr_inf_future); diff --git a/test/core/iomgr/fd_conservation_posix_test.c b/test/core/iomgr/fd_conservation_posix_test.c index aa4551f2f1..8327c681b8 100644 --- a/test/core/iomgr/fd_conservation_posix_test.c +++ b/test/core/iomgr/fd_conservation_posix_test.c @@ -40,9 +40,9 @@ #include "src/core/iomgr/iomgr.h" int main(int argc, char **argv) { - int i; - struct rlimit rlim; - grpc_endpoint_pair p; + int i; + struct rlimit rlim; + grpc_endpoint_pair p; grpc_test_init(argc, argv); grpc_iomgr_init(); @@ -53,9 +53,9 @@ int main(int argc, char **argv) { GPR_ASSERT(0 == setrlimit(RLIMIT_NOFILE, &rlim)); for (i = 0; i < 100; i++) { - p = grpc_iomgr_create_endpoint_pair("test", 1); - grpc_endpoint_destroy(p.client); - grpc_endpoint_destroy(p.server); + p = grpc_iomgr_create_endpoint_pair("test", 1); + grpc_endpoint_destroy(p.client); + grpc_endpoint_destroy(p.server); } grpc_iomgr_shutdown(); -- cgit v1.2.3 From d2cc45970b4681e214214199b9f52fc0e83cc9e9 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 1 Jul 2015 07:50:47 -0700 Subject: Spam cleanup, properly shut down lb_policy --- src/core/channel/client_channel.c | 3 +++ src/core/client_config/lb_policies/pick_first.c | 12 ++++++++++-- src/core/client_config/subchannel.c | 4 +++- src/core/iomgr/fd_posix.c | 1 - 4 files changed, 16 insertions(+), 4 deletions(-) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index 6815ec8718..95afc0d2e3 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -436,6 +436,9 @@ static void cc_start_transport_op(grpc_channel_element *elem, GRPC_CHANNEL_FATAL_FAILURE); destroy_resolver = chand->resolver; chand->resolver = NULL; + if (chand->lb_policy != NULL) { + grpc_lb_policy_shutdown(chand->lb_policy); + } } if (!is_empty(op, sizeof(*op))) { diff --git a/src/core/client_config/lb_policies/pick_first.c b/src/core/client_config/lb_policies/pick_first.c index ffdae75b28..3967350a9b 100644 --- a/src/core/client_config/lb_policies/pick_first.c +++ b/src/core/client_config/lb_policies/pick_first.c @@ -85,8 +85,16 @@ void pf_destroy(grpc_lb_policy *pol) { } void pf_shutdown(grpc_lb_policy *pol) { - /* pick_first_lb_policy *p = (pick_first_lb_policy*)pol; */ - abort(); + pick_first_lb_policy *p = (pick_first_lb_policy*)pol; + pending_pick *pp; + gpr_mu_lock(&p->mu); + while ((pp = p->pending_picks)) { + p->pending_picks = pp->next; + *pp->target = NULL; + grpc_iomgr_add_delayed_callback(pp->on_complete, 0); + gpr_free(pp); + } + gpr_mu_unlock(&p->mu); } void pf_pick(grpc_lb_policy *pol, grpc_pollset *pollset, diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c index cde14b9222..05fd02fb0a 100644 --- a/src/core/client_config/subchannel.c +++ b/src/core/client_config/subchannel.c @@ -562,6 +562,9 @@ static void on_alarm(void *arg, int iomgr_success) { grpc_subchannel *c = arg; gpr_mu_lock(&c->mu); c->have_alarm = 0; + if (c->disconnected) { + iomgr_success = 0; + } connectivity_state_changed_locked(c); gpr_mu_unlock(&c->mu); if (iomgr_success) { @@ -609,7 +612,6 @@ static grpc_connectivity_state compute_connectivity_locked(grpc_subchannel *c) { static void connectivity_state_changed_locked(grpc_subchannel *c) { grpc_connectivity_state current = compute_connectivity_locked(c); - gpr_log(GPR_DEBUG, "SUBCHANNEL constate=%d", current); grpc_connectivity_state_set(&c->state_tracker, current); } diff --git a/src/core/iomgr/fd_posix.c b/src/core/iomgr/fd_posix.c index afecccae17..2075c43945 100644 --- a/src/core/iomgr/fd_posix.c +++ b/src/core/iomgr/fd_posix.c @@ -159,7 +159,6 @@ void grpc_fd_global_shutdown(void) { grpc_fd *grpc_fd_create(int fd, const char *name) { grpc_fd *r = alloc_fd(fd); - gpr_log(GPR_DEBUG, "FD %d %p create", r->fd, r); grpc_iomgr_register_object(&r->iomgr_object, name); return r; } -- cgit v1.2.3 From 5d44c069e6870c0ddf26c1782f035c2835983e31 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 1 Jul 2015 08:55:28 -0700 Subject: Refcounting fixes and debugging, empty batch stability fixes --- src/core/channel/client_channel.c | 72 +++++++++++++++++++++--------- src/core/httpcli/httpcli.c | 2 +- src/core/security/client_auth_filter.c | 4 +- src/core/security/secure_transport_setup.c | 4 +- src/core/security/security_connector.c | 36 +++++++++++---- src/core/security/security_connector.h | 23 +++++++--- src/core/security/server_auth_filter.c | 4 +- src/core/security/server_secure_chttp2.c | 4 +- src/core/surface/secure_channel_create.c | 4 ++ 9 files changed, 109 insertions(+), 44 deletions(-) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index 95afc0d2e3..a4de59efb1 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -77,6 +77,7 @@ typedef struct { typedef enum { CALL_CREATED, + CALL_WAITING_FOR_SEND, CALL_WAITING_FOR_CONFIG, CALL_WAITING_FOR_PICK, CALL_WAITING_FOR_CALL, @@ -101,6 +102,9 @@ struct call_data { grpc_linked_mdelem details; }; +static grpc_iomgr_closure *merge_into_waiting_op(grpc_call_element *elem, + grpc_transport_stream_op *new_op) GRPC_MUST_USE_RESULT; + static void handle_op_after_cancellation(grpc_call_element *elem, grpc_transport_stream_op *op) { call_data *calld = elem->call_data; @@ -241,12 +245,13 @@ static void pick_target(grpc_lb_policy *lb_policy, call_data *calld) { &calld->picked_channel, &calld->async_setup_task); } -static void merge_into_waiting_op(grpc_call_element *elem, +static grpc_iomgr_closure *merge_into_waiting_op(grpc_call_element *elem, grpc_transport_stream_op *new_op) { call_data *calld = elem->call_data; + grpc_iomgr_closure *consumed_op = NULL; grpc_transport_stream_op *waiting_op = &calld->waiting_op; - GPR_ASSERT((waiting_op->send_ops == NULL) != (new_op->send_ops == NULL)); - GPR_ASSERT((waiting_op->recv_ops == NULL) != (new_op->recv_ops == NULL)); + GPR_ASSERT((waiting_op->send_ops == NULL) != (new_op->send_ops == NULL) || waiting_op->send_ops == NULL); + GPR_ASSERT((waiting_op->recv_ops == NULL) != (new_op->recv_ops == NULL) || waiting_op->recv_ops == NULL); if (new_op->send_ops != NULL) { waiting_op->send_ops = new_op->send_ops; waiting_op->is_last_send = new_op->is_last_send; @@ -257,13 +262,16 @@ static void merge_into_waiting_op(grpc_call_element *elem, waiting_op->recv_state = new_op->recv_state; waiting_op->on_done_recv = new_op->on_done_recv; } - if (waiting_op->on_consumed == NULL) { + if (new_op->on_consumed != NULL) { + if (waiting_op->on_consumed != NULL) { + consumed_op = waiting_op->on_consumed; + } waiting_op->on_consumed = new_op->on_consumed; - new_op->on_consumed = NULL; } if (new_op->cancel_with_status != GRPC_STATUS_OK) { waiting_op->cancel_with_status = new_op->cancel_with_status; } + return consumed_op; } static void perform_transport_stream_op(grpc_call_element *elem, @@ -274,6 +282,7 @@ static void perform_transport_stream_op(grpc_call_element *elem, grpc_subchannel_call *subchannel_call; grpc_lb_policy *lb_policy; grpc_transport_stream_op op2; + grpc_iomgr_closure *consumed_op = NULL; GPR_ASSERT(elem->filter == &grpc_client_channel_filter); GRPC_CALL_LOG_OP(GPR_INFO, elem, op); @@ -289,6 +298,17 @@ static void perform_transport_stream_op(grpc_call_element *elem, gpr_mu_unlock(&calld->mu_state); handle_op_after_cancellation(elem, op); break; + case CALL_WAITING_FOR_SEND: + GPR_ASSERT(!continuation); + consumed_op = merge_into_waiting_op(elem, op); + if (!calld->waiting_op.send_ops && calld->waiting_op.cancel_with_status == GRPC_STATUS_OK) { + gpr_mu_unlock(&calld->mu_state); + break; + } + *op = calld->waiting_op; + memset(&calld->waiting_op, 0, sizeof(calld->waiting_op)); + continuation = 1; + /* fall through */ case CALL_WAITING_FOR_CONFIG: case CALL_WAITING_FOR_PICK: case CALL_WAITING_FOR_CALL: @@ -308,7 +328,7 @@ static void perform_transport_stream_op(grpc_call_element *elem, handle_op_after_cancellation(elem, op); handle_op_after_cancellation(elem, &op2); } else { - merge_into_waiting_op(elem, op); + consumed_op = merge_into_waiting_op(elem, op); gpr_mu_unlock(&calld->mu_state); if (op->on_consumed != NULL) { op->on_consumed->cb(op->on_consumed->cb_arg, 0); @@ -325,26 +345,37 @@ static void perform_transport_stream_op(grpc_call_element *elem, } else { calld->waiting_op = *op; - gpr_mu_lock(&chand->mu_config); - lb_policy = chand->lb_policy; - if (lb_policy) { - GRPC_LB_POLICY_REF(lb_policy, "pick"); - gpr_mu_unlock(&chand->mu_config); - calld->state = CALL_WAITING_FOR_PICK; + if (op->send_ops == NULL) { + /* need to have some send ops before we can select the + lb target */ + calld->state = CALL_WAITING_FOR_SEND; gpr_mu_unlock(&calld->mu_state); - - pick_target(lb_policy, calld); - - GRPC_LB_POLICY_UNREF(lb_policy, "pick"); } else { - calld->state = CALL_WAITING_FOR_CONFIG; - add_to_lb_policy_wait_queue_locked_state_config(elem); - gpr_mu_unlock(&chand->mu_config); - gpr_mu_unlock(&calld->mu_state); + gpr_mu_lock(&chand->mu_config); + lb_policy = chand->lb_policy; + if (lb_policy) { + GRPC_LB_POLICY_REF(lb_policy, "pick"); + gpr_mu_unlock(&chand->mu_config); + calld->state = CALL_WAITING_FOR_PICK; + gpr_mu_unlock(&calld->mu_state); + + pick_target(lb_policy, calld); + + GRPC_LB_POLICY_UNREF(lb_policy, "pick"); + } else { + calld->state = CALL_WAITING_FOR_CONFIG; + add_to_lb_policy_wait_queue_locked_state_config(elem); + gpr_mu_unlock(&chand->mu_config); + gpr_mu_unlock(&calld->mu_state); + } } } break; } + + if (consumed_op != NULL) { + consumed_op->cb(consumed_op->cb_arg, 1); + } } static void cc_start_transport_stream_op(grpc_call_element *elem, @@ -503,6 +534,7 @@ static void destroy_call_elem(grpc_call_element *elem) { case CALL_WAITING_FOR_PICK: case CALL_WAITING_FOR_CONFIG: case CALL_WAITING_FOR_CALL: + case CALL_WAITING_FOR_SEND: gpr_log(GPR_ERROR, "should never reach here"); abort(); break; diff --git a/src/core/httpcli/httpcli.c b/src/core/httpcli/httpcli.c index 914355a408..3f5557e08e 100644 --- a/src/core/httpcli/httpcli.c +++ b/src/core/httpcli/httpcli.c @@ -198,7 +198,7 @@ static void on_connected(void *arg, grpc_endpoint *tcp) { GRPC_SECURITY_OK); grpc_setup_secure_transport(&sc->base, tcp, on_secure_transport_setup_done, req); - grpc_security_connector_unref(&sc->base); + GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli"); } else { start_write(req); } diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c index 5d04ec49b2..6816fbcfa1 100644 --- a/src/core/security/client_auth_filter.c +++ b/src/core/security/client_auth_filter.c @@ -297,7 +297,7 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, /* initialize members */ GPR_ASSERT(sc->is_client_side); chand->security_connector = - (grpc_channel_security_connector *)grpc_security_connector_ref(sc); + (grpc_channel_security_connector *)GRPC_SECURITY_CONNECTOR_REF(sc, "client_auth_filter"); chand->md_ctx = metadata_context; chand->authority_string = grpc_mdstr_from_string(chand->md_ctx, ":authority"); chand->path_string = grpc_mdstr_from_string(chand->md_ctx, ":path"); @@ -310,7 +310,7 @@ static void destroy_channel_elem(grpc_channel_element *elem) { /* grab pointers to our data from the channel element */ channel_data *chand = elem->channel_data; grpc_channel_security_connector *ctx = chand->security_connector; - if (ctx != NULL) grpc_security_connector_unref(&ctx->base); + if (ctx != NULL) GRPC_SECURITY_CONNECTOR_UNREF(&ctx->base, "client_auth_filter"); if (chand->authority_string != NULL) { grpc_mdstr_unref(chand->authority_string); } diff --git a/src/core/security/secure_transport_setup.c b/src/core/security/secure_transport_setup.c index 1b39ab141e..becc23bf7f 100644 --- a/src/core/security/secure_transport_setup.c +++ b/src/core/security/secure_transport_setup.c @@ -74,7 +74,7 @@ static void secure_transport_setup_done(grpc_secure_transport_setup *s, if (s->handshaker != NULL) tsi_handshaker_destroy(s->handshaker); if (s->handshake_buffer != NULL) gpr_free(s->handshake_buffer); gpr_slice_buffer_destroy(&s->left_overs); - grpc_security_connector_unref(s->connector); + GRPC_SECURITY_CONNECTOR_UNREF(s->connector, "secure_transport_setup"); gpr_free(s); } @@ -275,7 +275,7 @@ void grpc_setup_secure_transport(grpc_security_connector *connector, secure_transport_setup_done(s, 0); return; } - s->connector = grpc_security_connector_ref(connector); + s->connector = GRPC_SECURITY_CONNECTOR_REF(connector, "secure_transport_setup"); s->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE; s->handshake_buffer = gpr_malloc(s->handshake_buffer_size); s->endpoint = nonsecure_endpoint; diff --git a/src/core/security/security_connector.c b/src/core/security/security_connector.c index 34cb0395a2..f53e005d5b 100644 --- a/src/core/security/security_connector.c +++ b/src/core/security/security_connector.c @@ -124,24 +124,42 @@ grpc_security_status grpc_channel_security_connector_check_call_host( return sc->check_call_host(sc, host, cb, user_data); } -void grpc_security_connector_unref(grpc_security_connector *sc) { - if (sc == NULL) return; - if (gpr_unref(&sc->refcount)) sc->vtable->destroy(sc); -} - -grpc_security_connector *grpc_security_connector_ref( - grpc_security_connector *sc) { +#ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG +grpc_security_connector *grpc_security_connector_ref(grpc_security_connector *sc, + const char *file, int line, + const char *reason) { + if (sc == NULL) return NULL; + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "SECURITY_CONNECTOR:%p ref %d -> %d %s", sc, (int)sc->refcount.count, + (int)sc->refcount.count + 1, reason); +#else +grpc_security_connector *grpc_security_connector_ref(grpc_security_connector *sc) { if (sc == NULL) return NULL; +#endif gpr_ref(&sc->refcount); return sc; } +#ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG +void grpc_security_connector_unref(grpc_security_connector *sc, const char *file, int line, + const char *reason) { + if (sc == NULL) return; + gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, + "SECURITY_CONNECTOR:%p unref %d -> %d %s", sc, (int)sc->refcount.count, + (int)sc->refcount.count - 1, reason); +#else +void grpc_security_connector_unref(grpc_security_connector *sc) { + if (sc == NULL) return; +#endif + if (gpr_unref(&sc->refcount)) sc->vtable->destroy(sc); +} + static void connector_pointer_arg_destroy(void *p) { - grpc_security_connector_unref(p); + GRPC_SECURITY_CONNECTOR_UNREF(p, "connector_pointer_arg"); } static void *connector_pointer_arg_copy(void *p) { - return grpc_security_connector_ref(p); + return GRPC_SECURITY_CONNECTOR_REF(p, "connector_pointer_arg"); } grpc_arg grpc_security_connector_to_arg(grpc_security_connector *sc) { diff --git a/src/core/security/security_connector.h b/src/core/security/security_connector.h index ee3057b43b..f258b86b28 100644 --- a/src/core/security/security_connector.h +++ b/src/core/security/security_connector.h @@ -80,12 +80,23 @@ struct grpc_security_connector { grpc_auth_context *auth_context; /* Populated after the peer is checked. */ }; -/* Increments the refcount. */ -grpc_security_connector *grpc_security_connector_ref( - grpc_security_connector *sc); - -/* Decrements the refcount and destroys the object if it reaches 0. */ -void grpc_security_connector_unref(grpc_security_connector *sc); +/* Refcounting. */ +#ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG +#define GRPC_SECURITY_CONNECTOR_REF(p, r) \ + grpc_security_connector_ref((p), __FILE__, __LINE__, (r)) +#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) \ + grpc_security_connector_unref((p), __FILE__, __LINE__, (r)) +grpc_security_connector *grpc_security_connector_ref(grpc_security_connector *policy, + const char *file, int line, + const char *reason); +void grpc_security_connector_unref(grpc_security_connector *policy, const char *file, + int line, const char *reason); +#else +#define GRPC_SECURITY_CONNECTOR_REF(p, r) grpc_security_connector_ref((p)) +#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) grpc_security_connector_unref((p)) +grpc_security_connector *grpc_security_connector_ref(grpc_security_connector *policy); +void grpc_security_connector_unref(grpc_security_connector *policy); +#endif /* Handshake creation. */ grpc_security_status grpc_security_connector_create_handshaker( diff --git a/src/core/security/server_auth_filter.c b/src/core/security/server_auth_filter.c index 5675c06402..51a4b32a66 100644 --- a/src/core/security/server_auth_filter.c +++ b/src/core/security/server_auth_filter.c @@ -107,14 +107,14 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, /* initialize members */ GPR_ASSERT(!sc->is_client_side); - chand->security_connector = grpc_security_connector_ref(sc); + chand->security_connector = GRPC_SECURITY_CONNECTOR_REF(sc, "server_auth_filter"); } /* Destructor for channel data */ static void destroy_channel_elem(grpc_channel_element *elem) { /* grab pointers to our data from the channel element */ channel_data *chand = elem->channel_data; - grpc_security_connector_unref(chand->security_connector); + GRPC_SECURITY_CONNECTOR_UNREF(chand->security_connector, "server_auth_filter"); } const grpc_channel_filter grpc_server_auth_filter = { diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c index 2e49e370f7..6a99324da6 100644 --- a/src/core/security/server_secure_chttp2.c +++ b/src/core/security/server_secure_chttp2.c @@ -70,7 +70,7 @@ static void state_unref(grpc_server_secure_state *state) { gpr_mu_lock(&state->mu); gpr_mu_unlock(&state->mu); /* clean up */ - grpc_security_connector_unref(state->sc); + GRPC_SECURITY_CONNECTOR_UNREF(state->sc, "server"); gpr_free(state); } } @@ -220,7 +220,7 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, /* Error path: cleanup and return */ error: if (sc) { - grpc_security_connector_unref(sc); + GRPC_SECURITY_CONNECTOR_UNREF(sc, "server"); } if (resolved) { grpc_resolved_addresses_destroy(resolved); diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c index 1dd9e61d0f..927c678c67 100644 --- a/src/core/surface/secure_channel_create.c +++ b/src/core/surface/secure_channel_create.c @@ -142,6 +142,7 @@ static void subchannel_factory_ref(grpc_subchannel_factory *scf) { static void subchannel_factory_unref(grpc_subchannel_factory *scf) { subchannel_factory *f = (subchannel_factory *)scf; if (gpr_unref(&f->refs)) { + GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base, "subchannel_factory"); grpc_channel_args_destroy(f->merge_args); grpc_mdctx_unref(f->mdctx); gpr_free(f); @@ -218,6 +219,7 @@ grpc_channel *grpc_secure_channel_create(grpc_credentials *creds, gpr_ref_init(&f->refs, 1); grpc_mdctx_ref(mdctx); f->mdctx = mdctx; + GRPC_SECURITY_CONNECTOR_REF(&connector->base, "subchannel_factory"); f->security_connector = connector; f->merge_args = grpc_channel_args_copy(args_copy); resolver = grpc_resolver_create(target, &f->base); @@ -229,6 +231,8 @@ grpc_channel *grpc_secure_channel_create(grpc_credentials *creds, grpc_client_channel_set_resolver(grpc_channel_get_channel_stack(channel), resolver); GRPC_RESOLVER_UNREF(resolver, "create"); + grpc_subchannel_factory_unref(&f->base); + GRPC_SECURITY_CONNECTOR_UNREF(&connector->base, "channel_create"); grpc_channel_args_destroy(args_copy); if (new_args_from_connector != NULL) { -- cgit v1.2.3 From b9a46ae5d7044c6b436a33341135ead3f6fd7779 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 1 Jul 2015 09:45:21 -0700 Subject: Fix a bug where cancelled calls can be stranded past disconnection --- src/core/channel/client_channel.c | 12 +++++++----- src/core/iomgr/tcp_client_posix.c | 2 -- src/core/surface/call.h | 2 ++ src/core/transport/transport_op_string.c | 7 +++++++ 4 files changed, 16 insertions(+), 7 deletions(-) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index a4de59efb1..5d9331d2c5 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -330,9 +330,6 @@ static void perform_transport_stream_op(grpc_call_element *elem, } else { consumed_op = merge_into_waiting_op(elem, op); gpr_mu_unlock(&calld->mu_state); - if (op->on_consumed != NULL) { - op->on_consumed->cb(op->on_consumed->cb_arg, 0); - } } break; } @@ -362,11 +359,16 @@ static void perform_transport_stream_op(grpc_call_element *elem, pick_target(lb_policy, calld); GRPC_LB_POLICY_UNREF(lb_policy, "pick"); - } else { + } else if (chand->resolver != NULL) { calld->state = CALL_WAITING_FOR_CONFIG; add_to_lb_policy_wait_queue_locked_state_config(elem); gpr_mu_unlock(&chand->mu_config); gpr_mu_unlock(&calld->mu_state); + } else { + calld->state = CALL_CANCELLED; + gpr_mu_unlock(&chand->mu_config); + gpr_mu_unlock(&calld->mu_state); + handle_op_after_cancellation(elem, op); } } } @@ -402,7 +404,7 @@ static void cc_on_config_changed(void *arg, int iomgr_success) { gpr_mu_lock(&chand->mu_config); old_lb_policy = chand->lb_policy; chand->lb_policy = lb_policy; - if (lb_policy != NULL) { + if (lb_policy != NULL || chand->resolver == NULL /* disconnected */) { wakeup_closures = chand->waiting_for_config_closures; chand->waiting_for_config_closures = NULL; } diff --git a/src/core/iomgr/tcp_client_posix.c b/src/core/iomgr/tcp_client_posix.c index 20f833e28b..d981aaf028 100644 --- a/src/core/iomgr/tcp_client_posix.c +++ b/src/core/iomgr/tcp_client_posix.c @@ -166,13 +166,11 @@ static void on_writable(void *acp, int success) { finish: gpr_mu_lock(&ac->mu); - gpr_log(GPR_DEBUG, "ep=%p", ep); if (!ep) { grpc_pollset_set_del_fd(ac->interested_parties, ac->fd); grpc_fd_orphan(ac->fd, NULL, "tcp_client_orphan"); } done = (--ac->refs == 0); - gpr_log(GPR_DEBUG, "refs=%d", ac->refs); gpr_mu_unlock(&ac->mu); if (done) { gpr_mu_destroy(&ac->mu); diff --git a/src/core/surface/call.h b/src/core/surface/call.h index fb3662b50d..8fa411048b 100644 --- a/src/core/surface/call.h +++ b/src/core/surface/call.h @@ -94,6 +94,8 @@ grpc_call *grpc_call_create(grpc_channel *channel, grpc_completion_queue *cq, void grpc_call_set_completion_queue(grpc_call *call, grpc_completion_queue *cq); grpc_completion_queue *grpc_call_get_completion_queue(grpc_call *call); +#define GRPC_CALL_REF_COUNT_DEBUG + #ifdef GRPC_CALL_REF_COUNT_DEBUG void grpc_call_internal_ref(grpc_call *call, const char *reason); void grpc_call_internal_unref(grpc_call *call, const char *reason, diff --git a/src/core/transport/transport_op_string.c b/src/core/transport/transport_op_string.c index 516aa9d4d8..1ffdb5be94 100644 --- a/src/core/transport/transport_op_string.c +++ b/src/core/transport/transport_op_string.c @@ -146,6 +146,13 @@ char *grpc_transport_stream_op_string(grpc_transport_stream_op *op) { gpr_strvec_add(&b, tmp); } + if (op->on_consumed != NULL) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = 0; + gpr_asprintf(&tmp, "ON_CONSUMED:%p", op->on_consumed); + gpr_strvec_add(&b, tmp); + } + out = gpr_strvec_flatten(&b, NULL); gpr_strvec_destroy(&b); -- cgit v1.2.3 From b3671531159b7bbce54c4c3ee4895380a4c968fc Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 1 Jul 2015 10:37:40 -0700 Subject: clang-format changed files --- src/core/channel/client_channel.c | 20 ++++++++------ src/core/client_config/lb_policies/pick_first.c | 2 +- src/core/security/client_auth_filter.c | 6 +++-- src/core/security/secure_transport_setup.c | 8 +++--- src/core/security/security_connector.c | 35 ++++++++++++++----------- src/core/security/security_connector.h | 24 +++++++++-------- src/core/security/server_auth_filter.c | 6 +++-- src/core/surface/secure_channel_create.c | 3 ++- src/core/transport/chttp2/stream_lists.c | 4 ++- src/core/transport/chttp2_transport.c | 12 ++++++--- 10 files changed, 71 insertions(+), 49 deletions(-) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index 5d9331d2c5..384724d315 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -102,8 +102,9 @@ struct call_data { grpc_linked_mdelem details; }; -static grpc_iomgr_closure *merge_into_waiting_op(grpc_call_element *elem, - grpc_transport_stream_op *new_op) GRPC_MUST_USE_RESULT; +static grpc_iomgr_closure *merge_into_waiting_op( + grpc_call_element *elem, + grpc_transport_stream_op *new_op) GRPC_MUST_USE_RESULT; static void handle_op_after_cancellation(grpc_call_element *elem, grpc_transport_stream_op *op) { @@ -245,13 +246,15 @@ static void pick_target(grpc_lb_policy *lb_policy, call_data *calld) { &calld->picked_channel, &calld->async_setup_task); } -static grpc_iomgr_closure *merge_into_waiting_op(grpc_call_element *elem, - grpc_transport_stream_op *new_op) { +static grpc_iomgr_closure *merge_into_waiting_op( + grpc_call_element *elem, grpc_transport_stream_op *new_op) { call_data *calld = elem->call_data; grpc_iomgr_closure *consumed_op = NULL; grpc_transport_stream_op *waiting_op = &calld->waiting_op; - GPR_ASSERT((waiting_op->send_ops == NULL) != (new_op->send_ops == NULL) || waiting_op->send_ops == NULL); - GPR_ASSERT((waiting_op->recv_ops == NULL) != (new_op->recv_ops == NULL) || waiting_op->recv_ops == NULL); + GPR_ASSERT((waiting_op->send_ops == NULL) != (new_op->send_ops == NULL) || + waiting_op->send_ops == NULL); + GPR_ASSERT((waiting_op->recv_ops == NULL) != (new_op->recv_ops == NULL) || + waiting_op->recv_ops == NULL); if (new_op->send_ops != NULL) { waiting_op->send_ops = new_op->send_ops; waiting_op->is_last_send = new_op->is_last_send; @@ -301,14 +304,15 @@ static void perform_transport_stream_op(grpc_call_element *elem, case CALL_WAITING_FOR_SEND: GPR_ASSERT(!continuation); consumed_op = merge_into_waiting_op(elem, op); - if (!calld->waiting_op.send_ops && calld->waiting_op.cancel_with_status == GRPC_STATUS_OK) { + if (!calld->waiting_op.send_ops && + calld->waiting_op.cancel_with_status == GRPC_STATUS_OK) { gpr_mu_unlock(&calld->mu_state); break; } *op = calld->waiting_op; memset(&calld->waiting_op, 0, sizeof(calld->waiting_op)); continuation = 1; - /* fall through */ + /* fall through */ case CALL_WAITING_FOR_CONFIG: case CALL_WAITING_FOR_PICK: case CALL_WAITING_FOR_CALL: diff --git a/src/core/client_config/lb_policies/pick_first.c b/src/core/client_config/lb_policies/pick_first.c index ec2a45a572..3d57e3136a 100644 --- a/src/core/client_config/lb_policies/pick_first.c +++ b/src/core/client_config/lb_policies/pick_first.c @@ -85,7 +85,7 @@ void pf_destroy(grpc_lb_policy *pol) { } void pf_shutdown(grpc_lb_policy *pol) { - pick_first_lb_policy *p = (pick_first_lb_policy*)pol; + pick_first_lb_policy *p = (pick_first_lb_policy *)pol; pending_pick *pp; gpr_mu_lock(&p->mu); while ((pp = p->pending_picks)) { diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c index 6816fbcfa1..f8d18d9b17 100644 --- a/src/core/security/client_auth_filter.c +++ b/src/core/security/client_auth_filter.c @@ -297,7 +297,8 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, /* initialize members */ GPR_ASSERT(sc->is_client_side); chand->security_connector = - (grpc_channel_security_connector *)GRPC_SECURITY_CONNECTOR_REF(sc, "client_auth_filter"); + (grpc_channel_security_connector *)GRPC_SECURITY_CONNECTOR_REF( + sc, "client_auth_filter"); chand->md_ctx = metadata_context; chand->authority_string = grpc_mdstr_from_string(chand->md_ctx, ":authority"); chand->path_string = grpc_mdstr_from_string(chand->md_ctx, ":path"); @@ -310,7 +311,8 @@ static void destroy_channel_elem(grpc_channel_element *elem) { /* grab pointers to our data from the channel element */ channel_data *chand = elem->channel_data; grpc_channel_security_connector *ctx = chand->security_connector; - if (ctx != NULL) GRPC_SECURITY_CONNECTOR_UNREF(&ctx->base, "client_auth_filter"); + if (ctx != NULL) + GRPC_SECURITY_CONNECTOR_UNREF(&ctx->base, "client_auth_filter"); if (chand->authority_string != NULL) { grpc_mdstr_unref(chand->authority_string); } diff --git a/src/core/security/secure_transport_setup.c b/src/core/security/secure_transport_setup.c index becc23bf7f..731b382f09 100644 --- a/src/core/security/secure_transport_setup.c +++ b/src/core/security/secure_transport_setup.c @@ -234,8 +234,9 @@ static void on_handshake_data_received_from_peer( gpr_slice_split_tail(&slices[i], consumed_slice_size)); gpr_slice_unref(slices[i]); /* split_tail above increments refcount. */ } - gpr_slice_buffer_addn(&s->left_overs, &slices[i + 1], - num_left_overs - (size_t)has_left_overs_in_current_slice); + gpr_slice_buffer_addn( + &s->left_overs, &slices[i + 1], + num_left_overs - (size_t)has_left_overs_in_current_slice); check_peer(s); } @@ -275,7 +276,8 @@ void grpc_setup_secure_transport(grpc_security_connector *connector, secure_transport_setup_done(s, 0); return; } - s->connector = GRPC_SECURITY_CONNECTOR_REF(connector, "secure_transport_setup"); + s->connector = + GRPC_SECURITY_CONNECTOR_REF(connector, "secure_transport_setup"); s->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE; s->handshake_buffer = gpr_malloc(s->handshake_buffer_size); s->endpoint = nonsecure_endpoint; diff --git a/src/core/security/security_connector.c b/src/core/security/security_connector.c index f53e005d5b..f6e423eb27 100644 --- a/src/core/security/security_connector.c +++ b/src/core/security/security_connector.c @@ -84,12 +84,12 @@ static const char *ssl_cipher_suites(void) { /* -- Common methods. -- */ /* Returns the first property with that name. */ -const tsi_peer_property *tsi_peer_get_property_by_name( - const tsi_peer *peer, const char *name) { +const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer, + const char *name) { size_t i; if (peer == NULL) return NULL; for (i = 0; i < peer->property_count; i++) { - const tsi_peer_property* property = &peer->properties[i]; + const tsi_peer_property *property = &peer->properties[i]; if (name == NULL && property->name == NULL) { return property; } @@ -125,15 +125,16 @@ grpc_security_status grpc_channel_security_connector_check_call_host( } #ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG -grpc_security_connector *grpc_security_connector_ref(grpc_security_connector *sc, - const char *file, int line, - const char *reason) { +grpc_security_connector *grpc_security_connector_ref( + grpc_security_connector *sc, const char *file, int line, + const char *reason) { if (sc == NULL) return NULL; gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "SECURITY_CONNECTOR:%p ref %d -> %d %s", sc, (int)sc->refcount.count, - (int)sc->refcount.count + 1, reason); + "SECURITY_CONNECTOR:%p ref %d -> %d %s", sc, + (int)sc->refcount.count, (int)sc->refcount.count + 1, reason); #else -grpc_security_connector *grpc_security_connector_ref(grpc_security_connector *sc) { +grpc_security_connector *grpc_security_connector_ref( + grpc_security_connector *sc) { if (sc == NULL) return NULL; #endif gpr_ref(&sc->refcount); @@ -141,12 +142,13 @@ grpc_security_connector *grpc_security_connector_ref(grpc_security_connector *sc } #ifdef GRPC_SECURITY_CONNECTOR_REFCOUNT_DEBUG -void grpc_security_connector_unref(grpc_security_connector *sc, const char *file, int line, - const char *reason) { +void grpc_security_connector_unref(grpc_security_connector *sc, + const char *file, int line, + const char *reason) { if (sc == NULL) return; gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG, - "SECURITY_CONNECTOR:%p unref %d -> %d %s", sc, (int)sc->refcount.count, - (int)sc->refcount.count - 1, reason); + "SECURITY_CONNECTOR:%p unref %d -> %d %s", sc, + (int)sc->refcount.count, (int)sc->refcount.count - 1, reason); #else void grpc_security_connector_unref(grpc_security_connector *sc) { if (sc == NULL) return; @@ -598,7 +600,8 @@ grpc_security_status grpc_ssl_channel_security_connector_create( config->pem_private_key, config->pem_private_key_size, config->pem_cert_chain, config->pem_cert_chain_size, pem_root_certs, pem_root_certs_size, ssl_cipher_suites(), alpn_protocol_strings, - alpn_protocol_string_lengths, (uint16_t)num_alpn_protocols, &c->handshaker_factory); + alpn_protocol_string_lengths, (uint16_t)num_alpn_protocols, + &c->handshaker_factory); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", tsi_result_to_string(result)); @@ -651,8 +654,8 @@ grpc_security_status grpc_ssl_server_security_connector_create( (const unsigned char **)config->pem_cert_chains, config->pem_cert_chains_sizes, config->num_key_cert_pairs, config->pem_root_certs, config->pem_root_certs_size, ssl_cipher_suites(), - alpn_protocol_strings, alpn_protocol_string_lengths, (uint16_t)num_alpn_protocols, - &c->handshaker_factory); + alpn_protocol_strings, alpn_protocol_string_lengths, + (uint16_t)num_alpn_protocols, &c->handshaker_factory); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", tsi_result_to_string(result)); diff --git a/src/core/security/security_connector.h b/src/core/security/security_connector.h index f258b86b28..a4c723f026 100644 --- a/src/core/security/security_connector.h +++ b/src/core/security/security_connector.h @@ -86,15 +86,17 @@ struct grpc_security_connector { grpc_security_connector_ref((p), __FILE__, __LINE__, (r)) #define GRPC_SECURITY_CONNECTOR_UNREF(p, r) \ grpc_security_connector_unref((p), __FILE__, __LINE__, (r)) -grpc_security_connector *grpc_security_connector_ref(grpc_security_connector *policy, - const char *file, int line, - const char *reason); -void grpc_security_connector_unref(grpc_security_connector *policy, const char *file, - int line, const char *reason); +grpc_security_connector *grpc_security_connector_ref( + grpc_security_connector *policy, const char *file, int line, + const char *reason); +void grpc_security_connector_unref(grpc_security_connector *policy, + const char *file, int line, + const char *reason); #else #define GRPC_SECURITY_CONNECTOR_REF(p, r) grpc_security_connector_ref((p)) #define GRPC_SECURITY_CONNECTOR_UNREF(p, r) grpc_security_connector_unref((p)) -grpc_security_connector *grpc_security_connector_ref(grpc_security_connector *policy); +grpc_security_connector *grpc_security_connector_ref( + grpc_security_connector *policy); void grpc_security_connector_unref(grpc_security_connector *policy); #endif @@ -183,9 +185,9 @@ typedef struct { specific error code otherwise. */ grpc_security_status grpc_ssl_channel_security_connector_create( - grpc_credentials *request_metadata_creds, - const grpc_ssl_config *config, const char *target_name, - const char *overridden_target_name, grpc_channel_security_connector **sc); + grpc_credentials *request_metadata_creds, const grpc_ssl_config *config, + const char *target_name, const char *overridden_target_name, + grpc_channel_security_connector **sc); /* Gets the default ssl roots. */ size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs); @@ -211,8 +213,8 @@ grpc_security_status grpc_ssl_server_security_connector_create( const grpc_ssl_server_config *config, grpc_security_connector **sc); /* Util. */ -const tsi_peer_property *tsi_peer_get_property_by_name( - const tsi_peer *peer, const char *name); +const tsi_peer_property *tsi_peer_get_property_by_name(const tsi_peer *peer, + const char *name); /* Exposed for testing only. */ grpc_auth_context *tsi_ssl_peer_to_auth_context(const tsi_peer *peer); diff --git a/src/core/security/server_auth_filter.c b/src/core/security/server_auth_filter.c index 51a4b32a66..10eef6d237 100644 --- a/src/core/security/server_auth_filter.c +++ b/src/core/security/server_auth_filter.c @@ -107,14 +107,16 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, /* initialize members */ GPR_ASSERT(!sc->is_client_side); - chand->security_connector = GRPC_SECURITY_CONNECTOR_REF(sc, "server_auth_filter"); + chand->security_connector = + GRPC_SECURITY_CONNECTOR_REF(sc, "server_auth_filter"); } /* Destructor for channel data */ static void destroy_channel_elem(grpc_channel_element *elem) { /* grab pointers to our data from the channel element */ channel_data *chand = elem->channel_data; - GRPC_SECURITY_CONNECTOR_UNREF(chand->security_connector, "server_auth_filter"); + GRPC_SECURITY_CONNECTOR_UNREF(chand->security_connector, + "server_auth_filter"); } const grpc_channel_filter grpc_server_auth_filter = { diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c index 927c678c67..76fc862621 100644 --- a/src/core/surface/secure_channel_create.c +++ b/src/core/surface/secure_channel_create.c @@ -142,7 +142,8 @@ static void subchannel_factory_ref(grpc_subchannel_factory *scf) { static void subchannel_factory_unref(grpc_subchannel_factory *scf) { subchannel_factory *f = (subchannel_factory *)scf; if (gpr_unref(&f->refs)) { - GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base, "subchannel_factory"); + GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base, + "subchannel_factory"); grpc_channel_args_destroy(f->merge_args); grpc_mdctx_unref(f->mdctx); gpr_free(f); diff --git a/src/core/transport/chttp2/stream_lists.c b/src/core/transport/chttp2/stream_lists.c index f04e763387..85691b32d2 100644 --- a/src/core/transport/chttp2/stream_lists.c +++ b/src/core/transport/chttp2/stream_lists.c @@ -222,7 +222,9 @@ int grpc_chttp2_list_pop_writable_window_update_stream( void grpc_chttp2_list_remove_writable_window_update_stream( grpc_chttp2_transport_global *transport_global, grpc_chttp2_stream_global *stream_global) { - stream_list_maybe_remove(TRANSPORT_FROM_GLOBAL(transport_global), STREAM_FROM_GLOBAL(stream_global), GRPC_CHTTP2_LIST_WRITABLE_WINDOW_UPDATE); + stream_list_maybe_remove(TRANSPORT_FROM_GLOBAL(transport_global), + STREAM_FROM_GLOBAL(stream_global), + GRPC_CHTTP2_LIST_WRITABLE_WINDOW_UPDATE); } void grpc_chttp2_list_add_parsing_seen_stream( diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c index a7f9af5c0c..0a7b8f5bf9 100644 --- a/src/core/transport/chttp2_transport.c +++ b/src/core/transport/chttp2_transport.c @@ -766,16 +766,20 @@ static void unlock_check_read_write_state(grpc_chttp2_transport *t) { } if (!t->writing_active) { - while (grpc_chttp2_list_pop_cancelled_waiting_for_writing(transport_global, &stream_global)) { - grpc_chttp2_list_add_read_write_state_changed(transport_global, stream_global); + while (grpc_chttp2_list_pop_cancelled_waiting_for_writing(transport_global, + &stream_global)) { + grpc_chttp2_list_add_read_write_state_changed(transport_global, + stream_global); } } while (grpc_chttp2_list_pop_read_write_state_changed(transport_global, &stream_global)) { if (stream_global->cancelled) { - if (t->writing_active && stream_global->write_state != GRPC_WRITE_STATE_SENT_CLOSE) { - grpc_chttp2_list_add_cancelled_waiting_for_writing(transport_global, stream_global); + if (t->writing_active && + stream_global->write_state != GRPC_WRITE_STATE_SENT_CLOSE) { + grpc_chttp2_list_add_cancelled_waiting_for_writing(transport_global, + stream_global); } else { stream_global->write_state = GRPC_WRITE_STATE_SENT_CLOSE; stream_global->read_closed = 1; -- cgit v1.2.3 From 62b1473a0d49cbbcfa16b15109cf1597673a3d65 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 1 Jul 2015 11:28:41 -0700 Subject: Add missing unlock --- src/core/channel/client_channel.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index 384724d315..61fc4222d1 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -202,6 +202,7 @@ static void started_call(void *arg, int iomgr_success) { } } else { GPR_ASSERT(calld->state == CALL_CANCELLED); + gpr_mu_unlock(&calld->mu_state); } } -- cgit v1.2.3 From 2e9dc506e70b351c341ffac31abcd9d2de858172 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 1 Jul 2015 11:31:07 -0700 Subject: Simplify check --- src/core/channel/client_channel.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index 61fc4222d1..1eab87d714 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -252,10 +252,8 @@ static grpc_iomgr_closure *merge_into_waiting_op( call_data *calld = elem->call_data; grpc_iomgr_closure *consumed_op = NULL; grpc_transport_stream_op *waiting_op = &calld->waiting_op; - GPR_ASSERT((waiting_op->send_ops == NULL) != (new_op->send_ops == NULL) || - waiting_op->send_ops == NULL); - GPR_ASSERT((waiting_op->recv_ops == NULL) != (new_op->recv_ops == NULL) || - waiting_op->recv_ops == NULL); + GPR_ASSERT((waiting_op->send_ops != NULL) + (new_op->send_ops != NULL) <= 1); + GPR_ASSERT((waiting_op->recv_ops != NULL) + (new_op->recv_ops != NULL) <= 1); if (new_op->send_ops != NULL) { waiting_op->send_ops = new_op->send_ops; waiting_op->is_last_send = new_op->is_last_send; -- cgit v1.2.3 From 9d94b60c0ab3a945576ef0cf7385be8eea6c99e2 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 1 Jul 2015 14:23:18 -0700 Subject: Expand comment --- src/core/channel/client_channel.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index 1eab87d714..e05bda7f2d 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -60,7 +60,8 @@ typedef struct { /** master channel */ grpc_channel *master; - /** mutex protecting client configuration, resolution state */ + /** mutex protecting client configuration, including all + variables below in this data structure */ gpr_mu mu_config; /** currently active load balancer - guarded by mu_config */ grpc_lb_policy *lb_policy; -- cgit v1.2.3 From 50bc609f6e4395ff87ff6d7f5223f625e4360831 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 1 Jul 2015 14:25:19 -0700 Subject: Expand comment --- src/core/channel/client_channel.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/core/channel/client_channel.c') diff --git a/src/core/channel/client_channel.c b/src/core/channel/client_channel.c index e05bda7f2d..871e970eb8 100644 --- a/src/core/channel/client_channel.c +++ b/src/core/channel/client_channel.c @@ -57,7 +57,10 @@ typedef struct { grpc_mdctx *mdctx; /** resolver for this channel */ grpc_resolver *resolver; - /** master channel */ + /** master channel - the grpc_channel instance that ultimately owns + this channel_data via its channel stack. + We occasionally use this to bump the refcount on the master channel + to keep ourselves alive through an asynchronous operation. */ grpc_channel *master; /** mutex protecting client configuration, including all -- cgit v1.2.3