summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorBen Caimano <ben.caimano@mongodb.com>2019-10-21 19:31:44 +0000
committerevergreen <evergreen@mongodb.com>2019-10-21 19:31:44 +0000
commita843d5a714e415e128916e49b76e2b2d333bb5d8 (patch)
treea1cfb2fa46a760b5abe89e870f3b29a3619291ab /src/mongo
parent6cca153f9f75ca29f2cdca65124efb4329771882 (diff)
downloadmongo-a843d5a714e415e128916e49b76e2b2d333bb5d8.tar.gz
SERVER-44087 ReplicaSetMonitor shutdowns should synchronize with NetworkInterface shutdown
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/client/replica_set_monitor.cpp18
-rw-r--r--src/mongo/client/replica_set_monitor_manager.cpp11
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();
}
}