|  | @@ -61,6 +61,9 @@ typedef struct {
 | 
	
		
			
				|  |  |    grpc_iomgr_closure *notify;
 | 
	
		
			
				|  |  |    grpc_connect_in_args args;
 | 
	
		
			
				|  |  |    grpc_connect_out_args *result;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  gpr_mu mu;
 | 
	
		
			
				|  |  | +  grpc_endpoint *connecting_endpoint;
 | 
	
		
			
				|  |  |  } connector;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void connector_ref(grpc_connector *con) {
 | 
	
	
		
			
				|  | @@ -81,10 +84,20 @@ static void on_secure_transport_setup_done(void *arg,
 | 
	
		
			
				|  |  |                                             grpc_endpoint *secure_endpoint) {
 | 
	
		
			
				|  |  |    connector *c = arg;
 | 
	
		
			
				|  |  |    grpc_iomgr_closure *notify;
 | 
	
		
			
				|  |  | -  if (status != GRPC_SECURITY_OK) {
 | 
	
		
			
				|  |  | +  gpr_mu_lock(&c->mu);
 | 
	
		
			
				|  |  | +  if (c->connecting_endpoint == NULL) {
 | 
	
		
			
				|  |  | +    memset(c->result, 0, sizeof(*c->result));
 | 
	
		
			
				|  |  | +    gpr_mu_unlock(&c->mu);
 | 
	
		
			
				|  |  | +  } else if (status != GRPC_SECURITY_OK) {
 | 
	
		
			
				|  |  | +    GPR_ASSERT(c->connecting_endpoint == wrapped_endpoint);
 | 
	
		
			
				|  |  |      gpr_log(GPR_ERROR, "Secure transport setup failed with error %d.", status);
 | 
	
		
			
				|  |  |      memset(c->result, 0, sizeof(*c->result));
 | 
	
		
			
				|  |  | +    c->connecting_endpoint = NULL;
 | 
	
		
			
				|  |  | +    gpr_mu_unlock(&c->mu);
 | 
	
		
			
				|  |  |    } else {
 | 
	
		
			
				|  |  | +    GPR_ASSERT(c->connecting_endpoint == wrapped_endpoint);
 | 
	
		
			
				|  |  | +    c->connecting_endpoint = NULL;
 | 
	
		
			
				|  |  | +    gpr_mu_unlock(&c->mu);
 | 
	
		
			
				|  |  |      c->result->transport = grpc_create_chttp2_transport(
 | 
	
		
			
				|  |  |          c->args.channel_args, secure_endpoint, c->args.metadata_context, 1);
 | 
	
		
			
				|  |  |      grpc_chttp2_transport_start_reading(c->result->transport, NULL, 0);
 | 
	
	
		
			
				|  | @@ -102,6 +115,10 @@ static void connected(void *arg, grpc_endpoint *tcp) {
 | 
	
		
			
				|  |  |    connector *c = arg;
 | 
	
		
			
				|  |  |    grpc_iomgr_closure *notify;
 | 
	
		
			
				|  |  |    if (tcp != NULL) {
 | 
	
		
			
				|  |  | +    gpr_mu_lock(&c->mu);
 | 
	
		
			
				|  |  | +    GPR_ASSERT(c->connecting_endpoint == NULL);
 | 
	
		
			
				|  |  | +    c->connecting_endpoint = tcp;
 | 
	
		
			
				|  |  | +    gpr_mu_unlock(&c->mu);
 | 
	
		
			
				|  |  |      grpc_setup_secure_transport(&c->security_connector->base, tcp,
 | 
	
		
			
				|  |  |                                  on_secure_transport_setup_done, c);
 | 
	
		
			
				|  |  |    } else {
 | 
	
	
		
			
				|  | @@ -112,6 +129,18 @@ static void connected(void *arg, grpc_endpoint *tcp) {
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +static void connector_shutdown(grpc_connector *con) {
 | 
	
		
			
				|  |  | +  connector *c = (connector *)con;
 | 
	
		
			
				|  |  | +  grpc_endpoint *ep;
 | 
	
		
			
				|  |  | +  gpr_mu_lock(&c->mu);
 | 
	
		
			
				|  |  | +  ep = c->connecting_endpoint;
 | 
	
		
			
				|  |  | +  c->connecting_endpoint = NULL;
 | 
	
		
			
				|  |  | +  gpr_mu_unlock(&c->mu);
 | 
	
		
			
				|  |  | +  if (ep) {
 | 
	
		
			
				|  |  | +    grpc_endpoint_shutdown(ep);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  static void connector_connect(grpc_connector *con,
 | 
	
		
			
				|  |  |                                const grpc_connect_in_args *args,
 | 
	
		
			
				|  |  |                                grpc_connect_out_args *result,
 | 
	
	
		
			
				|  | @@ -122,12 +151,15 @@ static void connector_connect(grpc_connector *con,
 | 
	
		
			
				|  |  |    c->notify = notify;
 | 
	
		
			
				|  |  |    c->args = *args;
 | 
	
		
			
				|  |  |    c->result = result;
 | 
	
		
			
				|  |  | +  gpr_mu_lock(&c->mu);
 | 
	
		
			
				|  |  | +  GPR_ASSERT(c->connecting_endpoint == NULL);
 | 
	
		
			
				|  |  | +  gpr_mu_unlock(&c->mu);
 | 
	
		
			
				|  |  |    grpc_tcp_client_connect(connected, c, args->interested_parties, args->addr,
 | 
	
		
			
				|  |  |                            args->addr_len, args->deadline);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static const grpc_connector_vtable connector_vtable = {
 | 
	
		
			
				|  |  | -    connector_ref, connector_unref, connector_connect};
 | 
	
		
			
				|  |  | +    connector_ref, connector_unref, connector_shutdown, connector_connect};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  typedef struct {
 | 
	
		
			
				|  |  |    grpc_subchannel_factory base;
 |