| 
					
				 | 
			
			
				@@ -40,7 +40,6 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "src/core/channel/connected_channel.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "src/core/surface/channel.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "src/core/iomgr/iomgr.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-#include "src/core/iomgr/pollset_set.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "src/core/support/string.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include "src/core/transport/connectivity_state.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #include <grpc/support/alloc.h> 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -77,8 +76,22 @@ typedef struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_iomgr_closure on_config_changed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   /** connectivity state being tracked */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_connectivity_state_tracker state_tracker; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /** when an lb_policy arrives, should we try to exit idle */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int exit_idle_when_lb_policy_arrives; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /** pollset_set of interested parties in a new connection */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set pollset_set; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } channel_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** We create one watcher for each new lb_policy that is returned from a resolver, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    to watch for state changes from the lb_policy. When a state change is seen, we 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    update the channel, and create a new watcher */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+typedef struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  channel_data *chand; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_iomgr_closure on_changed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_connectivity_state state; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_lb_policy *lb_policy; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} lb_policy_connectivity_watcher; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 typedef enum { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   CALL_CREATED, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   CALL_WAITING_FOR_SEND, 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -408,16 +421,53 @@ static void cc_start_transport_stream_op(grpc_call_element *elem, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   perform_transport_stream_op(elem, op, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void watch_lb_policy(channel_data *chand, grpc_lb_policy *lb_policy, grpc_connectivity_state current_state); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void on_lb_policy_state_changed(void *arg, int iomgr_success) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  lb_policy_connectivity_watcher *w = arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_mu_lock(&w->chand->mu_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* check if the notification is for a stale policy */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (w->lb_policy == w->chand->lb_policy) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_connectivity_state_set(&w->chand->state_tracker, w->state, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                "lb_changed"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (w->state != GRPC_CHANNEL_FATAL_FAILURE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      watch_lb_policy(w->chand, w->lb_policy, w->state); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_mu_unlock(&w->chand->mu_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GRPC_CHANNEL_INTERNAL_UNREF(w->chand->master, "watch_lb_policy"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_free(w); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void watch_lb_policy(channel_data *chand, grpc_lb_policy *lb_policy, grpc_connectivity_state current_state) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  lb_policy_connectivity_watcher *w = gpr_malloc(sizeof(*w)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GRPC_CHANNEL_INTERNAL_REF(chand->master, "watch_lb_policy"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  w->chand = chand; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_iomgr_closure_init(&w->on_changed, on_lb_policy_state_changed, w); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  w->state = current_state; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  w->lb_policy = lb_policy; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_lb_policy_notify_on_state_change(lb_policy, &w->state, &w->on_changed); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void cc_on_config_changed(void *arg, int iomgr_success) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   channel_data *chand = arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_lb_policy *lb_policy = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_lb_policy *old_lb_policy; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_resolver *old_resolver; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_iomgr_closure *wakeup_closures = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_connectivity_state state = GRPC_CHANNEL_TRANSIENT_FAILURE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int exit_idle = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (chand->incoming_configuration != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     lb_policy = grpc_client_config_get_lb_policy(chand->incoming_configuration); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    GRPC_LB_POLICY_REF(lb_policy, "channel"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (lb_policy != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      GRPC_LB_POLICY_REF(lb_policy, "channel"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      GRPC_LB_POLICY_REF(lb_policy, "config_change"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      state = grpc_lb_policy_check_connectivity(lb_policy); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     grpc_client_config_unref(chand->incoming_configuration); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -431,13 +481,12 @@ static void cc_on_config_changed(void *arg, int iomgr_success) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     wakeup_closures = chand->waiting_for_config_closures; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     chand->waiting_for_config_closures = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  gpr_mu_unlock(&chand->mu_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (old_lb_policy) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    GRPC_LB_POLICY_UNREF(old_lb_policy, "channel"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (lb_policy != NULL && chand->exit_idle_when_lb_policy_arrives) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    GRPC_LB_POLICY_REF(lb_policy, "exit_idle"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exit_idle = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    chand->exit_idle_when_lb_policy_arrives = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  gpr_mu_lock(&chand->mu_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (iomgr_success && chand->resolver) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     grpc_resolver *resolver = chand->resolver; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GRPC_RESOLVER_REF(resolver, "channel-next"); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -446,11 +495,16 @@ static void cc_on_config_changed(void *arg, int iomgr_success) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     grpc_resolver_next(resolver, &chand->incoming_configuration, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                        &chand->on_config_changed); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GRPC_RESOLVER_UNREF(resolver, "channel-next"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_connectivity_state_set(&chand->state_tracker, state, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                "new_lb+resolver"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (lb_policy != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      watch_lb_policy(chand, lb_policy, state); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     old_resolver = chand->resolver; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     chand->resolver = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     grpc_connectivity_state_set(&chand->state_tracker, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                GRPC_CHANNEL_FATAL_FAILURE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                GRPC_CHANNEL_FATAL_FAILURE, "resolver_gone"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     gpr_mu_unlock(&chand->mu_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (old_resolver != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       grpc_resolver_shutdown(old_resolver); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -458,12 +512,24 @@ static void cc_on_config_changed(void *arg, int iomgr_success) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (exit_idle) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_lb_policy_exit_idle(lb_policy); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    GRPC_LB_POLICY_UNREF(lb_policy, "exit_idle"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (old_lb_policy != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    GRPC_LB_POLICY_UNREF(old_lb_policy, "channel"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   while (wakeup_closures) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     grpc_iomgr_closure *next = wakeup_closures->next; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     wakeup_closures->cb(wakeup_closures->cb_arg, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     wakeup_closures = next; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (lb_policy != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    GRPC_LB_POLICY_UNREF(lb_policy, "config_change"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   GRPC_CHANNEL_INTERNAL_UNREF(chand->master, "resolver"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -487,20 +553,22 @@ static void cc_start_transport_op(grpc_channel_element *elem, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     op->connectivity_state = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (!is_empty(op, sizeof(*op))) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    lb_policy = chand->lb_policy; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (lb_policy) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      GRPC_LB_POLICY_REF(lb_policy, "broadcast"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (op->disconnect && chand->resolver != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     grpc_connectivity_state_set(&chand->state_tracker, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                GRPC_CHANNEL_FATAL_FAILURE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                GRPC_CHANNEL_FATAL_FAILURE, "disconnect"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     destroy_resolver = chand->resolver; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     chand->resolver = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if (chand->lb_policy != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       grpc_lb_policy_shutdown(chand->lb_policy); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (!is_empty(op, sizeof(*op))) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    lb_policy = chand->lb_policy; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (lb_policy) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      GRPC_LB_POLICY_REF(lb_policy, "broadcast"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      GRPC_LB_POLICY_UNREF(chand->lb_policy, "channel"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      chand->lb_policy = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   gpr_mu_unlock(&chand->mu_config); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -581,10 +649,11 @@ static void init_channel_elem(grpc_channel_element *elem, grpc_channel *master, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   gpr_mu_init(&chand->mu_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   chand->mdctx = metadata_context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   chand->master = master; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_init(&chand->pollset_set); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_iomgr_closure_init(&chand->on_config_changed, cc_on_config_changed, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                           chand); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE, "client_channel"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /* Destructor for channel_data */ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -598,6 +667,8 @@ static void destroy_channel_elem(grpc_channel_element *elem) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (chand->lb_policy != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     GRPC_LB_POLICY_UNREF(chand->lb_policy, "channel"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_connectivity_state_destroy(&chand->state_tracker); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_destroy(&chand->pollset_set); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   gpr_mu_destroy(&chand->mu_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -626,3 +697,47 @@ void grpc_client_channel_set_resolver(grpc_channel_stack *channel_stack, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   grpc_resolver_next(resolver, &chand->incoming_configuration, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                      &chand->on_config_changed); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+grpc_connectivity_state grpc_client_channel_check_connectivity_state( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_channel_element *elem, int try_to_connect) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  channel_data *chand = elem->channel_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_connectivity_state out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_mu_lock(&chand->mu_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  out = grpc_connectivity_state_check(&chand->state_tracker); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (out == GRPC_CHANNEL_IDLE && try_to_connect) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (chand->lb_policy != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      grpc_lb_policy_exit_idle(chand->lb_policy); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      chand->exit_idle_when_lb_policy_arrives = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_mu_unlock(&chand->mu_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void grpc_client_channel_watch_connectivity_state( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_channel_element *elem, grpc_connectivity_state *state, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_iomgr_closure *on_complete) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  channel_data *chand = elem->channel_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_mu_lock(&chand->mu_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_connectivity_state_notify_on_state_change(&chand->state_tracker, state, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                 on_complete); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_mu_unlock(&chand->mu_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+grpc_pollset_set *grpc_client_channel_get_connecting_pollset_set(grpc_channel_element *elem) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  channel_data *chand = elem->channel_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return &chand->pollset_set; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void grpc_client_channel_add_interested_party(grpc_channel_element *elem, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                          grpc_pollset *pollset) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  channel_data *chand = elem->channel_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_add_pollset(&chand->pollset_set, pollset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void grpc_client_channel_del_interested_party(grpc_channel_element *elem, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                          grpc_pollset *pollset) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  channel_data *chand = elem->channel_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_del_pollset(&chand->pollset_set, pollset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 |