Browse Source

Change destroy_call_elem() to return a grpc_error*.

Mark D. Roth 9 years ago
parent
commit
5e2566e92b

+ 4 - 3
src/core/ext/census/grpc_filter.c

@@ -167,11 +167,12 @@ static void server_destroy_call_elem(grpc_exec_ctx *exec_ctx,
   /* TODO(hongyu): record rpc server stats and census_tracing_end_op here */
   /* 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;
   channel_data *chand = elem->channel_data;
   GPR_ASSERT(chand != NULL);
   GPR_ASSERT(chand != NULL);
+  return GRPC_ERROR_NONE;
 }
 }
 
 
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,

+ 7 - 5
src/core/ext/client_channel/client_channel.c

@@ -451,9 +451,9 @@ static void cc_get_channel_info(grpc_exec_ctx *exec_ctx,
 }
 }
 
 
 /* Constructor for channel_data */
 /* 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;
   channel_data *chand = elem->channel_data;
   memset(chand, 0, sizeof(*chand));
   memset(chand, 0, sizeof(*chand));
   GPR_ASSERT(args->is_last);
   GPR_ASSERT(args->is_last);
@@ -478,8 +478,10 @@ static void cc_init_channel_elem(grpc_exec_ctx *exec_ctx,
   GPR_ASSERT(arg != NULL);
   GPR_ASSERT(arg != NULL);
   GPR_ASSERT(arg->type == GRPC_ARG_STRING);
   GPR_ASSERT(arg->type == GRPC_ARG_STRING);
   chand->resolver = grpc_resolver_create(arg->value.string, args->channel_args);
   chand->resolver = grpc_resolver_create(arg->value.string, args->channel_args);
-// FIXME: return failure instead of asserting
-  GPR_ASSERT(chand->resolver != NULL);
+  if (chand->resolver == NULL) {
+    return GRPC_ERROR_CREATE("resolver creation failed");
+  }
+  return GRPC_ERROR_NONE;
 }
 }
 
 
 /* Destructor for channel_data */
 /* Destructor for channel_data */

+ 11 - 5
src/core/ext/client_channel/subchannel.c

@@ -542,14 +542,20 @@ static void publish_transport_locked(grpc_exec_ctx *exec_ctx,
   grpc_channel_stack_builder_set_transport(builder,
   grpc_channel_stack_builder_set_transport(builder,
                                            c->connecting_result.transport);
                                            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);
     grpc_channel_stack_builder_destroy(builder);
     abort(); /* TODO(ctiller): what to do here (previously we just crashed) */
     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);
   stk = CHANNEL_STACK_FROM_CONNECTION(con);
   memset(&c->connecting_result, 0, sizeof(c->connecting_result));
   memset(&c->connecting_result, 0, sizeof(c->connecting_result));
 
 

+ 5 - 3
src/core/ext/load_reporting/load_reporting_filter.c

@@ -152,9 +152,9 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
 }
 }
 
 
 /* Constructor for channel_data */
 /* 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);
   GPR_ASSERT(!args->is_last);
 
 
   channel_data *chand = elem->channel_data;
   channel_data *chand = elem->channel_data;
@@ -171,6 +171,8 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
                                                 NULL,
                                                 NULL,
                                                 NULL};
                                                 NULL};
                                                 */
                                                 */
+
+  return GRPC_ERROR_NONE;
 }
 }
 
 
 /* Destructor for channel data */
 /* Destructor for channel data */

+ 16 - 8
src/core/lib/channel/channel_stack.c

@@ -102,13 +102,11 @@ grpc_call_element *grpc_call_stack_element(grpc_call_stack *call_stack,
   return CALL_ELEMS_FROM_STACK(call_stack) + index;
   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 =
   size_t call_size =
       ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)) +
       ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)) +
       ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_call_element));
       ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_call_element));
@@ -126,6 +124,7 @@ void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx, int initial_refs,
       ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_channel_element));
       ROUND_UP_TO_ALIGNMENT_SIZE(filter_count * sizeof(grpc_channel_element));
 
 
   /* init per-filter data */
   /* init per-filter data */
+  grpc_error *first_error = GRPC_ERROR_NONE;
   for (i = 0; i < filter_count; i++) {
   for (i = 0; i < filter_count; i++) {
     args.channel_stack = stack;
     args.channel_stack = stack;
     args.channel_args = channel_args;
     args.channel_args = channel_args;
@@ -134,7 +133,15 @@ void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx, int initial_refs,
     args.is_last = i == (filter_count - 1);
     args.is_last = i == (filter_count - 1);
     elems[i].filter = filters[i];
     elems[i].filter = filters[i];
     elems[i].channel_data = user_data;
     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);
     user_data += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_channel_data);
     call_size += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_call_data);
     call_size += ROUND_UP_TO_ALIGNMENT_SIZE(filters[i]->sizeof_call_data);
   }
   }
@@ -144,6 +151,7 @@ void grpc_channel_stack_init(grpc_exec_ctx *exec_ctx, int initial_refs,
              grpc_channel_stack_size(filters, filter_count));
              grpc_channel_stack_size(filters, filter_count));
 
 
   stack->call_stack_size = call_size;
   stack->call_stack_size = call_size;
+  return first_error;
 }
 }
 
 
 void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx,
 void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx,

+ 9 - 8
src/core/lib/channel/channel_stack.h

@@ -146,8 +146,9 @@ typedef struct {
      is_first, is_last designate this elements position in the stack, and are
      is_first, is_last designate this elements position in the stack, and are
      useful for asserting correct configuration by upper layer code.
      useful for asserting correct configuration by upper layer code.
      The filter does not need to do any chaining */
      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.
   /* Destroy per channel data.
      The filter does not need to do any chaining */
      The filter does not need to do any chaining */
   void (*destroy_channel_elem)(grpc_exec_ctx *exec_ctx,
   void (*destroy_channel_elem)(grpc_exec_ctx *exec_ctx,
@@ -214,12 +215,12 @@ grpc_call_element *grpc_call_stack_element(grpc_call_stack *stack, size_t i);
 size_t grpc_channel_stack_size(const grpc_channel_filter **filters,
 size_t grpc_channel_stack_size(const grpc_channel_filter **filters,
                                size_t filter_count);
                                size_t filter_count);
 /* Initialize a channel stack given some filters */
 /* 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 */
 /* Destroy a channel stack */
 void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx,
 void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx,
                                 grpc_channel_stack *stack);
                                 grpc_channel_stack *stack);

+ 11 - 12
src/core/lib/channel/channel_stack_builder.c

@@ -227,11 +227,10 @@ void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder) {
   gpr_free(builder);
   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
   // count the number of filters
   size_t num_filters = 0;
   size_t num_filters = 0;
   for (filter_node *p = builder->begin.next; p != &builder->end; p = p->next) {
   for (filter_node *p = builder->begin.next; p != &builder->end; p = p->next) {
@@ -250,15 +249,15 @@ void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx,
   size_t channel_stack_size = grpc_channel_stack_size(filters, num_filters);
   size_t channel_stack_size = grpc_channel_stack_size(filters, num_filters);
 
 
   // allocate memory, with prefix_bytes followed by channel_stack_size
   // 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
   // fetch a pointer to the channel stack
   grpc_channel_stack *channel_stack =
   grpc_channel_stack *channel_stack =
-      (grpc_channel_stack *)(result + prefix_bytes);
+      (grpc_channel_stack *)(*result + prefix_bytes);
   // and initialize it
   // 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
   // run post-initialization functions
   i = 0;
   i = 0;
@@ -273,5 +272,5 @@ void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx,
   grpc_channel_stack_builder_destroy(builder);
   grpc_channel_stack_builder_destroy(builder);
   gpr_free((grpc_channel_filter **)filters);
   gpr_free((grpc_channel_filter **)filters);
 
 
-  return result;
+  return error;
 }
 }

+ 5 - 6
src/core/lib/channel/channel_stack_builder.h

@@ -146,16 +146,15 @@ bool grpc_channel_stack_builder_append_filter(
 void grpc_channel_stack_builder_iterator_destroy(
 void grpc_channel_stack_builder_iterator_destroy(
     grpc_channel_stack_builder_iterator *iterator);
     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
 /// Allocates \a prefix_bytes bytes before the channel stack
 /// Returns the base pointer of the allocated block
 /// Returns the base pointer of the allocated block
 /// \a initial_refs, \a destroy, \a destroy_arg are as per
 /// \a initial_refs, \a destroy, \a destroy_arg are as per
 /// grpc_channel_stack_init
 /// 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
 /// Destroy the builder without creating a channel stack
 void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder);
 void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder);

+ 4 - 3
src/core/lib/channel/compress_filter.c

@@ -285,9 +285,9 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
 }
 }
 
 
 /* Constructor for channel_data */
 /* 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;
   channel_data *channeld = elem->channel_data;
 
 
   channeld->enabled_algorithms_bitset =
   channeld->enabled_algorithms_bitset =
@@ -315,6 +315,7 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
   }
   }
 
 
   GPR_ASSERT(!args->is_last);
   GPR_ASSERT(!args->is_last);
+  return GRPC_ERROR_NONE;
 }
 }
 
 
 /* Destructor for channel data */
 /* Destructor for channel data */

+ 4 - 3
src/core/lib/channel/connected_channel.c

@@ -114,12 +114,13 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
 }
 }
 
 
 /* Constructor for channel_data */
 /* 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;
   channel_data *cd = (channel_data *)elem->channel_data;
   GPR_ASSERT(args->is_last);
   GPR_ASSERT(args->is_last);
   cd->transport = NULL;
   cd->transport = NULL;
+  return GRPC_ERROR_NONE;
 }
 }
 
 
 /* Destructor for channel_data */
 /* Destructor for channel_data */

+ 4 - 3
src/core/lib/channel/deadline_filter.c

@@ -207,10 +207,11 @@ void grpc_deadline_state_client_start_transport_stream_op(
 //
 //
 
 
 // Constructor for channel_data.  Used for both client and server filters.
 // 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);
   GPR_ASSERT(!args->is_last);
+  return GRPC_ERROR_NONE;
 }
 }
 
 
 // Destructor for channel_data.  Used for both client and server filters.
 // Destructor for channel_data.  Used for both client and server filters.

+ 4 - 3
src/core/lib/channel/http_client_filter.c

@@ -415,9 +415,9 @@ static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args,
 }
 }
 
 
 /* Constructor for channel_data */
 /* 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;
   channel_data *chand = elem->channel_data;
   GPR_ASSERT(!args->is_last);
   GPR_ASSERT(!args->is_last);
   GPR_ASSERT(args->optional_transport != NULL);
   GPR_ASSERT(args->optional_transport != NULL);
@@ -428,6 +428,7 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
       GRPC_MDSTR_USER_AGENT,
       GRPC_MDSTR_USER_AGENT,
       user_agent_from_args(args->channel_args,
       user_agent_from_args(args->channel_args,
                            args->optional_transport->vtable->name));
                            args->optional_transport->vtable->name));
+  return GRPC_ERROR_NONE;
 }
 }
 
 
 /* Destructor for channel data */
 /* Destructor for channel data */

+ 4 - 3
src/core/lib/channel/http_server_filter.c

@@ -326,10 +326,11 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
 }
 }
 
 
 /* Constructor for channel_data */
 /* 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);
   GPR_ASSERT(!args->is_last);
+  return GRPC_ERROR_NONE;
 }
 }
 
 
 /* Destructor for channel data */
 /* Destructor for channel data */

+ 4 - 3
src/core/lib/channel/message_size_filter.c

@@ -195,9 +195,9 @@ static void destroy_call_elem(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
                               void* ignored) {}
                               void* ignored) {}
 
 
 // Constructor for channel_data.
 // 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);
   GPR_ASSERT(!args->is_last);
   channel_data* chand = elem->channel_data;
   channel_data* chand = elem->channel_data;
   memset(chand, 0, sizeof(*chand));
   memset(chand, 0, sizeof(*chand));
@@ -228,6 +228,7 @@ static void init_channel_elem(grpc_exec_ctx* exec_ctx,
         (grpc_method_config_table*)channel_arg->value.pointer.p,
         (grpc_method_config_table*)channel_arg->value.pointer.p,
         method_config_convert_value, &message_size_limits_vtable);
         method_config_convert_value, &message_size_limits_vtable);
   }
   }
+  return GRPC_ERROR_NONE;
 }
 }
 
 
 // Destructor for channel_data.
 // Destructor for channel_data.

+ 4 - 3
src/core/lib/security/transport/client_auth_filter.c

@@ -303,9 +303,9 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
 }
 }
 
 
 /* Constructor for channel_data */
 /* 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_security_connector *sc =
       grpc_find_security_connector_in_args(args->channel_args);
       grpc_find_security_connector_in_args(args->channel_args);
   grpc_auth_context *auth_context =
   grpc_auth_context *auth_context =
@@ -327,6 +327,7 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
           sc, "client_auth_filter");
           sc, "client_auth_filter");
   chand->auth_context =
   chand->auth_context =
       GRPC_AUTH_CONTEXT_REF(auth_context, "client_auth_filter");
       GRPC_AUTH_CONTEXT_REF(auth_context, "client_auth_filter");
+  return GRPC_ERROR_NONE;
 }
 }
 
 
 /* Destructor for channel data */
 /* Destructor for channel data */

+ 4 - 3
src/core/lib/security/transport/server_auth_filter.c

@@ -238,9 +238,9 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               void *ignored) {}
                               void *ignored) {}
 
 
 /* Constructor for channel_data */
 /* 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_auth_context *auth_context =
       grpc_find_auth_context_in_args(args->channel_args);
       grpc_find_auth_context_in_args(args->channel_args);
   grpc_server_credentials *creds =
   grpc_server_credentials *creds =
@@ -256,6 +256,7 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
   chand->auth_context =
   chand->auth_context =
       GRPC_AUTH_CONTEXT_REF(auth_context, "server_auth_filter");
       GRPC_AUTH_CONTEXT_REF(auth_context, "server_auth_filter");
   chand->creds = grpc_server_credentials_ref(creds);
   chand->creds = grpc_server_credentials_ref(creds);
+  return GRPC_ERROR_NONE;
 }
 }
 
 
 /* Destructor for channel data */
 /* Destructor for channel data */

+ 10 - 5
src/core/lib/surface/channel.c

@@ -97,11 +97,16 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
   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;
-  } 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);
+  }
+  args = grpc_channel_args_copy(
+      grpc_channel_stack_builder_get_channel_arguments(builder));
+  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) {
+    grpc_channel_stack_destroy(exec_ctx, (grpc_channel_stack *)channel);
+    gpr_free(channel);
+    return NULL;
   }
   }
 
 
   memset(channel, 0, sizeof(*channel));
   memset(channel, 0, sizeof(*channel));

+ 4 - 3
src/core/lib/surface/lame_client.c

@@ -123,11 +123,12 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
   gpr_free(and_free_memory);
   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_first);
   GPR_ASSERT(args->is_last);
   GPR_ASSERT(args->is_last);
+  return GRPC_ERROR_NONE;
 }
 }
 
 
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,

+ 4 - 3
src/core/lib/surface/server.c

@@ -913,9 +913,9 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
   server_unref(exec_ctx, chand->server);
   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;
   channel_data *chand = elem->channel_data;
   GPR_ASSERT(args->is_first);
   GPR_ASSERT(args->is_first);
   GPR_ASSERT(!args->is_last);
   GPR_ASSERT(!args->is_last);
@@ -926,6 +926,7 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx,
   chand->connectivity_state = GRPC_CHANNEL_IDLE;
   chand->connectivity_state = GRPC_CHANNEL_IDLE;
   grpc_closure_init(&chand->channel_connectivity_changed,
   grpc_closure_init(&chand->channel_connectivity_changed,
                     channel_connectivity_changed, chand);
                     channel_connectivity_changed, chand);
+  return GRPC_ERROR_NONE;
 }
 }
 
 
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,

+ 5 - 3
test/core/end2end/tests/filter_call_init_fails.c

@@ -216,9 +216,11 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
                               const grpc_call_final_info *final_info,
                               void *and_free_memory) {}
                               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,
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
                                  grpc_channel_element *elem) {}
                                  grpc_channel_element *elem) {}

+ 5 - 3
test/core/end2end/tests/filter_causes_close.c

@@ -243,9 +243,11 @@ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                               const grpc_call_final_info *final_info,
                               const grpc_call_final_info *final_info,
                               void *and_free_memory) {}
                               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,
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
                                  grpc_channel_element *elem) {}
                                  grpc_channel_element *elem) {}

+ 5 - 3
test/core/end2end/tests/filter_latency.c

@@ -275,9 +275,11 @@ static void server_destroy_call_elem(grpc_exec_ctx *exec_ctx,
   gpr_mu_unlock(&g_mu);
   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,
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
                                  grpc_channel_element *elem) {}
                                  grpc_channel_element *elem) {}