|  | @@ -80,6 +80,8 @@ struct grpc_channel {
 | 
	
		
			
				|  |  |  /* the protobuf library will (by default) start warning at 100megs */
 | 
	
		
			
				|  |  |  #define DEFAULT_MAX_MESSAGE_LENGTH (100 * 1024 * 1024)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +static void destroy_channel(grpc_exec_ctx *exec_ctx, void *arg, int success);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  grpc_channel *grpc_channel_create_from_filters(
 | 
	
		
			
				|  |  |      grpc_exec_ctx *exec_ctx, const char *target,
 | 
	
		
			
				|  |  |      const grpc_channel_filter **filters, size_t num_filters,
 | 
	
	
		
			
				|  | @@ -92,8 +94,6 @@ grpc_channel *grpc_channel_create_from_filters(
 | 
	
		
			
				|  |  |    channel->target = gpr_strdup(target);
 | 
	
		
			
				|  |  |    GPR_ASSERT(grpc_is_initialized() && "call grpc_init()");
 | 
	
		
			
				|  |  |    channel->is_client = is_client;
 | 
	
		
			
				|  |  | -  /* decremented by grpc_channel_destroy */
 | 
	
		
			
				|  |  | -  gpr_ref_init(&channel->refs, 1);
 | 
	
		
			
				|  |  |    gpr_mu_init(&channel->registered_call_mu);
 | 
	
		
			
				|  |  |    channel->registered_calls = NULL;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -151,7 +151,8 @@ grpc_channel *grpc_channel_create_from_filters(
 | 
	
		
			
				|  |  |      gpr_free(default_authority);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  grpc_channel_stack_init(exec_ctx, filters, num_filters, channel, args,
 | 
	
		
			
				|  |  | +  grpc_channel_stack_init(exec_ctx, 1, destroy_channel, channel, filters,
 | 
	
		
			
				|  |  | +                          num_filters, args,
 | 
	
		
			
				|  |  |                            CHANNEL_STACK_FROM_CHANNEL(channel));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    return channel;
 | 
	
	
		
			
				|  | @@ -248,17 +249,25 @@ grpc_call *grpc_channel_create_registered_call(
 | 
	
		
			
				|  |  |        rc->authority ? GRPC_MDELEM_REF(rc->authority) : NULL, deadline);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -#ifdef GRPC_CHANNEL_REF_COUNT_DEBUG
 | 
	
		
			
				|  |  | -void grpc_channel_internal_ref(grpc_channel *c, const char *reason) {
 | 
	
		
			
				|  |  | -  gpr_log(GPR_DEBUG, "CHANNEL:   ref %p %d -> %d [%s]", c, c->refs.count,
 | 
	
		
			
				|  |  | -          c->refs.count + 1, reason);
 | 
	
		
			
				|  |  | +#ifdef GRPC_STREAM_REFCOUNT_DEBUG
 | 
	
		
			
				|  |  | +#define REF_REASON reason
 | 
	
		
			
				|  |  | +#define REF_ARG , const char *reason
 | 
	
		
			
				|  |  |  #else
 | 
	
		
			
				|  |  | -void grpc_channel_internal_ref(grpc_channel *c) {
 | 
	
		
			
				|  |  | +#define REF_REASON ""
 | 
	
		
			
				|  |  | +#define REF_ARG
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  | -  gpr_ref(&c->refs);
 | 
	
		
			
				|  |  | +void grpc_channel_internal_ref(grpc_channel *c REF_ARG) {
 | 
	
		
			
				|  |  | +  GRPC_CHANNEL_STACK_REF(CHANNEL_STACK_FROM_CHANNEL(c), REF_REASON);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void destroy_channel(grpc_exec_ctx *exec_ctx, grpc_channel *channel) {
 | 
	
		
			
				|  |  | +void grpc_channel_internal_unref(grpc_exec_ctx *exec_ctx,
 | 
	
		
			
				|  |  | +                                 grpc_channel *c REF_ARG) {
 | 
	
		
			
				|  |  | +  GRPC_CHANNEL_STACK_UNREF(exec_ctx, CHANNEL_STACK_FROM_CHANNEL(c), REF_REASON);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static void destroy_channel(grpc_exec_ctx *exec_ctx, void *arg,
 | 
	
		
			
				|  |  | +                            int iomgr_success) {
 | 
	
		
			
				|  |  | +  grpc_channel *channel = arg;
 | 
	
		
			
				|  |  |    grpc_channel_stack_destroy(exec_ctx, CHANNEL_STACK_FROM_CHANNEL(channel));
 | 
	
		
			
				|  |  |    while (channel->registered_calls) {
 | 
	
		
			
				|  |  |      registered_call *rc = channel->registered_calls;
 | 
	
	
		
			
				|  | @@ -277,20 +286,6 @@ static void destroy_channel(grpc_exec_ctx *exec_ctx, grpc_channel *channel) {
 | 
	
		
			
				|  |  |    gpr_free(channel);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -#ifdef GRPC_CHANNEL_REF_COUNT_DEBUG
 | 
	
		
			
				|  |  | -void grpc_channel_internal_unref(grpc_exec_ctx *exec_ctx, grpc_channel *channel,
 | 
	
		
			
				|  |  | -                                 const char *reason) {
 | 
	
		
			
				|  |  | -  gpr_log(GPR_DEBUG, "CHANNEL: unref %p %d -> %d [%s]", channel,
 | 
	
		
			
				|  |  | -          channel->refs.count, channel->refs.count - 1, reason);
 | 
	
		
			
				|  |  | -#else
 | 
	
		
			
				|  |  | -void grpc_channel_internal_unref(grpc_exec_ctx *exec_ctx,
 | 
	
		
			
				|  |  | -                                 grpc_channel *channel) {
 | 
	
		
			
				|  |  | -#endif
 | 
	
		
			
				|  |  | -  if (gpr_unref(&channel->refs)) {
 | 
	
		
			
				|  |  | -    destroy_channel(exec_ctx, channel);
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  void grpc_channel_destroy(grpc_channel *channel) {
 | 
	
		
			
				|  |  |    grpc_transport_op op;
 | 
	
		
			
				|  |  |    grpc_channel_element *elem;
 |