Immediately orphan watcher if state is SHUTDOWN when it is added.

reviewable/pr20406/r10
Mark D. Roth 5 years ago
parent cb67811c47
commit dbad2db848
  1. 6
      src/core/lib/transport/connectivity_state.cc
  2. 4
      src/core/lib/transport/connectivity_state.h
  3. 34
      test/core/transport/connectivity_state_test.cc

@ -120,7 +120,11 @@ void ConnectivityStateTracker::AddWatcher(
}
watcher->Notify(current_state);
}
watchers_.insert(MakePair(watcher.get(), std::move(watcher)));
// If we're in state SHUTDOWN, don't add the watcher, so that it will
// be orphaned immediately.
if (current_state != GRPC_CHANNEL_SHUTDOWN) {
watchers_.insert(MakePair(watcher.get(), std::move(watcher)));
}
}
void ConnectivityStateTracker::RemoveWatcher(

@ -76,6 +76,10 @@ class AsyncConnectivityStateWatcherInterface
// Tracks connectivity state. Maintains a list of watchers that are
// notified whenever the state changes.
//
// Note that once the state becomes SHUTDOWN, watchers will be notified
// and then automatically orphaned (i.e., RemoveWatcher() does not need
// to be called).
class ConnectivityStateTracker {
public:
ConnectivityStateTracker(const char* name,

@ -113,6 +113,40 @@ TEST(StateTracker, SubscribeThenUnsubscribe) {
EXPECT_EQ(state, GRPC_CHANNEL_IDLE);
}
TEST(StateTracker, OrphanUponShutdown) {
int count = 0;
grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
bool destroyed = false;
ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_IDLE);
ConnectivityStateWatcherInterface* watcher =
New<Watcher>(&count, &state, &destroyed);
tracker.AddWatcher(GRPC_CHANNEL_IDLE,
OrphanablePtr<ConnectivityStateWatcherInterface>(watcher));
// No initial notification, since we started the watch from the
// current state.
EXPECT_EQ(count, 0);
EXPECT_EQ(state, GRPC_CHANNEL_IDLE);
// Set state to SHUTDOWN.
tracker.SetState(GRPC_CHANNEL_SHUTDOWN, "shutting down");
EXPECT_TRUE(destroyed);
EXPECT_EQ(count, 1);
EXPECT_EQ(state, GRPC_CHANNEL_SHUTDOWN);
}
TEST(StateTracker, AddWhenAlreadyShutdown) {
int count = 0;
grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
bool destroyed = false;
ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_SHUTDOWN);
ConnectivityStateWatcherInterface* watcher =
New<Watcher>(&count, &state, &destroyed);
tracker.AddWatcher(GRPC_CHANNEL_IDLE,
OrphanablePtr<ConnectivityStateWatcherInterface>(watcher));
EXPECT_TRUE(destroyed);
EXPECT_EQ(count, 1);
EXPECT_EQ(state, GRPC_CHANNEL_SHUTDOWN);
}
TEST(StateTracker, NotifyShutdownAtDestruction) {
int count = 0;
grpc_connectivity_state state = GRPC_CHANNEL_IDLE;

Loading…
Cancel
Save