aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc27
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/subchannel_list.h14
2 files changed, 16 insertions, 25 deletions
diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
index 1fecdebccf..2d9e4af96c 100644
--- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
@@ -332,18 +332,23 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) {
this, selected_->subchannel(), i,
subchannel_list->num_subchannels());
}
- if (selected_->connected_subchannel() != nullptr) {
- sd->SetConnectedSubchannelFromLocked(selected_);
+ // Make sure it's in state READY. It might not be if we grabbed
+ // the combiner while a connectivity state notification
+ // informing us otherwise is pending.
+ // Note that CheckConnectivityStateLocked() also takes a ref to
+ // the connected subchannel.
+ grpc_error* error = GRPC_ERROR_NONE;
+ if (sd->CheckConnectivityStateLocked(&error) == GRPC_CHANNEL_READY) {
+ selected_ = sd;
+ subchannel_list_ = std::move(subchannel_list);
+ DestroyUnselectedSubchannelsLocked();
+ sd->StartConnectivityWatchLocked();
+ // 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.
+ latest_pending_subchannel_list_.reset();
+ return;
}
- selected_ = sd;
- subchannel_list_ = std::move(subchannel_list);
- DestroyUnselectedSubchannelsLocked();
- sd->StartConnectivityWatchLocked();
- // 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.
- latest_pending_subchannel_list_.reset();
- return;
}
}
// Not keeping the previous selected subchannel, so set the latest
diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
index bad50c461c..276a2f08a1 100644
--- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
+++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
@@ -89,20 +89,6 @@ class SubchannelData {
return connected_subchannel_.get();
}
-// FIXME: remove
- // Used to set the connected subchannel in cases where we are retaining a
- // subchannel from a previous subchannel list. This is slightly more
- // efficient than getting the connected subchannel from the subchannel,
- // because that approach requires the use of a mutex, whereas this one
- // only mutates a refcount.
- // TODO(roth): This method is a bit of a hack and is used only in
- // pick_first. When we have time, find a way to remove this, possibly
- // by making pick_first work more like round_robin.
- void SetConnectedSubchannelFromLocked(SubchannelData* other) {
- GPR_ASSERT(subchannel_ == other->subchannel_);
- connected_subchannel_ = other->connected_subchannel_; // Adds ref.
- }
-
// Synchronously checks the subchannel's connectivity state.
// Must not be called while there is a connectivity notification
// pending (i.e., between calling StartConnectivityWatchLocked() or