|  | @@ -98,9 +98,9 @@ class PickFirst : public LoadBalancingPolicy {
 | 
	
		
			
				|  |  |    void DestroyUnselectedSubchannelsLocked();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // All our subchannels.
 | 
	
		
			
				|  |  | -  RefCountedPtr<PickFirstSubchannelList> subchannel_list_;
 | 
	
		
			
				|  |  | +  OrphanablePtr<PickFirstSubchannelList> subchannel_list_;
 | 
	
		
			
				|  |  |    // Latest pending subchannel list.
 | 
	
		
			
				|  |  | -  RefCountedPtr<PickFirstSubchannelList> latest_pending_subchannel_list_;
 | 
	
		
			
				|  |  | +  OrphanablePtr<PickFirstSubchannelList> latest_pending_subchannel_list_;
 | 
	
		
			
				|  |  |    // Selected subchannel in \a subchannel_list_.
 | 
	
		
			
				|  |  |    PickFirstSubchannelData* selected_ = nullptr;
 | 
	
		
			
				|  |  |    // Have we started picking?
 | 
	
	
		
			
				|  | @@ -160,14 +160,8 @@ void PickFirst::ShutdownLocked() {
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN,
 | 
	
		
			
				|  |  |                                GRPC_ERROR_REF(error), "shutdown");
 | 
	
		
			
				|  |  | -  if (subchannel_list_ != nullptr) {
 | 
	
		
			
				|  |  | -    subchannel_list_->ShutdownLocked("pf_shutdown");
 | 
	
		
			
				|  |  | -    subchannel_list_.reset();
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -  if (latest_pending_subchannel_list_ != nullptr) {
 | 
	
		
			
				|  |  | -    latest_pending_subchannel_list_->ShutdownLocked("pf_shutdown");
 | 
	
		
			
				|  |  | -    latest_pending_subchannel_list_.reset();
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | +  subchannel_list_.reset();
 | 
	
		
			
				|  |  | +  latest_pending_subchannel_list_.reset();
 | 
	
		
			
				|  |  |    TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_CANCELLED);
 | 
	
		
			
				|  |  |    GRPC_ERROR_UNREF(error);
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -300,7 +294,7 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) {
 | 
	
		
			
				|  |  |              "Pick First %p received update with %" PRIuPTR " addresses", this,
 | 
	
		
			
				|  |  |              addresses->num_addresses);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  auto subchannel_list = MakeRefCounted<PickFirstSubchannelList>(
 | 
	
		
			
				|  |  | +  auto subchannel_list = MakeOrphanable<PickFirstSubchannelList>(
 | 
	
		
			
				|  |  |        this, &grpc_lb_pick_first_trace, addresses, combiner(),
 | 
	
		
			
				|  |  |        client_channel_factory(), args);
 | 
	
		
			
				|  |  |    if (subchannel_list->num_subchannels() == 0) {
 | 
	
	
		
			
				|  | @@ -310,9 +304,6 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) {
 | 
	
		
			
				|  |  |          &state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
 | 
	
		
			
				|  |  |          GRPC_ERROR_CREATE_FROM_STATIC_STRING("Empty update"),
 | 
	
		
			
				|  |  |          "pf_update_empty");
 | 
	
		
			
				|  |  | -    if (subchannel_list_ != nullptr) {
 | 
	
		
			
				|  |  | -      subchannel_list_->ShutdownLocked("sl_shutdown_empty_update");
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  |      subchannel_list_ = std::move(subchannel_list);  // Empty list.
 | 
	
		
			
				|  |  |      selected_ = nullptr;
 | 
	
		
			
				|  |  |      return;
 | 
	
	
		
			
				|  | @@ -320,9 +311,6 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) {
 | 
	
		
			
				|  |  |    if (selected_ == nullptr) {
 | 
	
		
			
				|  |  |      // We don't yet have a selected subchannel, so replace the current
 | 
	
		
			
				|  |  |      // subchannel list immediately.
 | 
	
		
			
				|  |  | -    if (subchannel_list_ != nullptr) {
 | 
	
		
			
				|  |  | -      subchannel_list_->ShutdownLocked("pf_update_before_selected");
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  |      subchannel_list_ = std::move(subchannel_list);
 | 
	
		
			
				|  |  |      // If we've started picking, start trying to connect to the first
 | 
	
		
			
				|  |  |      // subchannel in the new list.
 | 
	
	
		
			
				|  | @@ -347,20 +335,13 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) {
 | 
	
		
			
				|  |  |            sd->SetConnectedSubchannelFromLocked(selected_);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          selected_ = sd;
 | 
	
		
			
				|  |  | -        if (subchannel_list_ != nullptr) {
 | 
	
		
			
				|  |  | -          subchannel_list_->ShutdownLocked("pf_update_includes_selected");
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  |          subchannel_list_ = std::move(subchannel_list);
 | 
	
		
			
				|  |  |          DestroyUnselectedSubchannelsLocked();
 | 
	
		
			
				|  |  |          sd->StartOrRenewConnectivityWatchLocked();
 | 
	
		
			
				|  |  |          // If there was a previously pending update (which may or may
 | 
	
		
			
				|  |  |          // not have contained the currently selected subchannel), drop
 | 
	
		
			
				|  |  |          // it, so that it doesn't override what we've done here.
 | 
	
		
			
				|  |  | -        if (latest_pending_subchannel_list_ != nullptr) {
 | 
	
		
			
				|  |  | -          latest_pending_subchannel_list_->ShutdownLocked(
 | 
	
		
			
				|  |  | -              "pf_update_includes_selected+outdated");
 | 
	
		
			
				|  |  | -          latest_pending_subchannel_list_.reset();
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +        latest_pending_subchannel_list_.reset();
 | 
	
		
			
				|  |  |          return;
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |      }
 | 
	
	
		
			
				|  | @@ -376,7 +357,6 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) {
 | 
	
		
			
				|  |  |                  this, latest_pending_subchannel_list_.get(),
 | 
	
		
			
				|  |  |                  subchannel_list.get());
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  | -      latest_pending_subchannel_list_->ShutdownLocked("sl_outdated_dont_smash");
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |      latest_pending_subchannel_list_ = std::move(subchannel_list);
 | 
	
		
			
				|  |  |      // If we've started picking, start trying to connect to the first
 | 
	
	
		
			
				|  | @@ -404,8 +384,8 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    // The notification must be for a subchannel in either the current or
 | 
	
		
			
				|  |  |    // latest pending subchannel lists.
 | 
	
		
			
				|  |  | -  GPR_ASSERT(p->subchannel_list_ == subchannel_list() ||
 | 
	
		
			
				|  |  | -             p->latest_pending_subchannel_list_ == subchannel_list());
 | 
	
		
			
				|  |  | +  GPR_ASSERT(subchannel_list() == p->subchannel_list_.get() ||
 | 
	
		
			
				|  |  | +             subchannel_list() == p->latest_pending_subchannel_list_.get());
 | 
	
		
			
				|  |  |    // Handle updates for the currently selected subchannel.
 | 
	
		
			
				|  |  |    if (p->selected_ == this) {
 | 
	
		
			
				|  |  |      // If the new state is anything other than READY and there is a
 | 
	
	
		
			
				|  | @@ -414,7 +394,6 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
 | 
	
		
			
				|  |  |          p->latest_pending_subchannel_list_ != nullptr) {
 | 
	
		
			
				|  |  |        p->selected_ = nullptr;
 | 
	
		
			
				|  |  |        StopConnectivityWatchLocked();
 | 
	
		
			
				|  |  | -      subchannel_list()->ShutdownLocked("selected_not_ready+switch_to_update");
 | 
	
		
			
				|  |  |        p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_);
 | 
	
		
			
				|  |  |        grpc_connectivity_state_set(
 | 
	
		
			
				|  |  |            &p->state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
 | 
	
	
		
			
				|  | @@ -460,9 +439,8 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
 | 
	
		
			
				|  |  |      case GRPC_CHANNEL_READY: {
 | 
	
		
			
				|  |  |        // Case 2.  Promote p->latest_pending_subchannel_list_ to
 | 
	
		
			
				|  |  |        // p->subchannel_list_.
 | 
	
		
			
				|  |  | -      if (p->latest_pending_subchannel_list_ == subchannel_list()) {
 | 
	
		
			
				|  |  | +      if (subchannel_list() == p->latest_pending_subchannel_list_.get()) {
 | 
	
		
			
				|  |  |          GPR_ASSERT(p->subchannel_list_ != nullptr);
 | 
	
		
			
				|  |  | -        p->subchannel_list_->ShutdownLocked("finish_update");
 | 
	
		
			
				|  |  |          p->subchannel_list_ = std::move(p->latest_pending_subchannel_list_);
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |        // Cases 1 and 2.
 | 
	
	
		
			
				|  | @@ -502,7 +480,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
 | 
	
		
			
				|  |  |        } while (sd->subchannel() == nullptr);
 | 
	
		
			
				|  |  |        // Case 1: Only set state to TRANSIENT_FAILURE if we've tried
 | 
	
		
			
				|  |  |        // all subchannels.
 | 
	
		
			
				|  |  | -      if (sd->Index() == 0 && p->subchannel_list_ == subchannel_list()) {
 | 
	
		
			
				|  |  | +      if (sd->Index() == 0 && subchannel_list() == p->subchannel_list_.get()) {
 | 
	
		
			
				|  |  |          grpc_connectivity_state_set(
 | 
	
		
			
				|  |  |              &p->state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
 | 
	
		
			
				|  |  |              GRPC_ERROR_REF(error), "connecting_transient_failure");
 | 
	
	
		
			
				|  | @@ -513,7 +491,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
 | 
	
		
			
				|  |  |      case GRPC_CHANNEL_CONNECTING:
 | 
	
		
			
				|  |  |      case GRPC_CHANNEL_IDLE: {
 | 
	
		
			
				|  |  |        // Only update connectivity state in case 1.
 | 
	
		
			
				|  |  | -      if (p->subchannel_list_ == subchannel_list()) {
 | 
	
		
			
				|  |  | +      if (subchannel_list() == p->subchannel_list_.get()) {
 | 
	
		
			
				|  |  |          grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_CONNECTING,
 | 
	
		
			
				|  |  |                                      GRPC_ERROR_REF(error),
 | 
	
		
			
				|  |  |                                      "connecting_changed");
 |