diff --git a/src/core/ext/client_config/subchannel.c b/src/core/ext/client_config/subchannel.c index 4d74eb9811d..125a291f211 100644 --- a/src/core/ext/client_config/subchannel.c +++ b/src/core/ext/client_config/subchannel.c @@ -546,9 +546,20 @@ static void publish_transport_locked(grpc_exec_ctx *exec_ctx, state_watcher *sw_subchannel; /* construct channel stack */ - con = grpc_channel_init_create_stack( - exec_ctx, GRPC_CLIENT_SUBCHANNEL, 0, c->connecting_result.channel_args, 1, - connection_destroy, NULL, c->connecting_result.transport, NULL); + grpc_channel_stack_builder *builder = grpc_channel_stack_builder_create(); + grpc_channel_stack_builder_set_channel_arguments( + builder, c->connecting_result.channel_args); + grpc_channel_stack_builder_set_transport(builder, + c->connecting_result.transport); + + if (grpc_channel_init_create_stack(exec_ctx, builder, + GRPC_CLIENT_SUBCHANNEL)) { + con = grpc_channel_stack_builder_finish(exec_ctx, builder, 0, 1, + connection_destroy, NULL); + } else { + grpc_channel_stack_builder_destroy(builder); + abort(); /* TODO(ctiller): what to do here (previously we just crashed) */ + } stk = CHANNEL_STACK_FROM_CONNECTION(con); memset(&c->connecting_result, 0, sizeof(c->connecting_result)); @@ -576,7 +587,8 @@ static void publish_transport_locked(grpc_exec_ctx *exec_ctx, GPR_ASSERT(gpr_atm_rel_cas(&c->connected_subchannel, 0, (gpr_atm)con)); c->connecting = 0; - /* setup subchannel watching connected subchannel for changes; subchannel ref + /* setup subchannel watching connected subchannel for changes; subchannel + ref for connecting is donated to the state watcher */ GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher"); diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c index b805091b476..b6b760b5d8d 100644 --- a/src/core/lib/surface/channel.c +++ b/src/core/lib/surface/channel.c @@ -83,14 +83,26 @@ struct grpc_channel { static void destroy_channel(grpc_exec_ctx *exec_ctx, void *arg, bool success); grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target, - const grpc_channel_args *args, + const grpc_channel_args *input_args, grpc_channel_stack_type channel_stack_type, grpc_transport *optional_transport) { bool is_client = grpc_channel_stack_type_is_client(channel_stack_type); - grpc_channel *channel = grpc_channel_init_create_stack( - exec_ctx, channel_stack_type, sizeof(grpc_channel), args, 1, - destroy_channel, NULL, optional_transport, target); + grpc_channel_stack_builder *builder = grpc_channel_stack_builder_create(); + grpc_channel_stack_builder_set_channel_arguments(builder, input_args); + grpc_channel_stack_builder_set_target(builder, target); + grpc_channel_stack_builder_set_transport(builder, optional_transport); + grpc_channel *channel; + grpc_channel_args *args; + if (!grpc_channel_init_create_stack(exec_ctx, builder, channel_stack_type)) { + grpc_channel_stack_builder_destroy(builder); + return NULL; + } else { + args = grpc_channel_args_copy( + grpc_channel_stack_builder_get_channel_arguments(builder)); + channel = grpc_channel_stack_builder_finish( + exec_ctx, builder, sizeof(grpc_channel), 1, destroy_channel, NULL); + } memset(channel, 0, sizeof(*channel)); channel->target = gpr_strdup(target); @@ -141,6 +153,7 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target, } } } + grpc_channel_args_destroy(args); } return channel; diff --git a/src/core/lib/surface/channel_init.c b/src/core/lib/surface/channel_init.c index d0dd722ae0e..0627b344791 100644 --- a/src/core/lib/surface/channel_init.c +++ b/src/core/lib/surface/channel_init.c @@ -122,26 +122,19 @@ static const char *name_for_type(grpc_channel_stack_type type) { GPR_UNREACHABLE_CODE(return "UNKNOWN"); } -void *grpc_channel_init_create_stack( - grpc_exec_ctx *exec_ctx, grpc_channel_stack_type type, size_t prefix_bytes, - const grpc_channel_args *args, int initial_refs, grpc_iomgr_cb_func destroy, - void *destroy_arg, grpc_transport *transport, const char *target) { +bool grpc_channel_init_create_stack(grpc_exec_ctx *exec_ctx, + grpc_channel_stack_builder *builder, + grpc_channel_stack_type type) { GPR_ASSERT(g_finalized); - grpc_channel_stack_builder *builder = grpc_channel_stack_builder_create(); grpc_channel_stack_builder_set_name(builder, name_for_type(type)); - grpc_channel_stack_builder_set_channel_arguments(builder, args); - grpc_channel_stack_builder_set_transport(builder, transport); - grpc_channel_stack_builder_set_target(builder, target); for (size_t i = 0; i < g_slots[type].num_slots; i++) { const stage_slot *slot = &g_slots[type].slots[i]; if (!slot->fn(builder, slot->arg)) { - grpc_channel_stack_builder_destroy(builder); - return NULL; + return false; } } - return grpc_channel_stack_builder_finish(exec_ctx, builder, prefix_bytes, - initial_refs, destroy, destroy_arg); + return true; } diff --git a/src/core/lib/surface/channel_init.h b/src/core/lib/surface/channel_init.h index cb71ae3b7ca..3a18a61ddb8 100644 --- a/src/core/lib/surface/channel_init.h +++ b/src/core/lib/surface/channel_init.h @@ -80,10 +80,8 @@ void grpc_channel_init_shutdown(void); /// \a optional_transport is either NULL or a constructed transport object /// Returns a pointer to the base of the memory allocated (the actual channel /// stack object will be prefix_bytes past that pointer) -void *grpc_channel_init_create_stack( - grpc_exec_ctx *exec_ctx, grpc_channel_stack_type type, size_t prefix_bytes, - const grpc_channel_args *args, int initial_refs, grpc_iomgr_cb_func destroy, - void *destroy_arg, grpc_transport *optional_transport, - const char *optional_target); +bool grpc_channel_init_create_stack(grpc_exec_ctx *exec_ctx, + grpc_channel_stack_builder *builder, + grpc_channel_stack_type type); #endif /* GRPC_CORE_LIB_SURFACE_CHANNEL_INIT_H */