diff options
author | Ben Caimano <ben.caimano@mongodb.com> | 2019-10-21 19:31:44 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-10-21 19:31:44 +0000 |
commit | a843d5a714e415e128916e49b76e2b2d333bb5d8 (patch) | |
tree | a1cfb2fa46a760b5abe89e870f3b29a3619291ab | |
parent | 6cca153f9f75ca29f2cdca65124efb4329771882 (diff) | |
download | mongo-a843d5a714e415e128916e49b76e2b2d333bb5d8.tar.gz |
SERVER-44087 ReplicaSetMonitor shutdowns should synchronize with NetworkInterface shutdown
-rw-r--r-- | src/mongo/client/replica_set_monitor.cpp | 18 | ||||
-rw-r--r-- | src/mongo/client/replica_set_monitor_manager.cpp | 11 |
2 files changed, 25 insertions, 4 deletions
diff --git a/src/mongo/client/replica_set_monitor.cpp b/src/mongo/client/replica_set_monitor.cpp index 689b79de034..05f8d7d63e5 100644 --- a/src/mongo/client/replica_set_monitor.cpp +++ b/src/mongo/client/replica_set_monitor.cpp @@ -1352,11 +1352,27 @@ void SetState::init() { } void SetState::drop() { - isDropped = true; + if (std::exchange(isDropped, true)) { + // If a SetState calls drop() from destruction after the RSMM calls shutdown(), then the + // RSMM's executor may no longer exist. Thus, only drop once. + return; + } currentScan.reset(); notify(); + if (auto handle = std::exchange(refresherHandle, {})) { + // Cancel our refresh on the way out + executor->cancel(handle); + } + + for (auto& node : nodes) { + if (auto handle = std::exchange(node.scheduledIsMasterHandle, {})) { + // Cancel any isMasters we had scheduled + executor->cancel(handle); + } + } + // No point in notifying if we never started if (workingConnStr.isValid()) { notifier->onDroppedSet(name); diff --git a/src/mongo/client/replica_set_monitor_manager.cpp b/src/mongo/client/replica_set_monitor_manager.cpp index cb6c5094e75..96d270a5e4e 100644 --- a/src/mongo/client/replica_set_monitor_manager.cpp +++ b/src/mongo/client/replica_set_monitor_manager.cpp @@ -160,6 +160,7 @@ void ReplicaSetMonitorManager::shutdown() { // done. decltype(_monitors) monitors; + decltype(_taskExecutor) taskExecutor; { stdx::lock_guard<Latch> lk(_mutex); if (std::exchange(_isShutdown, true)) { @@ -167,6 +168,12 @@ void ReplicaSetMonitorManager::shutdown() { } monitors = std::exchange(_monitors, {}); + taskExecutor = std::exchange(_taskExecutor, {}); + } + + if (taskExecutor) { + LOG(1) << "Shutting down task executor used for monitoring replica sets"; + taskExecutor->shutdown(); } if (monitors.size()) { @@ -181,9 +188,7 @@ void ReplicaSetMonitorManager::shutdown() { anchor->drop(); } - if (auto taskExecutor = std::exchange(_taskExecutor, {})) { - LOG(1) << "Shutting down task executor used for monitoring replica sets"; - taskExecutor->shutdown(); + if (taskExecutor) { taskExecutor->join(); } } |