Fix error handling in channel initialization.

pull/8795/head
Mark D. Roth 8 years ago
parent 494790b84e
commit e62605f41e
  1. 21
      src/core/lib/channel/channel_stack_builder.c
  2. 113
      src/core/lib/surface/channel.c
  3. 12
      test/core/surface/channel_create_test.c

@ -259,14 +259,21 @@ grpc_error *grpc_channel_stack_builder_finish(
destroy_arg == NULL ? *result : destroy_arg, filters, num_filters, destroy_arg == NULL ? *result : destroy_arg, filters, num_filters,
builder->args, builder->transport, builder->name, channel_stack); builder->args, builder->transport, builder->name, channel_stack);
// run post-initialization functions if (error != GRPC_ERROR_NONE) {
i = 0; grpc_channel_stack_destroy(exec_ctx, channel_stack);
for (filter_node *p = builder->begin.next; p != &builder->end; p = p->next) { gpr_free(*result);
if (p->init != NULL) { *result = NULL;
p->init(channel_stack, grpc_channel_stack_element(channel_stack, i), } else {
p->init_arg); // run post-initialization functions
i = 0;
for (filter_node *p = builder->begin.next; p != &builder->end;\
p = p->next) {
if (p->init != NULL) {
p->init(channel_stack, grpc_channel_stack_element(channel_stack, i),
p->init_arg);
}
i++;
} }
i++;
} }
grpc_channel_stack_builder_destroy(builder); grpc_channel_stack_builder_destroy(builder);

@ -86,92 +86,91 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
const grpc_channel_args *input_args, const grpc_channel_args *input_args,
grpc_channel_stack_type channel_stack_type, grpc_channel_stack_type channel_stack_type,
grpc_transport *optional_transport) { grpc_transport *optional_transport) {
bool is_client = grpc_channel_stack_type_is_client(channel_stack_type);
grpc_channel_stack_builder *builder = grpc_channel_stack_builder_create(); 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_channel_arguments(builder, input_args);
grpc_channel_stack_builder_set_target(builder, target); grpc_channel_stack_builder_set_target(builder, target);
grpc_channel_stack_builder_set_transport(builder, optional_transport); 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)) { if (!grpc_channel_init_create_stack(exec_ctx, builder, channel_stack_type)) {
grpc_channel_stack_builder_destroy(builder); grpc_channel_stack_builder_destroy(builder);
return NULL; return NULL;
} }
args = grpc_channel_args_copy( grpc_channel_args *args = grpc_channel_args_copy(
grpc_channel_stack_builder_get_channel_arguments(builder)); grpc_channel_stack_builder_get_channel_arguments(builder));
grpc_channel *channel;
grpc_error *error = grpc_channel_stack_builder_finish( grpc_error *error = grpc_channel_stack_builder_finish(
exec_ctx, builder, sizeof(grpc_channel), 1, destroy_channel, NULL, exec_ctx, builder, sizeof(grpc_channel), 1, destroy_channel, NULL,
(void **)&channel); (void **)&channel);
if (error != GRPC_ERROR_NONE) { if (error != GRPC_ERROR_NONE) {
grpc_channel_stack_destroy(exec_ctx, (grpc_channel_stack *)channel); const char* msg = grpc_error_string(error);
gpr_free(channel); gpr_log(GPR_ERROR, "channel stack builder failed: %s", msg);
return NULL; grpc_error_free_string(msg);
GRPC_ERROR_UNREF(error);
goto done;
} }
memset(channel, 0, sizeof(*channel)); memset(channel, 0, sizeof(*channel));
channel->target = gpr_strdup(target); channel->target = gpr_strdup(target);
channel->is_client = is_client; channel->is_client = grpc_channel_stack_type_is_client(channel_stack_type);
gpr_mu_init(&channel->registered_call_mu); gpr_mu_init(&channel->registered_call_mu);
channel->registered_calls = NULL; channel->registered_calls = NULL;
grpc_compression_options_init(&channel->compression_options); grpc_compression_options_init(&channel->compression_options);
if (args) {
for (size_t i = 0; i < args->num_args; i++) { for (size_t i = 0; i < args->num_args; i++) {
if (0 == strcmp(args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) { if (0 == strcmp(args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) {
if (args->args[i].type != GRPC_ARG_STRING) { if (args->args[i].type != GRPC_ARG_STRING) {
gpr_log(GPR_ERROR, "%s ignored: it must be a string", gpr_log(GPR_ERROR, "%s ignored: it must be a string",
GRPC_ARG_DEFAULT_AUTHORITY); GRPC_ARG_DEFAULT_AUTHORITY);
} else { } else {
if (channel->default_authority) { if (channel->default_authority) {
/* setting this takes precedence over anything else */ /* setting this takes precedence over anything else */
GRPC_MDELEM_UNREF(channel->default_authority); GRPC_MDELEM_UNREF(channel->default_authority);
}
channel->default_authority = grpc_mdelem_from_strings(
":authority", args->args[i].value.string);
} }
} else if (0 == channel->default_authority = grpc_mdelem_from_strings(
strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) { ":authority", args->args[i].value.string);
if (args->args[i].type != GRPC_ARG_STRING) { }
gpr_log(GPR_ERROR, "%s ignored: it must be a string", } else if (0 ==
strcmp(args->args[i].key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)) {
if (args->args[i].type != GRPC_ARG_STRING) {
gpr_log(GPR_ERROR, "%s ignored: it must be a string",
GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
} else {
if (channel->default_authority) {
/* other ways of setting this (notably ssl) take precedence */
gpr_log(GPR_ERROR,
"%s ignored: default host already set some other way",
GRPC_SSL_TARGET_NAME_OVERRIDE_ARG); GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
} else { } else {
if (channel->default_authority) { channel->default_authority = grpc_mdelem_from_strings(
/* other ways of setting this (notably ssl) take precedence */ ":authority", args->args[i].value.string);
gpr_log(GPR_ERROR,
"%s ignored: default host already set some other way",
GRPC_SSL_TARGET_NAME_OVERRIDE_ARG);
} else {
channel->default_authority = grpc_mdelem_from_strings(
":authority", args->args[i].value.string);
}
} }
} else if (0 == strcmp(args->args[i].key,
GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL)) {
channel->compression_options.default_level.is_set = true;
GPR_ASSERT(args->args[i].value.integer >= 0 &&
args->args[i].value.integer < GRPC_COMPRESS_LEVEL_COUNT);
channel->compression_options.default_level.level =
(grpc_compression_level)args->args[i].value.integer;
} else if (0 == strcmp(args->args[i].key,
GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM)) {
channel->compression_options.default_algorithm.is_set = true;
GPR_ASSERT(args->args[i].value.integer >= 0 &&
args->args[i].value.integer <
GRPC_COMPRESS_ALGORITHMS_COUNT);
channel->compression_options.default_algorithm.algorithm =
(grpc_compression_algorithm)args->args[i].value.integer;
} else if (0 ==
strcmp(args->args[i].key,
GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET)) {
channel->compression_options.enabled_algorithms_bitset =
(uint32_t)args->args[i].value.integer |
0x1; /* always support no compression */
} }
} else if (0 == strcmp(args->args[i].key,
GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL)) {
channel->compression_options.default_level.is_set = true;
GPR_ASSERT(args->args[i].value.integer >= 0 &&
args->args[i].value.integer < GRPC_COMPRESS_LEVEL_COUNT);
channel->compression_options.default_level.level =
(grpc_compression_level)args->args[i].value.integer;
} else if (0 == strcmp(args->args[i].key,
GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM)) {
channel->compression_options.default_algorithm.is_set = true;
GPR_ASSERT(args->args[i].value.integer >= 0 &&
args->args[i].value.integer <
GRPC_COMPRESS_ALGORITHMS_COUNT);
channel->compression_options.default_algorithm.algorithm =
(grpc_compression_algorithm)args->args[i].value.integer;
} else if (0 ==
strcmp(args->args[i].key,
GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET)) {
channel->compression_options.enabled_algorithms_bitset =
(uint32_t)args->args[i].value.integer |
0x1; /* always support no compression */
} }
grpc_channel_args_destroy(args);
} }
done:
grpc_channel_args_destroy(args);
return channel; return channel;
} }

@ -31,9 +31,14 @@
* *
*/ */
#include <string.h>
#include <grpc/grpc.h> #include <grpc/grpc.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include "src/core/ext/client_channel/resolver_registry.h" #include "src/core/ext/client_channel/resolver_registry.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/surface/channel.h"
#include "test/core/util/test_config.h" #include "test/core/util/test_config.h"
void test_unknown_scheme_target(void) { void test_unknown_scheme_target(void) {
@ -44,6 +49,13 @@ void test_unknown_scheme_target(void) {
chan = grpc_insecure_channel_create("blah://blah", NULL, NULL); chan = grpc_insecure_channel_create("blah://blah", NULL, NULL);
GPR_ASSERT(chan != NULL); GPR_ASSERT(chan != NULL);
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
grpc_channel_element *elem =
grpc_channel_stack_element(grpc_channel_get_channel_stack(chan), 0);
GPR_ASSERT(0 == strcmp(elem->filter->name, "lame-client"));
grpc_exec_ctx_finish(&exec_ctx);
grpc_channel_destroy(chan); grpc_channel_destroy(chan);
} }

Loading…
Cancel
Save