[flake] Fix tsan error surfaced by grpc_lb_end2end_test (#37663)

Pretty sure that the `LoadBalancedCall` instance is getting dropped before return on *some* path through `PickSubchannel`, although it's unclear to me which and it's hard to tell with this implementation.

Ensure that such an event cannot cause a crash by holding a ref to the object we need and calling through that.

This will be marginally worse performance per pick for now, but once work serializer dispatch lands everywhere the additional ref will disappear.

Closes #37663

COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/37663 from ctiller:flake-fightas-3 d12b2e0540
PiperOrigin-RevId: 673088001
pull/37671/head
Craig Tiller 3 months ago committed by Copybara-Service
parent 648304df01
commit c831e1de79
  1. 21
      src/core/client_channel/client_channel_filter.cc

@ -2518,16 +2518,17 @@ ClientChannelFilter::LoadBalancedCall::PickSubchannel(bool was_queued) {
// updated before we queue it.
// We need to unref pickers in the WorkSerializer.
std::vector<RefCountedPtr<LoadBalancingPolicy::SubchannelPicker>> pickers;
auto cleanup = absl::MakeCleanup([&]() {
if (IsWorkSerializerDispatchEnabled()) return;
chand_->work_serializer_->Run(
[pickers = std::move(pickers)]() mutable {
for (auto& picker : pickers) {
picker.reset(DEBUG_LOCATION, "PickSubchannel");
}
},
DEBUG_LOCATION);
});
auto cleanup = absl::MakeCleanup(
[work_serializer = chand_->work_serializer_, &pickers]() {
if (IsWorkSerializerDispatchEnabled()) return;
work_serializer->Run(
[pickers = std::move(pickers)]() mutable {
for (auto& picker : pickers) {
picker.reset(DEBUG_LOCATION, "PickSubchannel");
}
},
DEBUG_LOCATION);
});
absl::AnyInvocable<void(RefCountedPtr<LoadBalancingPolicy::SubchannelPicker>)>
set_picker;
if (!IsWorkSerializerDispatchEnabled()) {

Loading…
Cancel
Save