Merge remote-tracking branch 'upstream/master' into client_channel_init_cleanup
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index da1bd9d..c86f7ec 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -213,6 +213,8 @@
#define GRPC_ARG_SERVICE_CONFIG "grpc.service_config"
/** LB policy name. */
#define GRPC_ARG_LB_POLICY_NAME "grpc.lb_policy_name"
+/** Server URI. Not intended for external use. */
+#define GRPC_ARG_SERVER_URI "grpc.server_uri"
/** Server name. Not intended for external use. */
#define GRPC_ARG_SERVER_NAME "grpc.server_name"
/** Resolved addresses in a form used by the LB policy.
@@ -220,6 +222,8 @@
#define GRPC_ARG_LB_ADDRESSES "grpc.lb_addresses"
/** The grpc_socket_mutator instance that set the socket options. A pointer. */
#define GRPC_ARG_SOCKET_MUTATOR "grpc.socket_mutator"
+/** Client channel factory. Not intended for external use. */
+#define GRPC_ARG_CLIENT_CHANNEL_FACTORY "grpc.client_channel_factory"
/** \} */
/** Result of a grpc call. If the caller satisfies the prerequisites of a
diff --git a/src/core/ext/census/grpc_filter.c b/src/core/ext/census/grpc_filter.c
index 397dbc4..3e8acc8 100644
--- a/src/core/ext/census/grpc_filter.c
+++ b/src/core/ext/census/grpc_filter.c
@@ -167,11 +167,12 @@
/* TODO(hongyu): record rpc server stats and census_tracing_end_op here */
}
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
- grpc_channel_element *elem,
- grpc_channel_element_args *args) {
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_channel_element_args *args) {
channel_data *chand = elem->channel_data;
GPR_ASSERT(chand != NULL);
+ return GRPC_ERROR_NONE;
}
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c
index 1fcff43..98892a4 100644
--- a/src/core/ext/client_channel/client_channel.c
+++ b/src/core/ext/client_channel/client_channel.c
@@ -44,6 +44,7 @@
#include <grpc/support/useful.h>
#include "src/core/ext/client_channel/lb_policy_registry.h"
+#include "src/core/ext/client_channel/resolver_registry.h"
#include "src/core/ext/client_channel/subchannel.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/connected_channel.h"
@@ -499,24 +500,37 @@
}
/* Constructor for channel_data */
-static void cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
- grpc_channel_element *elem,
- grpc_channel_element_args *args) {
+static grpc_error *cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_channel_element_args *args) {
channel_data *chand = elem->channel_data;
-
memset(chand, 0, sizeof(*chand));
-
GPR_ASSERT(args->is_last);
GPR_ASSERT(elem->filter == &grpc_client_channel_filter);
-
+ // Initialize data members.
gpr_mu_init(&chand->mu);
+ chand->owning_stack = args->channel_stack;
grpc_closure_init(&chand->on_resolver_result_changed,
on_resolver_result_changed, chand);
- chand->owning_stack = args->channel_stack;
-
+ chand->interested_parties = grpc_pollset_set_create();
grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE,
"client_channel");
- chand->interested_parties = grpc_pollset_set_create();
+ // Record client channel factory.
+ const grpc_arg *arg = grpc_channel_args_find(args->channel_args,
+ GRPC_ARG_CLIENT_CHANNEL_FACTORY);
+ GPR_ASSERT(arg != NULL);
+ GPR_ASSERT(arg->type == GRPC_ARG_POINTER);
+ grpc_client_channel_factory_ref(arg->value.pointer.p);
+ chand->client_channel_factory = arg->value.pointer.p;
+ // Instantiate resolver.
+ arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVER_URI);
+ GPR_ASSERT(arg != NULL);
+ GPR_ASSERT(arg->type == GRPC_ARG_STRING);
+ chand->resolver = grpc_resolver_create(arg->value.string, args->channel_args);
+ if (chand->resolver == NULL) {
+ return GRPC_ERROR_CREATE("resolver creation failed");
+ }
+ return GRPC_ERROR_NONE;
}
/* Destructor for channel_data */
@@ -1130,30 +1144,6 @@
"client-channel",
};
-void grpc_client_channel_finish_initialization(
- grpc_exec_ctx *exec_ctx, grpc_channel_stack *channel_stack,
- grpc_resolver *resolver,
- grpc_client_channel_factory *client_channel_factory) {
- /* post construction initialization: set the transport setup pointer */
- GPR_ASSERT(client_channel_factory != NULL);
- grpc_channel_element *elem = grpc_channel_stack_last_element(channel_stack);
- channel_data *chand = elem->channel_data;
- gpr_mu_lock(&chand->mu);
- GPR_ASSERT(!chand->resolver);
- chand->resolver = resolver;
- GRPC_RESOLVER_REF(resolver, "channel");
- if (!grpc_closure_list_empty(chand->waiting_for_config_closures) ||
- chand->exit_idle_when_lb_policy_arrives) {
- chand->started_resolving = true;
- GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
- grpc_resolver_next(exec_ctx, resolver, &chand->resolver_result,
- &chand->on_resolver_result_changed);
- }
- chand->client_channel_factory = client_channel_factory;
- grpc_client_channel_factory_ref(client_channel_factory);
- gpr_mu_unlock(&chand->mu);
-}
-
grpc_connectivity_state grpc_client_channel_check_connectivity_state(
grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, int try_to_connect) {
channel_data *chand = elem->channel_data;
diff --git a/src/core/ext/client_channel/client_channel.h b/src/core/ext/client_channel/client_channel.h
index ab5a84f..9ba0128 100644
--- a/src/core/ext/client_channel/client_channel.h
+++ b/src/core/ext/client_channel/client_channel.h
@@ -47,13 +47,6 @@
extern const grpc_channel_filter grpc_client_channel_filter;
-/* Post-construction initializer to give the client channel its resolver
- and factory. */
-void grpc_client_channel_finish_initialization(
- grpc_exec_ctx *exec_ctx, grpc_channel_stack *channel_stack,
- grpc_resolver *resolver,
- grpc_client_channel_factory *client_channel_factory);
-
grpc_connectivity_state grpc_client_channel_check_connectivity_state(
grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, int try_to_connect);
diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/client_channel/subchannel.c
index 0863207..f294e69 100644
--- a/src/core/ext/client_channel/subchannel.c
+++ b/src/core/ext/client_channel/subchannel.c
@@ -604,14 +604,20 @@
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 {
+ if (!grpc_channel_init_create_stack(exec_ctx, builder,
+ GRPC_CLIENT_SUBCHANNEL)) {
grpc_channel_stack_builder_destroy(builder);
abort(); /* TODO(ctiller): what to do here (previously we just crashed) */
}
+ grpc_error *error = grpc_channel_stack_builder_finish(
+ exec_ctx, builder, 0, 1, connection_destroy, NULL, (void **)&con);
+ if (error != GRPC_ERROR_NONE) {
+ const char *msg = grpc_error_string(error);
+ gpr_log(GPR_ERROR, "error initializing subchannel stack: %s", msg);
+ grpc_error_free_string(msg);
+ GRPC_ERROR_UNREF(error);
+ abort(); /* TODO(ctiller): what to do here? */
+ }
stk = CHANNEL_STACK_FROM_CONNECTION(con);
memset(&c->connecting_result, 0, sizeof(c->connecting_result));
diff --git a/src/core/ext/load_reporting/load_reporting_filter.c b/src/core/ext/load_reporting/load_reporting_filter.c
index b810e20..18bb826 100644
--- a/src/core/ext/load_reporting/load_reporting_filter.c
+++ b/src/core/ext/load_reporting/load_reporting_filter.c
@@ -152,9 +152,9 @@
}
/* Constructor for channel_data */
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
- grpc_channel_element *elem,
- grpc_channel_element_args *args) {
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_channel_element_args *args) {
GPR_ASSERT(!args->is_last);
channel_data *chand = elem->channel_data;
@@ -171,6 +171,8 @@
NULL,
NULL};
*/
+
+ return GRPC_ERROR_NONE;
}
/* Destructor for channel data */
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
index 29f3759..7325f94 100644
--- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
@@ -39,8 +39,8 @@
#include <grpc/support/string_util.h>
#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/client_channel/resolver_registry.h"
#include "src/core/ext/transport/chttp2/client/chttp2_connector.h"
+#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/channel.h"
@@ -65,18 +65,7 @@
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
const char *target, grpc_client_channel_type type,
const grpc_channel_args *args) {
- grpc_channel *channel =
- grpc_channel_create(exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
- grpc_resolver *resolver = grpc_resolver_create(target, args);
- if (resolver == NULL) {
- GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel,
- "client_channel_factory_create_channel");
- return NULL;
- }
- grpc_client_channel_finish_initialization(
- exec_ctx, grpc_channel_get_channel_stack(channel), resolver, cc_factory);
- GRPC_RESOLVER_UNREF(exec_ctx, resolver, "create_channel");
- return channel;
+ return grpc_channel_create(exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
}
static const grpc_client_channel_factory_vtable client_channel_factory_vtable =
@@ -87,6 +76,19 @@
static grpc_client_channel_factory client_channel_factory = {
&client_channel_factory_vtable};
+static void *cc_factory_arg_copy(void *cc_factory) { return cc_factory; }
+
+static void cc_factory_arg_destroy(void *cc_factory) {}
+
+static int cc_factory_arg_cmp(void *cc_factory1, void *cc_factory2) {
+ if (cc_factory1 < cc_factory2) return -1;
+ if (cc_factory1 > cc_factory2) return 1;
+ return 0;
+}
+
+static const grpc_arg_pointer_vtable cc_factory_arg_vtable = {
+ cc_factory_arg_copy, cc_factory_arg_destroy, cc_factory_arg_cmp};
+
/* Create a client channel:
Asynchronously: - resolve target
- connect to it (trying alternatives as presented)
@@ -101,8 +103,22 @@
GPR_ASSERT(reserved == NULL);
grpc_client_channel_factory *factory =
(grpc_client_channel_factory *)&client_channel_factory;
+ // Add channel args containing the server name and client channel factory.
+ grpc_arg new_args[2];
+ new_args[0].type = GRPC_ARG_STRING;
+ new_args[0].key = GRPC_ARG_SERVER_URI;
+ new_args[0].value.string = (char *)target;
+ new_args[1].type = GRPC_ARG_POINTER;
+ new_args[1].key = GRPC_ARG_CLIENT_CHANNEL_FACTORY;
+ new_args[1].value.pointer.p = factory;
+ new_args[1].value.pointer.vtable = &cc_factory_arg_vtable;
+ grpc_channel_args *args_copy =
+ grpc_channel_args_copy_and_add(args, new_args, GPR_ARRAY_SIZE(new_args));
+ // Create channel.
grpc_channel *channel = client_channel_factory_create_channel(
- &exec_ctx, factory, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, args);
+ &exec_ctx, factory, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, args_copy);
+ // Clean up.
+ grpc_channel_args_destroy(args_copy);
grpc_client_channel_factory_unref(&exec_ctx, factory);
grpc_exec_ctx_finish(&exec_ctx);
return channel != NULL ? channel : grpc_lame_client_channel_create(
diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
index 35e1e1f..63f2488 100644
--- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
+++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
@@ -39,7 +39,6 @@
#include <grpc/support/string_util.h>
#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/client_channel/resolver_registry.h"
#include "src/core/ext/transport/chttp2/client/chttp2_connector.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/security/credentials/credentials.h"
@@ -91,19 +90,7 @@
grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
const char *target, grpc_client_channel_type type,
const grpc_channel_args *args) {
- client_channel_factory *f = (client_channel_factory *)cc_factory;
- grpc_channel *channel =
- grpc_channel_create(exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
- grpc_resolver *resolver = grpc_resolver_create(target, args);
- if (resolver == NULL) {
- GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel,
- "client_channel_factory_create_channel");
- return NULL;
- }
- grpc_client_channel_finish_initialization(
- exec_ctx, grpc_channel_get_channel_stack(channel), resolver, &f->base);
- GRPC_RESOLVER_UNREF(exec_ctx, resolver, "create_channel");
- return channel;
+ return grpc_channel_create(exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
}
static const grpc_client_channel_factory_vtable client_channel_factory_vtable =
@@ -111,6 +98,28 @@
client_channel_factory_create_subchannel,
client_channel_factory_create_channel};
+static void *cc_factory_arg_copy(void *cc_factory) {
+ client_channel_factory_ref(cc_factory);
+ return cc_factory;
+}
+
+static void cc_factory_arg_destroy(void *cc_factory) {
+ // TODO(roth): remove local exec_ctx when
+ // https://github.com/grpc/grpc/pull/8705 is merged
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ client_channel_factory_unref(&exec_ctx, cc_factory);
+ grpc_exec_ctx_finish(&exec_ctx);
+}
+
+static int cc_factory_arg_cmp(void *cc_factory1, void *cc_factory2) {
+ if (cc_factory1 < cc_factory2) return -1;
+ if (cc_factory1 > cc_factory2) return 1;
+ return 0;
+}
+
+static const grpc_arg_pointer_vtable cc_factory_arg_vtable = {
+ cc_factory_arg_copy, cc_factory_arg_destroy, cc_factory_arg_cmp};
+
/* Create a secure client channel:
Asynchronously: - resolve target
- connect to it (trying alternatives as presented)
@@ -143,14 +152,6 @@
return grpc_lame_client_channel_create(
target, GRPC_STATUS_INTERNAL, "Failed to create security connector.");
}
- grpc_arg connector_arg =
- grpc_security_connector_to_arg(&security_connector->base);
- grpc_channel_args *new_args = grpc_channel_args_copy_and_add(
- new_args_from_connector != NULL ? new_args_from_connector : args,
- &connector_arg, 1);
- if (new_args_from_connector != NULL) {
- grpc_channel_args_destroy(new_args_from_connector);
- }
// Create client channel factory.
client_channel_factory *f = gpr_malloc(sizeof(*f));
memset(f, 0, sizeof(*f));
@@ -159,13 +160,30 @@
GRPC_SECURITY_CONNECTOR_REF(&security_connector->base,
"grpc_secure_channel_create");
f->security_connector = security_connector;
+ // Add channel args containing the server name, client channel
+ // factory, and security connector.
+ grpc_arg new_args[3];
+ new_args[0].type = GRPC_ARG_STRING;
+ new_args[0].key = GRPC_ARG_SERVER_URI;
+ new_args[0].value.string = (char *)target;
+ new_args[1].type = GRPC_ARG_POINTER;
+ new_args[1].key = GRPC_ARG_CLIENT_CHANNEL_FACTORY;
+ new_args[1].value.pointer.p = f;
+ new_args[1].value.pointer.vtable = &cc_factory_arg_vtable;
+ new_args[2] = grpc_security_connector_to_arg(&security_connector->base);
+ grpc_channel_args *args_copy = grpc_channel_args_copy_and_add(
+ new_args_from_connector != NULL ? new_args_from_connector : args,
+ new_args, GPR_ARRAY_SIZE(new_args));
+ if (new_args_from_connector != NULL) {
+ grpc_channel_args_destroy(new_args_from_connector);
+ }
// Create channel.
grpc_channel *channel = client_channel_factory_create_channel(
- &exec_ctx, &f->base, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, new_args);
+ &exec_ctx, &f->base, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, args_copy);
// Clean up.
GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base,
"secure_client_channel_factory_create_channel");
- grpc_channel_args_destroy(new_args);
+ grpc_channel_args_destroy(args_copy);
grpc_client_channel_factory_unref(&exec_ctx, &f->base);
grpc_exec_ctx_finish(&exec_ctx);
return channel; /* may be NULL */
diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c
index 999ad5f..1d0b7d4 100644
--- a/src/core/lib/channel/channel_stack.c
+++ b/src/core/lib/channel/channel_stack.c
@@ -102,13 +102,11 @@
return CALL_ELEMS_FROM_STACK(call_stack) + index;
}
-void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx, int initial_refs,
- grpc_iomgr_cb_func destroy, void *destroy_arg,
- const grpc_channel_filter **filters,
- size_t filter_count,
- const grpc_channel_args *channel_args,
- grpc_transport *optional_transport,
- const char *name, grpc_channel_stack *stack) {
+grpc_error *grpc_channel_stack_init(
+ grpc_exec_ctx *exec_ctx, int initial_refs, grpc_iomgr_cb_func destroy,
+ void *destroy_arg, const grpc_channel_filter **filters, size_t filter_count,
+ const grpc_channel_args *channel_args, grpc_transport *optional_transport,
+ const char *name, grpc_channel_stack *stack) {
size_t call_size =
ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)) +
ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_call_element));
@@ -126,6 +124,7 @@
ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_channel_element));
/* init per-filter data */
+ grpc_error *first_error = GRPC_ERROR_NONE;
for (i = 0; i < filter_count; i++) {
args.channel_stack = stack;
args.channel_args = channel_args;
@@ -134,7 +133,15 @@
args.is_last = i == (filter_count - 1);
elems[i].filter = filters[i];
elems[i].channel_data = user_data;
- elems[i].filter->init_channel_elem(exec_ctx, &elems[i], &args);
+ grpc_error *error =
+ elems[i].filter->init_channel_elem(exec_ctx, &elems[i], &args);
+ if (error != GRPC_ERROR_NONE) {
+ if (first_error == GRPC_ERROR_NONE) {
+ first_error = error;
+ } else {
+ GRPC_ERROR_UNREF(error);
+ }
+ }
user_data += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data);
call_size += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_call_data);
}
@@ -144,6 +151,7 @@
grpc_channel_stack_size(filters, filter_count));
stack->call_stack_size = call_size;
+ return first_error;
}
void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h
index 004643d..5d064c5 100644
--- a/src/core/lib/channel/channel_stack.h
+++ b/src/core/lib/channel/channel_stack.h
@@ -146,8 +146,9 @@
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_exec_ctx *exec_ctx, grpc_channel_element *elem,
- grpc_channel_element_args *args);
+ grpc_error *(*init_channel_elem)(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_channel_element_args *args);
/* Destroy per channel data.
The filter does not need to do any chaining */
void (*destroy_channel_elem)(grpc_exec_ctx *exec_ctx,
@@ -214,12 +215,11 @@
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(grpc_exec_ctx *exec_ctx, int initial_refs,
- grpc_iomgr_cb_func destroy, void *destroy_arg,
- const grpc_channel_filter **filters,
- size_t filter_count, const grpc_channel_args *args,
- grpc_transport *optional_transport,
- const char *name, grpc_channel_stack *stack);
+grpc_error *grpc_channel_stack_init(
+ grpc_exec_ctx *exec_ctx, int initial_refs, grpc_iomgr_cb_func destroy,
+ void *destroy_arg, const grpc_channel_filter **filters, size_t filter_count,
+ const grpc_channel_args *args, grpc_transport *optional_transport,
+ const char *name, grpc_channel_stack *stack);
/* Destroy a channel stack */
void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx,
grpc_channel_stack *stack);
diff --git a/src/core/lib/channel/channel_stack_builder.c b/src/core/lib/channel/channel_stack_builder.c
index eda4968..b959517 100644
--- a/src/core/lib/channel/channel_stack_builder.c
+++ b/src/core/lib/channel/channel_stack_builder.c
@@ -227,11 +227,10 @@
gpr_free(builder);
}
-void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx,
- grpc_channel_stack_builder *builder,
- size_t prefix_bytes, int initial_refs,
- grpc_iomgr_cb_func destroy,
- void *destroy_arg) {
+grpc_error *grpc_channel_stack_builder_finish(
+ grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder,
+ size_t prefix_bytes, int initial_refs, grpc_iomgr_cb_func destroy,
+ void *destroy_arg, void **result) {
// count the number of filters
size_t num_filters = 0;
for (filter_node *p = builder->begin.next; p != &builder->end; p = p->next) {
@@ -250,28 +249,35 @@
size_t channel_stack_size = grpc_channel_stack_size(filters, num_filters);
// allocate memory, with prefix_bytes followed by channel_stack_size
- char *result = gpr_malloc(prefix_bytes + channel_stack_size);
+ *result = gpr_malloc(prefix_bytes + channel_stack_size);
// fetch a pointer to the channel stack
grpc_channel_stack *channel_stack =
- (grpc_channel_stack *)(result + prefix_bytes);
+ (grpc_channel_stack *)((char *)(*result) + prefix_bytes);
// and initialize it
- grpc_channel_stack_init(exec_ctx, initial_refs, destroy,
- destroy_arg == NULL ? result : destroy_arg, filters,
- num_filters, builder->args, builder->transport,
- builder->name, channel_stack);
+ grpc_error *error = grpc_channel_stack_init(
+ exec_ctx, initial_refs, destroy,
+ destroy_arg == NULL ? *result : destroy_arg, filters, num_filters,
+ builder->args, builder->transport, builder->name, channel_stack);
- // 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);
+ if (error != GRPC_ERROR_NONE) {
+ grpc_channel_stack_destroy(exec_ctx, channel_stack);
+ gpr_free(*result);
+ *result = NULL;
+ } else {
+ // 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);
gpr_free((grpc_channel_filter **)filters);
- return result;
+ return error;
}
diff --git a/src/core/lib/channel/channel_stack_builder.h b/src/core/lib/channel/channel_stack_builder.h
index 4a00f7b..65bfebc 100644
--- a/src/core/lib/channel/channel_stack_builder.h
+++ b/src/core/lib/channel/channel_stack_builder.h
@@ -146,16 +146,15 @@
void grpc_channel_stack_builder_iterator_destroy(
grpc_channel_stack_builder_iterator *iterator);
-/// Destroy the builder, return the freshly minted channel stack
+/// Destroy the builder, return the freshly minted channel stack in \a result.
/// Allocates \a prefix_bytes bytes before the channel stack
/// Returns the base pointer of the allocated block
/// \a initial_refs, \a destroy, \a destroy_arg are as per
/// grpc_channel_stack_init
-void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx,
- grpc_channel_stack_builder *builder,
- size_t prefix_bytes, int initial_refs,
- grpc_iomgr_cb_func destroy,
- void *destroy_arg);
+grpc_error *grpc_channel_stack_builder_finish(
+ grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder,
+ size_t prefix_bytes, int initial_refs, grpc_iomgr_cb_func destroy,
+ void *destroy_arg, void **result);
/// Destroy the builder without creating a channel stack
void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder);
diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c
index 2874d63..0e336dc 100644
--- a/src/core/lib/channel/compress_filter.c
+++ b/src/core/lib/channel/compress_filter.c
@@ -285,9 +285,9 @@
}
/* Constructor for channel_data */
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
- grpc_channel_element *elem,
- grpc_channel_element_args *args) {
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_channel_element_args *args) {
channel_data *channeld = elem->channel_data;
channeld->enabled_algorithms_bitset =
@@ -315,6 +315,7 @@
}
GPR_ASSERT(!args->is_last);
+ return GRPC_ERROR_NONE;
}
/* Destructor for channel data */
diff --git a/src/core/lib/channel/connected_channel.c b/src/core/lib/channel/connected_channel.c
index 038e819..c2a36b5 100644
--- a/src/core/lib/channel/connected_channel.c
+++ b/src/core/lib/channel/connected_channel.c
@@ -114,12 +114,13 @@
}
/* Constructor for channel_data */
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
- grpc_channel_element *elem,
- grpc_channel_element_args *args) {
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_channel_element_args *args) {
channel_data *cd = (channel_data *)elem->channel_data;
GPR_ASSERT(args->is_last);
cd->transport = NULL;
+ return GRPC_ERROR_NONE;
}
/* Destructor for channel_data */
diff --git a/src/core/lib/channel/deadline_filter.c b/src/core/lib/channel/deadline_filter.c
index 0e703d8..470ccfe 100644
--- a/src/core/lib/channel/deadline_filter.c
+++ b/src/core/lib/channel/deadline_filter.c
@@ -207,10 +207,11 @@
//
// Constructor for channel_data. Used for both client and server filters.
-static void init_channel_elem(grpc_exec_ctx* exec_ctx,
- grpc_channel_element* elem,
- grpc_channel_element_args* args) {
+static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx,
+ grpc_channel_element* elem,
+ grpc_channel_element_args* args) {
GPR_ASSERT(!args->is_last);
+ return GRPC_ERROR_NONE;
}
// Destructor for channel_data. Used for both client and server filters.
diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c
index fd8b46a..1a2d08d 100644
--- a/src/core/lib/channel/http_client_filter.c
+++ b/src/core/lib/channel/http_client_filter.c
@@ -457,9 +457,9 @@
}
/* Constructor for channel_data */
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
- grpc_channel_element *elem,
- grpc_channel_element_args *args) {
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_channel_element_args *args) {
channel_data *chand = elem->channel_data;
GPR_ASSERT(!args->is_last);
GPR_ASSERT(args->optional_transport != NULL);
@@ -470,6 +470,7 @@
GRPC_MDSTR_USER_AGENT,
user_agent_from_args(args->channel_args,
args->optional_transport->vtable->name));
+ return GRPC_ERROR_NONE;
}
/* Destructor for channel data */
diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/lib/channel/http_server_filter.c
index b42ff06..a5134ee 100644
--- a/src/core/lib/channel/http_server_filter.c
+++ b/src/core/lib/channel/http_server_filter.c
@@ -350,10 +350,11 @@
}
/* Constructor for channel_data */
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
- grpc_channel_element *elem,
- grpc_channel_element_args *args) {
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_channel_element_args *args) {
GPR_ASSERT(!args->is_last);
+ return GRPC_ERROR_NONE;
}
/* Destructor for channel data */
diff --git a/src/core/lib/channel/message_size_filter.c b/src/core/lib/channel/message_size_filter.c
index 1cf68d7..f05c789 100644
--- a/src/core/lib/channel/message_size_filter.c
+++ b/src/core/lib/channel/message_size_filter.c
@@ -192,9 +192,9 @@
void* ignored) {}
// Constructor for channel_data.
-static void init_channel_elem(grpc_exec_ctx* exec_ctx,
- grpc_channel_element* elem,
- grpc_channel_element_args* args) {
+static grpc_error* init_channel_elem(grpc_exec_ctx* exec_ctx,
+ grpc_channel_element* elem,
+ grpc_channel_element_args* args) {
GPR_ASSERT(!args->is_last);
channel_data* chand = elem->channel_data;
memset(chand, 0, sizeof(*chand));
@@ -231,6 +231,7 @@
grpc_service_config_destroy(service_config);
}
}
+ return GRPC_ERROR_NONE;
}
// Destructor for channel_data.
diff --git a/src/core/lib/security/transport/client_auth_filter.c b/src/core/lib/security/transport/client_auth_filter.c
index 053bf59..da89729 100644
--- a/src/core/lib/security/transport/client_auth_filter.c
+++ b/src/core/lib/security/transport/client_auth_filter.c
@@ -303,9 +303,9 @@
}
/* Constructor for channel_data */
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
- grpc_channel_element *elem,
- grpc_channel_element_args *args) {
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_channel_element_args *args) {
grpc_security_connector *sc =
grpc_find_security_connector_in_args(args->channel_args);
grpc_auth_context *auth_context =
@@ -327,6 +327,7 @@
sc, "client_auth_filter");
chand->auth_context =
GRPC_AUTH_CONTEXT_REF(auth_context, "client_auth_filter");
+ return GRPC_ERROR_NONE;
}
/* Destructor for channel data */
diff --git a/src/core/lib/security/transport/server_auth_filter.c b/src/core/lib/security/transport/server_auth_filter.c
index eaa1d07..e6a242e 100644
--- a/src/core/lib/security/transport/server_auth_filter.c
+++ b/src/core/lib/security/transport/server_auth_filter.c
@@ -238,9 +238,9 @@
void *ignored) {}
/* Constructor for channel_data */
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
- grpc_channel_element *elem,
- grpc_channel_element_args *args) {
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_channel_element_args *args) {
grpc_auth_context *auth_context =
grpc_find_auth_context_in_args(args->channel_args);
grpc_server_credentials *creds =
@@ -256,6 +256,7 @@
chand->auth_context =
GRPC_AUTH_CONTEXT_REF(auth_context, "server_auth_filter");
chand->creds = grpc_server_credentials_ref(creds);
+ return GRPC_ERROR_NONE;
}
/* Destructor for channel data */
diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c
index 1389df6..9405015 100644
--- a/src/core/lib/surface/channel.c
+++ b/src/core/lib/surface/channel.c
@@ -86,87 +86,90 @@
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_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);
+ }
+ grpc_channel_args *args = grpc_channel_args_copy(
+ grpc_channel_stack_builder_get_channel_arguments(builder));
+ grpc_channel *channel;
+ grpc_error *error = grpc_channel_stack_builder_finish(
+ exec_ctx, builder, sizeof(grpc_channel), 1, destroy_channel, NULL,
+ (void **)&channel);
+ if (error != GRPC_ERROR_NONE) {
+ const char *msg = grpc_error_string(error);
+ gpr_log(GPR_ERROR, "channel stack builder failed: %s", msg);
+ grpc_error_free_string(msg);
+ GRPC_ERROR_UNREF(error);
+ goto done;
}
memset(channel, 0, sizeof(*channel));
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);
channel->registered_calls = NULL;
grpc_compression_options_init(&channel->compression_options);
- if (args) {
- for (size_t i = 0; i < args->num_args; i++) {
- if (0 == strcmp(args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) {
- if (args->args[i].type != GRPC_ARG_STRING) {
- gpr_log(GPR_ERROR, "%s ignored: it must be a string",
- GRPC_ARG_DEFAULT_AUTHORITY);
+
+ for (size_t i = 0; i < args->num_args; i++) {
+ if (0 == strcmp(args->args[i].key, GRPC_ARG_DEFAULT_AUTHORITY)) {
+ if (args->args[i].type != GRPC_ARG_STRING) {
+ gpr_log(GPR_ERROR, "%s ignored: it must be a string",
+ GRPC_ARG_DEFAULT_AUTHORITY);
+ } else {
+ if (channel->default_authority) {
+ /* setting this takes precedence over anything else */
+ GRPC_MDELEM_UNREF(channel->default_authority);
+ }
+ channel->default_authority =
+ grpc_mdelem_from_strings(":authority", args->args[i].value.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);
} else {
- if (channel->default_authority) {
- /* setting this takes precedence over anything else */
- GRPC_MDELEM_UNREF(channel->default_authority);
- }
channel->default_authority = grpc_mdelem_from_strings(
":authority", args->args[i].value.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);
- } 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;
}
diff --git a/src/core/lib/surface/lame_client.c b/src/core/lib/surface/lame_client.c
index d0df8e7..57da94a 100644
--- a/src/core/lib/surface/lame_client.c
+++ b/src/core/lib/surface/lame_client.c
@@ -123,11 +123,12 @@
gpr_free(and_free_memory);
}
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
- grpc_channel_element *elem,
- grpc_channel_element_args *args) {
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_channel_element_args *args) {
GPR_ASSERT(args->is_first);
GPR_ASSERT(args->is_last);
+ return GRPC_ERROR_NONE;
}
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c
index fe73aa3..62d7afc 100644
--- a/src/core/lib/surface/server.c
+++ b/src/core/lib/surface/server.c
@@ -914,9 +914,9 @@
server_unref(exec_ctx, chand->server);
}
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
- grpc_channel_element *elem,
- grpc_channel_element_args *args) {
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_channel_element_args *args) {
channel_data *chand = elem->channel_data;
GPR_ASSERT(args->is_first);
GPR_ASSERT(!args->is_last);
@@ -927,6 +927,7 @@
chand->connectivity_state = GRPC_CHANNEL_IDLE;
grpc_closure_init(&chand->channel_connectivity_changed,
channel_connectivity_changed, chand);
+ return GRPC_ERROR_NONE;
}
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h
index e420efc..107522e 100644
--- a/src/cpp/common/channel_filter.h
+++ b/src/cpp/common/channel_filter.h
@@ -220,6 +220,9 @@
if (peer_) gpr_free((void *)peer_);
}
+ /// Initializes the call data.
+ virtual grpc_error *Init() { return GRPC_ERROR_NONE; }
+
/// Caller does NOT take ownership of result.
const char *peer() const { return peer_; }
@@ -276,15 +279,17 @@
public:
static const size_t channel_data_size = sizeof(ChannelDataType);
- static void InitChannelElement(grpc_exec_ctx *exec_ctx,
- grpc_channel_element *elem,
- grpc_channel_element_args *args) {
+ static grpc_error *InitChannelElement(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_channel_element_args *args) {
const char *peer =
args->optional_transport
? grpc_transport_get_peer(exec_ctx, args->optional_transport)
: nullptr;
// Construct the object in the already-allocated memory.
- new (elem->channel_data) ChannelDataType(*args->channel_args, peer);
+ ChannelDataType *channel_data =
+ new (elem->channel_data) ChannelDataType(*args->channel_args, peer);
+ return channel_data->Init();
}
static void DestroyChannelElement(grpc_exec_ctx *exec_ctx,
diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c
index 0840820..b43d05e 100644
--- a/test/core/channel/channel_stack_test.c
+++ b/test/core/channel/channel_stack_test.c
@@ -41,9 +41,9 @@
#include "test/core/util/test_config.h"
-static void channel_init_func(grpc_exec_ctx *exec_ctx,
- grpc_channel_element *elem,
- grpc_channel_element_args *args) {
+static grpc_error *channel_init_func(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_channel_element_args *args) {
GPR_ASSERT(args->channel_args->num_args == 1);
GPR_ASSERT(args->channel_args->args[0].type == GRPC_ARG_INTEGER);
GPR_ASSERT(0 == strcmp(args->channel_args->args[0].key, "test_key"));
@@ -51,6 +51,7 @@
GPR_ASSERT(args->is_first);
GPR_ASSERT(args->is_last);
*(int *)(elem->channel_data) = 0;
+ return GRPC_ERROR_NONE;
}
static grpc_error *call_init_func(grpc_exec_ctx *exec_ctx,
diff --git a/test/core/end2end/tests/filter_call_init_fails.c b/test/core/end2end/tests/filter_call_init_fails.c
index 41ae575..6d9351e 100644
--- a/test/core/end2end/tests/filter_call_init_fails.c
+++ b/test/core/end2end/tests/filter_call_init_fails.c
@@ -216,9 +216,11 @@
const grpc_call_final_info *final_info,
void *and_free_memory) {}
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
- grpc_channel_element *elem,
- grpc_channel_element_args *args) {}
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_channel_element_args *args) {
+ return GRPC_ERROR_NONE;
+}
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {}
diff --git a/test/core/end2end/tests/filter_causes_close.c b/test/core/end2end/tests/filter_causes_close.c
index bf9fd90..21905b9 100644
--- a/test/core/end2end/tests/filter_causes_close.c
+++ b/test/core/end2end/tests/filter_causes_close.c
@@ -243,9 +243,11 @@
const grpc_call_final_info *final_info,
void *and_free_memory) {}
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
- grpc_channel_element *elem,
- grpc_channel_element_args *args) {}
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_channel_element_args *args) {
+ return GRPC_ERROR_NONE;
+}
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {}
diff --git a/test/core/end2end/tests/filter_latency.c b/test/core/end2end/tests/filter_latency.c
index ea63d45..e102048 100644
--- a/test/core/end2end/tests/filter_latency.c
+++ b/test/core/end2end/tests/filter_latency.c
@@ -281,9 +281,11 @@
gpr_mu_unlock(&g_mu);
}
-static void init_channel_elem(grpc_exec_ctx *exec_ctx,
- grpc_channel_element *elem,
- grpc_channel_element_args *args) {}
+static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx,
+ grpc_channel_element *elem,
+ grpc_channel_element_args *args) {
+ return GRPC_ERROR_NONE;
+}
static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {}
diff --git a/test/core/surface/channel_create_test.c b/test/core/surface/channel_create_test.c
index ad7970a..654e532 100644
--- a/test/core/surface/channel_create_test.c
+++ b/test/core/surface/channel_create_test.c
@@ -31,9 +31,14 @@
*
*/
+#include <string.h>
+
#include <grpc/grpc.h>
#include <grpc/support/log.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"
void test_unknown_scheme_target(void) {
@@ -44,6 +49,13 @@
chan = grpc_insecure_channel_create("blah://blah", NULL, 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);
}