|  | @@ -65,8 +65,6 @@ struct grpc_ares_request {
 | 
	
		
			
				|  |  |    /** number of ongoing queries */
 | 
	
		
			
				|  |  |    gpr_refcount pending_queries;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  /** mutex guarding the rest of the state */
 | 
	
		
			
				|  |  | -  gpr_mu mu;
 | 
	
		
			
				|  |  |    /** is there at least one successful query, set in on_done_cb */
 | 
	
		
			
				|  |  |    bool success;
 | 
	
		
			
				|  |  |    /** the errors explaining the request failure, set in on_done_cb */
 | 
	
	
		
			
				|  | @@ -74,7 +72,8 @@ struct grpc_ares_request {
 | 
	
		
			
				|  |  |  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  typedef struct grpc_ares_hostbyname_request {
 | 
	
		
			
				|  |  | -  /** following members are set in create_hostbyname_request */
 | 
	
		
			
				|  |  | +  /** following members are set in create_hostbyname_request_locked
 | 
	
		
			
				|  |  | +   */
 | 
	
		
			
				|  |  |    /** the top-level request instance */
 | 
	
		
			
				|  |  |    grpc_ares_request* parent_request;
 | 
	
		
			
				|  |  |    /** host to resolve, parsed from the name to resolve */
 | 
	
	
		
			
				|  | @@ -96,10 +95,6 @@ static uint16_t strhtons(const char* port) {
 | 
	
		
			
				|  |  |    return htons(static_cast<unsigned short>(atoi(port)));
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void grpc_ares_request_ref(grpc_ares_request* r) {
 | 
	
		
			
				|  |  | -  gpr_ref(&r->pending_queries);
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  static void log_address_sorting_list(grpc_lb_addresses* lb_addrs,
 | 
	
		
			
				|  |  |                                       const char* input_output_str) {
 | 
	
		
			
				|  |  |    for (size_t i = 0; i < lb_addrs->num_addresses; i++) {
 | 
	
	
		
			
				|  | @@ -149,7 +144,11 @@ void grpc_cares_wrapper_test_only_address_sorting_sort(
 | 
	
		
			
				|  |  |    grpc_cares_wrapper_address_sorting_sort(lb_addrs);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void grpc_ares_request_unref(grpc_ares_request* r) {
 | 
	
		
			
				|  |  | +static void grpc_ares_request_ref_locked(grpc_ares_request* r) {
 | 
	
		
			
				|  |  | +  gpr_ref(&r->pending_queries);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static void grpc_ares_request_unref_locked(grpc_ares_request* r) {
 | 
	
		
			
				|  |  |    /* If there are no pending queries, invoke on_done callback and destroy the
 | 
	
		
			
				|  |  |       request */
 | 
	
		
			
				|  |  |    if (gpr_unref(&r->pending_queries)) {
 | 
	
	
		
			
				|  | @@ -158,13 +157,12 @@ static void grpc_ares_request_unref(grpc_ares_request* r) {
 | 
	
		
			
				|  |  |        grpc_cares_wrapper_address_sorting_sort(lb_addrs);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      GRPC_CLOSURE_SCHED(r->on_done, r->error);
 | 
	
		
			
				|  |  | -    gpr_mu_destroy(&r->mu);
 | 
	
		
			
				|  |  | -    grpc_ares_ev_driver_destroy(r->ev_driver);
 | 
	
		
			
				|  |  | +    grpc_ares_ev_driver_destroy_locked(r->ev_driver);
 | 
	
		
			
				|  |  |      gpr_free(r);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static grpc_ares_hostbyname_request* create_hostbyname_request(
 | 
	
		
			
				|  |  | +static grpc_ares_hostbyname_request* create_hostbyname_request_locked(
 | 
	
		
			
				|  |  |      grpc_ares_request* parent_request, char* host, uint16_t port,
 | 
	
		
			
				|  |  |      bool is_balancer) {
 | 
	
		
			
				|  |  |    grpc_ares_hostbyname_request* hr = static_cast<grpc_ares_hostbyname_request*>(
 | 
	
	
		
			
				|  | @@ -173,22 +171,22 @@ static grpc_ares_hostbyname_request* create_hostbyname_request(
 | 
	
		
			
				|  |  |    hr->host = gpr_strdup(host);
 | 
	
		
			
				|  |  |    hr->port = port;
 | 
	
		
			
				|  |  |    hr->is_balancer = is_balancer;
 | 
	
		
			
				|  |  | -  grpc_ares_request_ref(parent_request);
 | 
	
		
			
				|  |  | +  grpc_ares_request_ref_locked(parent_request);
 | 
	
		
			
				|  |  |    return hr;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void destroy_hostbyname_request(grpc_ares_hostbyname_request* hr) {
 | 
	
		
			
				|  |  | -  grpc_ares_request_unref(hr->parent_request);
 | 
	
		
			
				|  |  | +static void destroy_hostbyname_request_locked(
 | 
	
		
			
				|  |  | +    grpc_ares_hostbyname_request* hr) {
 | 
	
		
			
				|  |  | +  grpc_ares_request_unref_locked(hr->parent_request);
 | 
	
		
			
				|  |  |    gpr_free(hr->host);
 | 
	
		
			
				|  |  |    gpr_free(hr);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void on_hostbyname_done_cb(void* arg, int status, int timeouts,
 | 
	
		
			
				|  |  | -                                  struct hostent* hostent) {
 | 
	
		
			
				|  |  | +static void on_hostbyname_done_locked(void* arg, int status, int timeouts,
 | 
	
		
			
				|  |  | +                                      struct hostent* hostent) {
 | 
	
		
			
				|  |  |    grpc_ares_hostbyname_request* hr =
 | 
	
		
			
				|  |  |        static_cast<grpc_ares_hostbyname_request*>(arg);
 | 
	
		
			
				|  |  |    grpc_ares_request* r = hr->parent_request;
 | 
	
		
			
				|  |  | -  gpr_mu_lock(&r->mu);
 | 
	
		
			
				|  |  |    if (status == ARES_SUCCESS) {
 | 
	
		
			
				|  |  |      GRPC_ERROR_UNREF(r->error);
 | 
	
		
			
				|  |  |      r->error = GRPC_ERROR_NONE;
 | 
	
	
		
			
				|  | @@ -263,16 +261,15 @@ static void on_hostbyname_done_cb(void* arg, int status, int timeouts,
 | 
	
		
			
				|  |  |        r->error = grpc_error_add_child(error, r->error);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  gpr_mu_unlock(&r->mu);
 | 
	
		
			
				|  |  | -  destroy_hostbyname_request(hr);
 | 
	
		
			
				|  |  | +  destroy_hostbyname_request_locked(hr);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void on_srv_query_done_cb(void* arg, int status, int timeouts,
 | 
	
		
			
				|  |  | -                                 unsigned char* abuf, int alen) {
 | 
	
		
			
				|  |  | +static void on_srv_query_done_locked(void* arg, int status, int timeouts,
 | 
	
		
			
				|  |  | +                                     unsigned char* abuf, int alen) {
 | 
	
		
			
				|  |  |    grpc_ares_request* r = static_cast<grpc_ares_request*>(arg);
 | 
	
		
			
				|  |  | -  gpr_log(GPR_DEBUG, "on_query_srv_done_cb");
 | 
	
		
			
				|  |  | +  gpr_log(GPR_DEBUG, "on_query_srv_done_locked");
 | 
	
		
			
				|  |  |    if (status == ARES_SUCCESS) {
 | 
	
		
			
				|  |  | -    gpr_log(GPR_DEBUG, "on_query_srv_done_cb ARES_SUCCESS");
 | 
	
		
			
				|  |  | +    gpr_log(GPR_DEBUG, "on_query_srv_done_locked ARES_SUCCESS");
 | 
	
		
			
				|  |  |      struct ares_srv_reply* reply;
 | 
	
		
			
				|  |  |      const int parse_status = ares_parse_srv_reply(abuf, alen, &reply);
 | 
	
		
			
				|  |  |      if (parse_status == ARES_SUCCESS) {
 | 
	
	
		
			
				|  | @@ -280,16 +277,16 @@ static void on_srv_query_done_cb(void* arg, int status, int timeouts,
 | 
	
		
			
				|  |  |        for (struct ares_srv_reply* srv_it = reply; srv_it != nullptr;
 | 
	
		
			
				|  |  |             srv_it = srv_it->next) {
 | 
	
		
			
				|  |  |          if (grpc_ipv6_loopback_available()) {
 | 
	
		
			
				|  |  | -          grpc_ares_hostbyname_request* hr = create_hostbyname_request(
 | 
	
		
			
				|  |  | +          grpc_ares_hostbyname_request* hr = create_hostbyname_request_locked(
 | 
	
		
			
				|  |  |                r, srv_it->host, htons(srv_it->port), true /* is_balancer */);
 | 
	
		
			
				|  |  |            ares_gethostbyname(*channel, hr->host, AF_INET6,
 | 
	
		
			
				|  |  | -                             on_hostbyname_done_cb, hr);
 | 
	
		
			
				|  |  | +                             on_hostbyname_done_locked, hr);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        grpc_ares_hostbyname_request* hr = create_hostbyname_request(
 | 
	
		
			
				|  |  | +        grpc_ares_hostbyname_request* hr = create_hostbyname_request_locked(
 | 
	
		
			
				|  |  |              r, srv_it->host, htons(srv_it->port), true /* is_balancer */);
 | 
	
		
			
				|  |  | -        ares_gethostbyname(*channel, hr->host, AF_INET, on_hostbyname_done_cb,
 | 
	
		
			
				|  |  | -                           hr);
 | 
	
		
			
				|  |  | -        grpc_ares_ev_driver_start(r->ev_driver);
 | 
	
		
			
				|  |  | +        ares_gethostbyname(*channel, hr->host, AF_INET,
 | 
	
		
			
				|  |  | +                           on_hostbyname_done_locked, hr);
 | 
	
		
			
				|  |  | +        grpc_ares_ev_driver_start_locked(r->ev_driver);
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      if (reply != nullptr) {
 | 
	
	
		
			
				|  | @@ -307,21 +304,20 @@ static void on_srv_query_done_cb(void* arg, int status, int timeouts,
 | 
	
		
			
				|  |  |        r->error = grpc_error_add_child(error, r->error);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  grpc_ares_request_unref(r);
 | 
	
		
			
				|  |  | +  grpc_ares_request_unref_locked(r);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static const char g_service_config_attribute_prefix[] = "grpc_config=";
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static void on_txt_done_cb(void* arg, int status, int timeouts,
 | 
	
		
			
				|  |  | -                           unsigned char* buf, int len) {
 | 
	
		
			
				|  |  | -  gpr_log(GPR_DEBUG, "on_txt_done_cb");
 | 
	
		
			
				|  |  | +static void on_txt_done_locked(void* arg, int status, int timeouts,
 | 
	
		
			
				|  |  | +                               unsigned char* buf, int len) {
 | 
	
		
			
				|  |  | +  gpr_log(GPR_DEBUG, "on_txt_done_locked");
 | 
	
		
			
				|  |  |    char* error_msg;
 | 
	
		
			
				|  |  |    grpc_ares_request* r = static_cast<grpc_ares_request*>(arg);
 | 
	
		
			
				|  |  |    const size_t prefix_len = sizeof(g_service_config_attribute_prefix) - 1;
 | 
	
		
			
				|  |  |    struct ares_txt_ext* result = nullptr;
 | 
	
		
			
				|  |  |    struct ares_txt_ext* reply = nullptr;
 | 
	
		
			
				|  |  |    grpc_error* error = GRPC_ERROR_NONE;
 | 
	
		
			
				|  |  | -  gpr_mu_lock(&r->mu);
 | 
	
		
			
				|  |  |    if (status != ARES_SUCCESS) goto fail;
 | 
	
		
			
				|  |  |    status = ares_parse_txt_reply_ext(buf, len, &reply);
 | 
	
		
			
				|  |  |    if (status != ARES_SUCCESS) goto fail;
 | 
	
	
		
			
				|  | @@ -366,14 +362,14 @@ fail:
 | 
	
		
			
				|  |  |      r->error = grpc_error_add_child(error, r->error);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  done:
 | 
	
		
			
				|  |  | -  gpr_mu_unlock(&r->mu);
 | 
	
		
			
				|  |  | -  grpc_ares_request_unref(r);
 | 
	
		
			
				|  |  | +  grpc_ares_request_unref_locked(r);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -static grpc_ares_request* grpc_dns_lookup_ares_impl(
 | 
	
		
			
				|  |  | +static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
 | 
	
		
			
				|  |  |      const char* dns_server, const char* name, const char* default_port,
 | 
	
		
			
				|  |  |      grpc_pollset_set* interested_parties, grpc_closure* on_done,
 | 
	
		
			
				|  |  | -    grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json) {
 | 
	
		
			
				|  |  | +    grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json,
 | 
	
		
			
				|  |  | +    grpc_combiner* combiner) {
 | 
	
		
			
				|  |  |    grpc_error* error = GRPC_ERROR_NONE;
 | 
	
		
			
				|  |  |    grpc_ares_hostbyname_request* hr = nullptr;
 | 
	
		
			
				|  |  |    grpc_ares_request* r = nullptr;
 | 
	
	
		
			
				|  | @@ -402,13 +398,11 @@ static grpc_ares_request* grpc_dns_lookup_ares_impl(
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      port = gpr_strdup(default_port);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    grpc_ares_ev_driver* ev_driver;
 | 
	
		
			
				|  |  | -  error = grpc_ares_ev_driver_create(&ev_driver, interested_parties);
 | 
	
		
			
				|  |  | +  error = grpc_ares_ev_driver_create(&ev_driver, interested_parties, combiner);
 | 
	
		
			
				|  |  |    if (error != GRPC_ERROR_NONE) goto error_cleanup;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    r = static_cast<grpc_ares_request*>(gpr_zalloc(sizeof(grpc_ares_request)));
 | 
	
		
			
				|  |  | -  gpr_mu_init(&r->mu);
 | 
	
		
			
				|  |  |    r->ev_driver = ev_driver;
 | 
	
		
			
				|  |  |    r->on_done = on_done;
 | 
	
		
			
				|  |  |    r->lb_addrs_out = addrs;
 | 
	
	
		
			
				|  | @@ -457,32 +451,34 @@ static grpc_ares_request* grpc_dns_lookup_ares_impl(
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    gpr_ref_init(&r->pending_queries, 1);
 | 
	
		
			
				|  |  |    if (grpc_ipv6_loopback_available()) {
 | 
	
		
			
				|  |  | -    hr = create_hostbyname_request(r, host, strhtons(port),
 | 
	
		
			
				|  |  | -                                   false /* is_balancer */);
 | 
	
		
			
				|  |  | -    ares_gethostbyname(*channel, hr->host, AF_INET6, on_hostbyname_done_cb, hr);
 | 
	
		
			
				|  |  | +    hr = create_hostbyname_request_locked(r, host, strhtons(port),
 | 
	
		
			
				|  |  | +                                          false /* is_balancer */);
 | 
	
		
			
				|  |  | +    ares_gethostbyname(*channel, hr->host, AF_INET6, on_hostbyname_done_locked,
 | 
	
		
			
				|  |  | +                       hr);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  hr = create_hostbyname_request(r, host, strhtons(port),
 | 
	
		
			
				|  |  | -                                 false /* is_balancer */);
 | 
	
		
			
				|  |  | -  ares_gethostbyname(*channel, hr->host, AF_INET, on_hostbyname_done_cb, hr);
 | 
	
		
			
				|  |  | +  hr = create_hostbyname_request_locked(r, host, strhtons(port),
 | 
	
		
			
				|  |  | +                                        false /* is_balancer */);
 | 
	
		
			
				|  |  | +  ares_gethostbyname(*channel, hr->host, AF_INET, on_hostbyname_done_locked,
 | 
	
		
			
				|  |  | +                     hr);
 | 
	
		
			
				|  |  |    if (check_grpclb) {
 | 
	
		
			
				|  |  |      /* Query the SRV record */
 | 
	
		
			
				|  |  | -    grpc_ares_request_ref(r);
 | 
	
		
			
				|  |  | +    grpc_ares_request_ref_locked(r);
 | 
	
		
			
				|  |  |      char* service_name;
 | 
	
		
			
				|  |  |      gpr_asprintf(&service_name, "_grpclb._tcp.%s", host);
 | 
	
		
			
				|  |  | -    ares_query(*channel, service_name, ns_c_in, ns_t_srv, on_srv_query_done_cb,
 | 
	
		
			
				|  |  | -               r);
 | 
	
		
			
				|  |  | +    ares_query(*channel, service_name, ns_c_in, ns_t_srv,
 | 
	
		
			
				|  |  | +               on_srv_query_done_locked, r);
 | 
	
		
			
				|  |  |      gpr_free(service_name);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    if (service_config_json != nullptr) {
 | 
	
		
			
				|  |  | -    grpc_ares_request_ref(r);
 | 
	
		
			
				|  |  | +    grpc_ares_request_ref_locked(r);
 | 
	
		
			
				|  |  |      char* config_name;
 | 
	
		
			
				|  |  |      gpr_asprintf(&config_name, "_grpc_config.%s", host);
 | 
	
		
			
				|  |  | -    ares_search(*channel, config_name, ns_c_in, ns_t_txt, on_txt_done_cb, r);
 | 
	
		
			
				|  |  | +    ares_search(*channel, config_name, ns_c_in, ns_t_txt, on_txt_done_locked,
 | 
	
		
			
				|  |  | +                r);
 | 
	
		
			
				|  |  |      gpr_free(config_name);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  /* TODO(zyc): Handle CNAME records here. */
 | 
	
		
			
				|  |  | -  grpc_ares_ev_driver_start(r->ev_driver);
 | 
	
		
			
				|  |  | -  grpc_ares_request_unref(r);
 | 
	
		
			
				|  |  | +  grpc_ares_ev_driver_start_locked(r->ev_driver);
 | 
	
		
			
				|  |  | +  grpc_ares_request_unref_locked(r);
 | 
	
		
			
				|  |  |    gpr_free(host);
 | 
	
		
			
				|  |  |    gpr_free(port);
 | 
	
		
			
				|  |  |    return r;
 | 
	
	
		
			
				|  | @@ -494,15 +490,15 @@ error_cleanup:
 | 
	
		
			
				|  |  |    return nullptr;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -grpc_ares_request* (*grpc_dns_lookup_ares)(
 | 
	
		
			
				|  |  | +grpc_ares_request* (*grpc_dns_lookup_ares_locked)(
 | 
	
		
			
				|  |  |      const char* dns_server, const char* name, const char* default_port,
 | 
	
		
			
				|  |  |      grpc_pollset_set* interested_parties, grpc_closure* on_done,
 | 
	
		
			
				|  |  | -    grpc_lb_addresses** addrs, bool check_grpclb,
 | 
	
		
			
				|  |  | -    char** service_config_json) = grpc_dns_lookup_ares_impl;
 | 
	
		
			
				|  |  | +    grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json,
 | 
	
		
			
				|  |  | +    grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void grpc_cancel_ares_request(grpc_ares_request* r) {
 | 
	
		
			
				|  |  | -  if (grpc_dns_lookup_ares == grpc_dns_lookup_ares_impl) {
 | 
	
		
			
				|  |  | -    grpc_ares_ev_driver_shutdown(r->ev_driver);
 | 
	
		
			
				|  |  | +  if (grpc_dns_lookup_ares_locked == grpc_dns_lookup_ares_locked_impl) {
 | 
	
		
			
				|  |  | +    grpc_ares_ev_driver_shutdown_locked(r->ev_driver);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -534,6 +530,8 @@ void grpc_ares_cleanup(void) {
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  typedef struct grpc_resolve_address_ares_request {
 | 
	
		
			
				|  |  | +  /* combiner that queries and related callbacks run under */
 | 
	
		
			
				|  |  | +  grpc_combiner* combiner;
 | 
	
		
			
				|  |  |    /** the pointer to receive the resolved addresses */
 | 
	
		
			
				|  |  |    grpc_resolved_addresses** addrs_out;
 | 
	
		
			
				|  |  |    /** currently resolving lb addresses */
 | 
	
	
		
			
				|  | @@ -541,8 +539,14 @@ typedef struct grpc_resolve_address_ares_request {
 | 
	
		
			
				|  |  |    /** closure to call when the resolve_address_ares request completes */
 | 
	
		
			
				|  |  |    grpc_closure* on_resolve_address_done;
 | 
	
		
			
				|  |  |    /** a closure wrapping on_dns_lookup_done_cb, which should be invoked when the
 | 
	
		
			
				|  |  | -      grpc_dns_lookup_ares operation is done. */
 | 
	
		
			
				|  |  | +      grpc_dns_lookup_ares_locked operation is done. */
 | 
	
		
			
				|  |  |    grpc_closure on_dns_lookup_done;
 | 
	
		
			
				|  |  | +  /* target name */
 | 
	
		
			
				|  |  | +  const char* name;
 | 
	
		
			
				|  |  | +  /* default port to use if none is specified */
 | 
	
		
			
				|  |  | +  const char* default_port;
 | 
	
		
			
				|  |  | +  /* pollset_set to be driven by */
 | 
	
		
			
				|  |  | +  grpc_pollset_set* interested_parties;
 | 
	
		
			
				|  |  |  } grpc_resolve_address_ares_request;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static void on_dns_lookup_done_cb(void* arg, grpc_error* error) {
 | 
	
	
		
			
				|  | @@ -566,9 +570,20 @@ static void on_dns_lookup_done_cb(void* arg, grpc_error* error) {
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    GRPC_CLOSURE_SCHED(r->on_resolve_address_done, GRPC_ERROR_REF(error));
 | 
	
		
			
				|  |  |    if (r->lb_addrs != nullptr) grpc_lb_addresses_destroy(r->lb_addrs);
 | 
	
		
			
				|  |  | +  GRPC_COMBINER_UNREF(r->combiner, "on_dns_lookup_done_cb");
 | 
	
		
			
				|  |  |    gpr_free(r);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +static void grpc_resolve_address_invoke_dns_lookup_ares_locked(
 | 
	
		
			
				|  |  | +    void* arg, grpc_error* unused_error) {
 | 
	
		
			
				|  |  | +  grpc_resolve_address_ares_request* r =
 | 
	
		
			
				|  |  | +      static_cast<grpc_resolve_address_ares_request*>(arg);
 | 
	
		
			
				|  |  | +  grpc_dns_lookup_ares_locked(
 | 
	
		
			
				|  |  | +      nullptr /* dns_server */, r->name, r->default_port, r->interested_parties,
 | 
	
		
			
				|  |  | +      &r->on_dns_lookup_done, &r->lb_addrs, false /* check_grpclb */,
 | 
	
		
			
				|  |  | +      nullptr /* service_config_json */, r->combiner);
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  static void grpc_resolve_address_ares_impl(const char* name,
 | 
	
		
			
				|  |  |                                             const char* default_port,
 | 
	
		
			
				|  |  |                                             grpc_pollset_set* interested_parties,
 | 
	
	
		
			
				|  | @@ -577,14 +592,18 @@ static void grpc_resolve_address_ares_impl(const char* name,
 | 
	
		
			
				|  |  |    grpc_resolve_address_ares_request* r =
 | 
	
		
			
				|  |  |        static_cast<grpc_resolve_address_ares_request*>(
 | 
	
		
			
				|  |  |            gpr_zalloc(sizeof(grpc_resolve_address_ares_request)));
 | 
	
		
			
				|  |  | +  r->combiner = grpc_combiner_create();
 | 
	
		
			
				|  |  |    r->addrs_out = addrs;
 | 
	
		
			
				|  |  |    r->on_resolve_address_done = on_done;
 | 
	
		
			
				|  |  |    GRPC_CLOSURE_INIT(&r->on_dns_lookup_done, on_dns_lookup_done_cb, r,
 | 
	
		
			
				|  |  |                      grpc_schedule_on_exec_ctx);
 | 
	
		
			
				|  |  | -  grpc_dns_lookup_ares(nullptr /* dns_server */, name, default_port,
 | 
	
		
			
				|  |  | -                       interested_parties, &r->on_dns_lookup_done, &r->lb_addrs,
 | 
	
		
			
				|  |  | -                       false /* check_grpclb */,
 | 
	
		
			
				|  |  | -                       nullptr /* service_config_json */);
 | 
	
		
			
				|  |  | +  r->name = name;
 | 
	
		
			
				|  |  | +  r->default_port = default_port;
 | 
	
		
			
				|  |  | +  r->interested_parties = interested_parties;
 | 
	
		
			
				|  |  | +  GRPC_CLOSURE_SCHED(
 | 
	
		
			
				|  |  | +      GRPC_CLOSURE_CREATE(grpc_resolve_address_invoke_dns_lookup_ares_locked, r,
 | 
	
		
			
				|  |  | +                          grpc_combiner_scheduler(r->combiner)),
 | 
	
		
			
				|  |  | +      GRPC_ERROR_NONE);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void (*grpc_resolve_address_ares)(
 |