summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Caimano <ben.caimano@mongodb.com>2019-10-21 20:04:47 +0000
committerevergreen <evergreen@mongodb.com>2019-10-21 20:04:47 +0000
commitb641599cf48d33bc79a4131ac8a8f5018dea83c4 (patch)
tree50500c6436bdb90ae0893fee20541cffeb4538ce
parenta843d5a714e415e128916e49b76e2b2d333bb5d8 (diff)
downloadmongo-b641599cf48d33bc79a4131ac8a8f5018dea83c4.tar.gz
SERVER-42967 SERVER-42895 SERVER-44086 Expand DiagnosticInfo hooks in Interruptible and Mutex
This commit: - Adds Listener hooks for Interruptible - Expands Listener hooks for Mutex - Updates the DiagnosticInfo and its tests to use the new hooks - Removes stacktracing pieces from DiagnosticInfo and its tests - Removes mongo::ConditionVariable entirely in favor of Interruptible
-rw-r--r--jstests/core/currentop_waiting_for_latch.js52
-rw-r--r--src/mongo/SConscript1
-rw-r--r--src/mongo/client/connpool.h2
-rw-r--r--src/mongo/client/connpool_integration_test.cpp2
-rw-r--r--src/mongo/client/fetcher.h2
-rw-r--r--src/mongo/client/remote_command_retry_scheduler.h2
-rw-r--r--src/mongo/client/replica_set_monitor.cpp2
-rw-r--r--src/mongo/client/replica_set_monitor_internal.h2
-rw-r--r--src/mongo/db/auth/authorization_manager.h2
-rw-r--r--src/mongo/db/auth/authorization_manager_impl.h2
-rw-r--r--src/mongo/db/background.cpp2
-rw-r--r--src/mongo/db/catalog/collection.h2
-rw-r--r--src/mongo/db/collection_index_builds_tracker.h2
-rw-r--r--src/mongo/db/commands/fsync.cpp2
-rw-r--r--src/mongo/db/concurrency/flow_control_ticketholder.h2
-rw-r--r--src/mongo/db/concurrency/lock_manager.h2
-rw-r--r--src/mongo/db/curop.cpp2
-rw-r--r--src/mongo/db/database_index_builds_tracker.h2
-rw-r--r--src/mongo/db/default_baton.h2
-rw-r--r--src/mongo/db/free_mon/free_mon_message.h2
-rw-r--r--src/mongo/db/ftdc/controller.cpp2
-rw-r--r--src/mongo/db/ftdc/controller.h2
-rw-r--r--src/mongo/db/index_builds_coordinator.h2
-rw-r--r--src/mongo/db/operation_context.h2
-rw-r--r--src/mongo/db/pipeline/document_source_exchange.h2
-rw-r--r--src/mongo/db/repl/abstract_async_component.h2
-rw-r--r--src/mongo/db/repl/base_cloner_test_fixture.h2
-rw-r--r--src/mongo/db/repl/bgsync.h2
-rw-r--r--src/mongo/db/repl/collection_cloner.h2
-rw-r--r--src/mongo/db/repl/database_cloner.h2
-rw-r--r--src/mongo/db/repl/databases_cloner.h2
-rw-r--r--src/mongo/db/repl/initial_syncer.h2
-rw-r--r--src/mongo/db/repl/multiapplier.h2
-rw-r--r--src/mongo/db/repl/replication_coordinator_external_state_mock.h2
-rw-r--r--src/mongo/db/repl/reporter.h2
-rw-r--r--src/mongo/db/repl/sync_source_feedback.h2
-rw-r--r--src/mongo/db/repl/sync_source_resolver.h2
-rw-r--r--src/mongo/db/repl/task_runner.h2
-rw-r--r--src/mongo/db/repl/task_runner_test.cpp2
-rw-r--r--src/mongo/db/repl_index_build_state.h2
-rw-r--r--src/mongo/db/s/balancer/balancer.h2
-rw-r--r--src/mongo/db/s/balancer/migration_manager.h2
-rw-r--r--src/mongo/db/s/config/namespace_serializer.h2
-rw-r--r--src/mongo/db/s/implicit_create_collection.cpp2
-rw-r--r--src/mongo/db/s/metadata_manager_test.cpp2
-rw-r--r--src/mongo/db/s/migration_chunk_cloner_source_legacy.h2
-rw-r--r--src/mongo/db/s/migration_destination_manager.h2
-rw-r--r--src/mongo/db/s/session_catalog_migration_destination.h2
-rw-r--r--src/mongo/db/s/shard_server_catalog_cache_loader.h2
-rw-r--r--src/mongo/db/s/transaction_coordinator_catalog.h2
-rw-r--r--src/mongo/db/service_context.h2
-rw-r--r--src/mongo/db/service_liaison_mock.h2
-rw-r--r--src/mongo/db/session_catalog.h2
-rw-r--r--src/mongo/db/session_killer.h2
-rw-r--r--src/mongo/db/storage/biggie/biggie_visibility_manager.h2
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.h2
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_record_store.h2
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_record_store_oplog_stones.h2
-rw-r--r--src/mongo/executor/async_multicaster.cpp2
-rw-r--r--src/mongo/executor/network_interface_mock.h2
-rw-r--r--src/mongo/executor/network_interface_thread_pool.h2
-rw-r--r--src/mongo/executor/scoped_task_executor.h2
-rw-r--r--src/mongo/executor/task_executor.h2
-rw-r--r--src/mongo/executor/thread_pool_task_executor.h2
-rw-r--r--src/mongo/platform/SConscript1
-rw-r--r--src/mongo/platform/condition_variable.cpp50
-rw-r--r--src/mongo/platform/condition_variable.h173
-rw-r--r--src/mongo/platform/condition_variable_test.cpp61
-rw-r--r--src/mongo/platform/mutex.cpp55
-rw-r--r--src/mongo/platform/mutex.h67
-rw-r--r--src/mongo/s/catalog/replset_dist_lock_manager.h2
-rw-r--r--src/mongo/s/catalog/replset_dist_lock_manager_test.cpp2
-rw-r--r--src/mongo/s/client/shard_registry.h2
-rw-r--r--src/mongo/s/cluster_identity_loader.h2
-rw-r--r--src/mongo/s/sharding_task_executor.h2
-rw-r--r--src/mongo/scripting/deadline_monitor.h2
-rw-r--r--src/mongo/scripting/mozjs/PosixNSPR.cpp2
-rw-r--r--src/mongo/scripting/mozjs/countdownlatch.cpp2
-rw-r--r--src/mongo/scripting/mozjs/jsthread.cpp2
-rw-r--r--src/mongo/scripting/mozjs/proxyscope.h2
-rw-r--r--src/mongo/shell/bench.h2
-rw-r--r--src/mongo/transport/service_entry_point_impl.h2
-rw-r--r--src/mongo/transport/service_executor_adaptive.h2
-rw-r--r--src/mongo/transport/service_executor_reserved.h2
-rw-r--r--src/mongo/transport/service_executor_synchronous.h2
-rw-r--r--src/mongo/transport/transport_layer_asio.h2
-rw-r--r--src/mongo/unittest/barrier.h2
-rw-r--r--src/mongo/util/alarm_runner_background_thread.h2
-rw-r--r--src/mongo/util/background.cpp2
-rw-r--r--src/mongo/util/background_thread_clock_source.h2
-rw-r--r--src/mongo/util/concurrency/notification.h2
-rw-r--r--src/mongo/util/concurrency/thread_pool.h2
-rw-r--r--src/mongo/util/concurrency/thread_pool_test.cpp2
-rw-r--r--src/mongo/util/concurrency/thread_pool_test_common.cpp2
-rw-r--r--src/mongo/util/concurrency/ticketholder.h2
-rw-r--r--src/mongo/util/diagnostic_info.cpp327
-rw-r--r--src/mongo/util/diagnostic_info.h50
-rw-r--r--src/mongo/util/diagnostic_info_test.cpp90
-rw-r--r--src/mongo/util/exit.cpp2
-rw-r--r--src/mongo/util/future_impl.h2
-rw-r--r--src/mongo/util/interruptible.h180
-rw-r--r--src/mongo/util/invalidating_lru_cache.h2
-rw-r--r--src/mongo/util/periodic_runner_impl.h2
-rw-r--r--src/mongo/util/periodic_runner_impl_test.cpp2
-rw-r--r--src/mongo/util/producer_consumer_queue.h2
-rw-r--r--src/mongo/util/producer_consumer_queue_test.cpp2
-rw-r--r--src/mongo/util/queue.h2
-rw-r--r--src/mongo/watchdog/watchdog.h2
108 files changed, 534 insertions, 765 deletions
diff --git a/jstests/core/currentop_waiting_for_latch.js b/jstests/core/currentop_waiting_for_latch.js
index 383ba32a643..c584e0d98bf 100644
--- a/jstests/core/currentop_waiting_for_latch.js
+++ b/jstests/core/currentop_waiting_for_latch.js
@@ -26,7 +26,10 @@ const getCurrentOp = function() {
return result;
};
-const blockedOpClientName = "DiagnosticCaptureTest";
+const blockedOpClients = {
+ "DiagnosticCaptureTestLatch": {"seen": false},
+ "DiagnosticCaptureTestInterruptible": {"seen": false},
+};
const getClientName = function() {
let myUri = adminDB.runCommand({whatsmyuri: 1}).you;
@@ -46,34 +49,43 @@ try {
},
}));
- let result = null;
+ const verifyResult = function(result) {
+ jsTestLog("Verifying " + tojson(result));
+ assert(result);
+ assert(result.hasOwnProperty("waitingForLatch"));
+ assert(result["waitingForLatch"].hasOwnProperty("timestamp"));
+ assert(result["waitingForLatch"].hasOwnProperty("captureName"));
+
+ /* Absent until we have efficient enough backtracing
+ assert(result["waitingForLatch"].hasOwnProperty("backtrace"));
+ result["waitingForLatch"]["backtrace"].forEach(function(frame) {
+ assert(frame.hasOwnProperty("addr"));
+ assert(typeof frame["addr"] === "string");
+ assert(frame.hasOwnProperty("path"));
+ assert(typeof frame["path"] === "string");
+ });
+ */
+ };
getCurrentOp().forEach(function(op) {
- jsTestLog(tojson(op));
- if (op["desc"] == blockedOpClientName) {
- result = op;
+ const name = op["desc"];
+ if (name in blockedOpClients) {
+ jsTestLog("Verifying " + op["desc"]);
+ verifyResult(op);
+ blockedOpClients[name].seen = true;
}
});
- assert(result);
- assert(result.hasOwnProperty("waitingForLatch"));
- assert(result["waitingForLatch"].hasOwnProperty("timestamp"));
- assert(result["waitingForLatch"].hasOwnProperty("captureName"));
- /* Absent until we have efficient enough backtracing
- assert(result["waitingForLatch"].hasOwnProperty("backtrace"));
- result["waitingForLatch"]["backtrace"].forEach(function(frame) {
- assert(frame.hasOwnProperty("addr"));
- assert(typeof frame["addr"] === "string");
- assert(frame.hasOwnProperty("path"));
- assert(typeof frame["path"] === "string");
- });
- */
+ // Make sure we saw the ops we expected
+ for (const name in blockedOpClients) {
+ assert(blockedOpClients[name].seen);
+ }
} finally {
assert.commandWorked(db.adminCommand(
{"configureFailPoint": 'currentOpSpawnsThreadWaitingForLatch', "mode": 'off'}));
getCurrentOp().forEach(function(op) {
- jsTestLog(tojson(op));
- if (op["desc"] == blockedOpClientName) {
+ const name = op["desc"];
+ if (name in blockedOpClients) {
assert(!op.hasOwnProperty("waitingForLatch"));
}
});
diff --git a/src/mongo/SConscript b/src/mongo/SConscript
index 77c87f51dc7..3ae639f83c7 100644
--- a/src/mongo/SConscript
+++ b/src/mongo/SConscript
@@ -123,7 +123,6 @@ baseEnv.Library(
'logv2/log_severity.cpp',
'logv2/log_tag.cpp',
'logv2/ramlog.cpp',
- 'platform/condition_variable.cpp',
'platform/decimal128.cpp',
'platform/mutex.cpp',
'platform/posix_fadvise.cpp',
diff --git a/src/mongo/client/connpool.h b/src/mongo/client/connpool.h
index 4fb06c6057a..1d39268d588 100644
--- a/src/mongo/client/connpool.h
+++ b/src/mongo/client/connpool.h
@@ -35,7 +35,7 @@
#include "mongo/client/dbclient_base.h"
#include "mongo/client/mongo_uri.h"
#include "mongo/platform/atomic_word.h"
-#include "mongo/platform/condition_variable.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/background.h"
#include "mongo/util/concurrency/mutex.h"
#include "mongo/util/time_support.h"
diff --git a/src/mongo/client/connpool_integration_test.cpp b/src/mongo/client/connpool_integration_test.cpp
index 41323e41584..8daada412a3 100644
--- a/src/mongo/client/connpool_integration_test.cpp
+++ b/src/mongo/client/connpool_integration_test.cpp
@@ -31,8 +31,8 @@
#include "mongo/client/connpool.h"
#include "mongo/client/global_conn_pool.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/unittest/integration_test.h"
#include "mongo/unittest/unittest.h"
diff --git a/src/mongo/client/fetcher.h b/src/mongo/client/fetcher.h
index 0a2abbd12fe..bd4556d0ee4 100644
--- a/src/mongo/client/fetcher.h
+++ b/src/mongo/client/fetcher.h
@@ -42,8 +42,8 @@
#include "mongo/db/clientcursor.h"
#include "mongo/db/namespace_string.h"
#include "mongo/executor/task_executor.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/net/hostandport.h"
namespace mongo {
diff --git a/src/mongo/client/remote_command_retry_scheduler.h b/src/mongo/client/remote_command_retry_scheduler.h
index c0718b8408f..d466a3b217b 100644
--- a/src/mongo/client/remote_command_retry_scheduler.h
+++ b/src/mongo/client/remote_command_retry_scheduler.h
@@ -37,8 +37,8 @@
#include "mongo/base/error_codes.h"
#include "mongo/executor/task_executor.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/time_support.h"
namespace mongo {
diff --git a/src/mongo/client/replica_set_monitor.cpp b/src/mongo/client/replica_set_monitor.cpp
index 05f8d7d63e5..9d24576d312 100644
--- a/src/mongo/client/replica_set_monitor.cpp
+++ b/src/mongo/client/replica_set_monitor.cpp
@@ -46,8 +46,8 @@
#include "mongo/db/repl/bson_extract_optime.h"
#include "mongo/db/server_options.h"
#include "mongo/platform/atomic_word.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/background.h"
#include "mongo/util/debug_util.h"
#include "mongo/util/exit.h"
diff --git a/src/mongo/client/replica_set_monitor_internal.h b/src/mongo/client/replica_set_monitor_internal.h
index 9f7812f1ff3..f65b1306200 100644
--- a/src/mongo/client/replica_set_monitor_internal.h
+++ b/src/mongo/client/replica_set_monitor_internal.h
@@ -44,9 +44,9 @@
#include "mongo/client/read_preference.h"
#include "mongo/client/replica_set_monitor.h"
#include "mongo/db/jsobj.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
#include "mongo/platform/random.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/net/hostandport.h"
namespace mongo {
diff --git a/src/mongo/db/auth/authorization_manager.h b/src/mongo/db/auth/authorization_manager.h
index 035d797f48d..21380460468 100644
--- a/src/mongo/db/auth/authorization_manager.h
+++ b/src/mongo/db/auth/authorization_manager.h
@@ -49,8 +49,8 @@
#include "mongo/db/jsobj.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/server_options.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/unordered_map.h"
namespace mongo {
diff --git a/src/mongo/db/auth/authorization_manager_impl.h b/src/mongo/db/auth/authorization_manager_impl.h
index 725bb27b7d8..d80d0b668f6 100644
--- a/src/mongo/db/auth/authorization_manager_impl.h
+++ b/src/mongo/db/auth/authorization_manager_impl.h
@@ -50,8 +50,8 @@
#include "mongo/db/namespace_string.h"
#include "mongo/db/server_options.h"
#include "mongo/platform/atomic_word.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/unordered_map.h"
#include "mongo/util/invalidating_lru_cache.h"
diff --git a/src/mongo/db/background.cpp b/src/mongo/db/background.cpp
index 62afb3e099b..14da56c02ec 100644
--- a/src/mongo/db/background.cpp
+++ b/src/mongo/db/background.cpp
@@ -35,8 +35,8 @@
#include <string>
#include "mongo/db/operation_context.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/map_util.h"
diff --git a/src/mongo/db/catalog/collection.h b/src/mongo/db/catalog/collection.h
index 492b0628e32..2da11684f68 100644
--- a/src/mongo/db/catalog/collection.h
+++ b/src/mongo/db/catalog/collection.h
@@ -51,8 +51,8 @@
#include "mongo/db/storage/capped_callback.h"
#include "mongo/db/storage/record_store.h"
#include "mongo/db/storage/snapshot.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/decorable.h"
namespace mongo {
diff --git a/src/mongo/db/collection_index_builds_tracker.h b/src/mongo/db/collection_index_builds_tracker.h
index 8d43dbd96bc..81c25fe73d3 100644
--- a/src/mongo/db/collection_index_builds_tracker.h
+++ b/src/mongo/db/collection_index_builds_tracker.h
@@ -33,7 +33,7 @@
#include <string>
#include "mongo/db/repl_index_build_state.h"
-#include "mongo/platform/condition_variable.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/concurrency/with_lock.h"
#include "mongo/util/uuid.h"
diff --git a/src/mongo/db/commands/fsync.cpp b/src/mongo/db/commands/fsync.cpp
index 27691749ac6..25bedb64ba5 100644
--- a/src/mongo/db/commands/fsync.cpp
+++ b/src/mongo/db/commands/fsync.cpp
@@ -49,7 +49,7 @@
#include "mongo/db/service_context.h"
#include "mongo/db/storage/backup_cursor_hooks.h"
#include "mongo/db/storage/storage_engine.h"
-#include "mongo/platform/condition_variable.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/background.h"
#include "mongo/util/exit.h"
diff --git a/src/mongo/db/concurrency/flow_control_ticketholder.h b/src/mongo/db/concurrency/flow_control_ticketholder.h
index 39413477937..8247318a842 100644
--- a/src/mongo/db/concurrency/flow_control_ticketholder.h
+++ b/src/mongo/db/concurrency/flow_control_ticketholder.h
@@ -31,8 +31,8 @@
#include "mongo/bson/bsonobjbuilder.h"
#include "mongo/platform/atomic_word.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
namespace mongo {
diff --git a/src/mongo/db/concurrency/lock_manager.h b/src/mongo/db/concurrency/lock_manager.h
index d6bed91bc9f..b464c0f85c8 100644
--- a/src/mongo/db/concurrency/lock_manager.h
+++ b/src/mongo/db/concurrency/lock_manager.h
@@ -40,8 +40,8 @@
#include "mongo/db/concurrency/lock_request_list.h"
#include "mongo/platform/atomic_word.h"
#include "mongo/platform/compiler.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/unordered_map.h"
#include "mongo/util/concurrency/mutex.h"
diff --git a/src/mongo/db/curop.cpp b/src/mongo/db/curop.cpp
index 4767acb9f26..b8df781916f 100644
--- a/src/mongo/db/curop.cpp
+++ b/src/mongo/db/curop.cpp
@@ -311,11 +311,13 @@ void CurOp::reportCurrentOpForClient(OperationContext* opCtx,
waitingForLatchBuilder.append("captureName", diagnostic->getCaptureName());
if (backtraceMode) {
BSONArrayBuilder backtraceBuilder(waitingForLatchBuilder.subarrayStart("backtrace"));
+ /** This branch becomes useful again with SERVER-44091
for (const auto& frame : diagnostic->makeStackTrace().frames) {
BSONObjBuilder backtraceObj(backtraceBuilder.subobjStart());
backtraceObj.append("addr", integerToHex(frame.instructionOffset));
backtraceObj.append("path", frame.objectPath);
}
+ */
}
}
}
diff --git a/src/mongo/db/database_index_builds_tracker.h b/src/mongo/db/database_index_builds_tracker.h
index 372f5f08210..8b2eb4ea474 100644
--- a/src/mongo/db/database_index_builds_tracker.h
+++ b/src/mongo/db/database_index_builds_tracker.h
@@ -33,7 +33,7 @@
#include <string>
#include "mongo/db/repl_index_build_state.h"
-#include "mongo/platform/condition_variable.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/concurrency/with_lock.h"
#include "mongo/util/uuid.h"
diff --git a/src/mongo/db/default_baton.h b/src/mongo/db/default_baton.h
index c406741e332..74fd724fae1 100644
--- a/src/mongo/db/default_baton.h
+++ b/src/mongo/db/default_baton.h
@@ -32,8 +32,8 @@
#include <vector>
#include "mongo/db/baton.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/functional.h"
namespace mongo {
diff --git a/src/mongo/db/free_mon/free_mon_message.h b/src/mongo/db/free_mon/free_mon_message.h
index 11fab7c8501..9b7fc83a05b 100644
--- a/src/mongo/db/free_mon/free_mon_message.h
+++ b/src/mongo/db/free_mon/free_mon_message.h
@@ -33,8 +33,8 @@
#include <vector>
#include "mongo/db/free_mon/free_mon_protocol_gen.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/duration.h"
#include "mongo/util/time_support.h"
diff --git a/src/mongo/db/ftdc/controller.cpp b/src/mongo/db/ftdc/controller.cpp
index 11f80503acd..947fd004dfe 100644
--- a/src/mongo/db/ftdc/controller.cpp
+++ b/src/mongo/db/ftdc/controller.cpp
@@ -39,8 +39,8 @@
#include "mongo/db/ftdc/collector.h"
#include "mongo/db/ftdc/util.h"
#include "mongo/db/jsobj.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/concurrency/idle_thread_block.h"
#include "mongo/util/exit.h"
diff --git a/src/mongo/db/ftdc/controller.h b/src/mongo/db/ftdc/controller.h
index 949117cbc79..50d6ae48886 100644
--- a/src/mongo/db/ftdc/controller.h
+++ b/src/mongo/db/ftdc/controller.h
@@ -37,8 +37,8 @@
#include "mongo/db/ftdc/config.h"
#include "mongo/db/ftdc/file_manager.h"
#include "mongo/db/jsobj.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
namespace mongo {
diff --git a/src/mongo/db/index_builds_coordinator.h b/src/mongo/db/index_builds_coordinator.h
index 1c22bf9fec9..7f582b0c684 100644
--- a/src/mongo/db/index_builds_coordinator.h
+++ b/src/mongo/db/index_builds_coordinator.h
@@ -43,8 +43,8 @@
#include "mongo/db/namespace_string.h"
#include "mongo/db/repl_index_build_state.h"
#include "mongo/db/storage/durable_catalog.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/concurrency/with_lock.h"
#include "mongo/util/fail_point.h"
#include "mongo/util/future.h"
diff --git a/src/mongo/db/operation_context.h b/src/mongo/db/operation_context.h
index 7ebef518aec..9a7fb8c17ad 100644
--- a/src/mongo/db/operation_context.h
+++ b/src/mongo/db/operation_context.h
@@ -41,8 +41,8 @@
#include "mongo/db/storage/write_unit_of_work.h"
#include "mongo/db/write_concern_options.h"
#include "mongo/platform/atomic_word.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/transport/session.h"
#include "mongo/util/decorable.h"
#include "mongo/util/interruptible.h"
diff --git a/src/mongo/db/pipeline/document_source_exchange.h b/src/mongo/db/pipeline/document_source_exchange.h
index df423ff28bb..f77e5d14bde 100644
--- a/src/mongo/db/pipeline/document_source_exchange.h
+++ b/src/mongo/db/pipeline/document_source_exchange.h
@@ -36,8 +36,8 @@
#include "mongo/db/pipeline/document_source.h"
#include "mongo/db/pipeline/exchange_spec_gen.h"
#include "mongo/db/pipeline/field_path.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
namespace mongo {
diff --git a/src/mongo/db/repl/abstract_async_component.h b/src/mongo/db/repl/abstract_async_component.h
index c5ce2da5afa..5b0e6426900 100644
--- a/src/mongo/db/repl/abstract_async_component.h
+++ b/src/mongo/db/repl/abstract_async_component.h
@@ -37,8 +37,8 @@
#include "mongo/base/static_assert.h"
#include "mongo/base/status.h"
#include "mongo/executor/task_executor.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
namespace mongo {
namespace repl {
diff --git a/src/mongo/db/repl/base_cloner_test_fixture.h b/src/mongo/db/repl/base_cloner_test_fixture.h
index d0e5a9b9289..328bfdb27d2 100644
--- a/src/mongo/db/repl/base_cloner_test_fixture.h
+++ b/src/mongo/db/repl/base_cloner_test_fixture.h
@@ -41,8 +41,8 @@
#include "mongo/db/service_context_test_fixture.h"
#include "mongo/executor/network_interface_mock.h"
#include "mongo/executor/thread_pool_task_executor_test_fixture.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/concurrency/thread_pool.h"
#include "mongo/util/net/hostandport.h"
diff --git a/src/mongo/db/repl/bgsync.h b/src/mongo/db/repl/bgsync.h
index 0bacdc71d29..b418c935492 100644
--- a/src/mongo/db/repl/bgsync.h
+++ b/src/mongo/db/repl/bgsync.h
@@ -43,8 +43,8 @@
#include "mongo/db/repl/rollback_impl.h"
#include "mongo/db/repl/sync_source_resolver.h"
#include "mongo/platform/atomic_word.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/net/hostandport.h"
diff --git a/src/mongo/db/repl/collection_cloner.h b/src/mongo/db/repl/collection_cloner.h
index ba8139dd98f..4f0ddfd23a8 100644
--- a/src/mongo/db/repl/collection_cloner.h
+++ b/src/mongo/db/repl/collection_cloner.h
@@ -48,8 +48,8 @@
#include "mongo/db/repl/storage_interface.h"
#include "mongo/db/repl/task_runner.h"
#include "mongo/executor/task_executor.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/concurrency/thread_pool.h"
#include "mongo/util/net/hostandport.h"
#include "mongo/util/progress_meter.h"
diff --git a/src/mongo/db/repl/database_cloner.h b/src/mongo/db/repl/database_cloner.h
index 666f23610fb..96c9e6b4c06 100644
--- a/src/mongo/db/repl/database_cloner.h
+++ b/src/mongo/db/repl/database_cloner.h
@@ -41,8 +41,8 @@
#include "mongo/db/repl/base_cloner.h"
#include "mongo/db/repl/collection_cloner.h"
#include "mongo/executor/task_executor.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/concurrency/thread_pool.h"
#include "mongo/util/net/hostandport.h"
diff --git a/src/mongo/db/repl/databases_cloner.h b/src/mongo/db/repl/databases_cloner.h
index e5ea692d8bc..f4a8662883d 100644
--- a/src/mongo/db/repl/databases_cloner.h
+++ b/src/mongo/db/repl/databases_cloner.h
@@ -42,8 +42,8 @@
#include "mongo/db/repl/collection_cloner.h"
#include "mongo/db/repl/database_cloner.h"
#include "mongo/executor/task_executor.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/concurrency/thread_pool.h"
#include "mongo/util/net/hostandport.h"
diff --git a/src/mongo/db/repl/initial_syncer.h b/src/mongo/db/repl/initial_syncer.h
index 406c89352bb..cce4018d1e1 100644
--- a/src/mongo/db/repl/initial_syncer.h
+++ b/src/mongo/db/repl/initial_syncer.h
@@ -53,8 +53,8 @@
#include "mongo/db/repl/rollback_checker.h"
#include "mongo/db/repl/sync_source_selector.h"
#include "mongo/dbtests/mock/mock_dbclient_connection.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/concurrency/thread_pool.h"
#include "mongo/util/fail_point.h"
#include "mongo/util/net/hostandport.h"
diff --git a/src/mongo/db/repl/multiapplier.h b/src/mongo/db/repl/multiapplier.h
index 406888746b1..22023e6eafc 100644
--- a/src/mongo/db/repl/multiapplier.h
+++ b/src/mongo/db/repl/multiapplier.h
@@ -43,8 +43,8 @@
#include "mongo/db/repl/oplog_entry.h"
#include "mongo/db/service_context.h"
#include "mongo/executor/task_executor.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
namespace mongo {
namespace repl {
diff --git a/src/mongo/db/repl/replication_coordinator_external_state_mock.h b/src/mongo/db/repl/replication_coordinator_external_state_mock.h
index 5cebab1e820..0f1ed300583 100644
--- a/src/mongo/db/repl/replication_coordinator_external_state_mock.h
+++ b/src/mongo/db/repl/replication_coordinator_external_state_mock.h
@@ -37,8 +37,8 @@
#include "mongo/db/jsobj.h"
#include "mongo/db/repl/last_vote.h"
#include "mongo/db/repl/replication_coordinator_external_state.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/net/hostandport.h"
diff --git a/src/mongo/db/repl/reporter.h b/src/mongo/db/repl/reporter.h
index caa67aaa528..824ae59b17e 100644
--- a/src/mongo/db/repl/reporter.h
+++ b/src/mongo/db/repl/reporter.h
@@ -36,8 +36,8 @@
#include "mongo/db/jsobj.h"
#include "mongo/db/repl/replication_coordinator.h"
#include "mongo/executor/task_executor.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/time_support.h"
namespace mongo {
diff --git a/src/mongo/db/repl/sync_source_feedback.h b/src/mongo/db/repl/sync_source_feedback.h
index 3688de9a0ed..fdec94bff72 100644
--- a/src/mongo/db/repl/sync_source_feedback.h
+++ b/src/mongo/db/repl/sync_source_feedback.h
@@ -32,8 +32,8 @@
#include "mongo/base/status.h"
#include "mongo/db/repl/replication_coordinator.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
namespace mongo {
struct HostAndPort;
diff --git a/src/mongo/db/repl/sync_source_resolver.h b/src/mongo/db/repl/sync_source_resolver.h
index 2b2734d2c70..a98db3d8773 100644
--- a/src/mongo/db/repl/sync_source_resolver.h
+++ b/src/mongo/db/repl/sync_source_resolver.h
@@ -38,8 +38,8 @@
#include "mongo/db/namespace_string.h"
#include "mongo/db/repl/optime.h"
#include "mongo/executor/task_executor.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/net/hostandport.h"
#include "mongo/util/time_support.h"
diff --git a/src/mongo/db/repl/task_runner.h b/src/mongo/db/repl/task_runner.h
index c1db72bdba5..4f7303e3ad6 100644
--- a/src/mongo/db/repl/task_runner.h
+++ b/src/mongo/db/repl/task_runner.h
@@ -33,8 +33,8 @@
#include <list>
#include "mongo/db/service_context.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/concurrency/thread_pool.h"
#include "mongo/util/functional.h"
diff --git a/src/mongo/db/repl/task_runner_test.cpp b/src/mongo/db/repl/task_runner_test.cpp
index 96ad44916aa..d71dc3c42e8 100644
--- a/src/mongo/db/repl/task_runner_test.cpp
+++ b/src/mongo/db/repl/task_runner_test.cpp
@@ -34,8 +34,8 @@
#include "mongo/db/operation_context_noop.h"
#include "mongo/db/repl/task_runner.h"
#include "mongo/db/repl/task_runner_test_fixture.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/unittest/barrier.h"
#include "mongo/util/concurrency/thread_pool.h"
diff --git a/src/mongo/db/repl_index_build_state.h b/src/mongo/db/repl_index_build_state.h
index f5e14beb4cc..66ab914807c 100644
--- a/src/mongo/db/repl_index_build_state.h
+++ b/src/mongo/db/repl_index_build_state.h
@@ -39,7 +39,7 @@
#include "mongo/db/catalog/commit_quorum_options.h"
#include "mongo/db/index/index_descriptor.h"
#include "mongo/db/namespace_string.h"
-#include "mongo/platform/condition_variable.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/future.h"
#include "mongo/util/net/hostandport.h"
#include "mongo/util/uuid.h"
diff --git a/src/mongo/db/s/balancer/balancer.h b/src/mongo/db/s/balancer/balancer.h
index 4e22590bf1d..1df09000920 100644
--- a/src/mongo/db/s/balancer/balancer.h
+++ b/src/mongo/db/s/balancer/balancer.h
@@ -32,8 +32,8 @@
#include "mongo/db/s/balancer/balancer_chunk_selection_policy.h"
#include "mongo/db/s/balancer/balancer_random.h"
#include "mongo/db/s/balancer/migration_manager.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
namespace mongo {
diff --git a/src/mongo/db/s/balancer/migration_manager.h b/src/mongo/db/s/balancer/migration_manager.h
index 0e517b7e067..b321b361e79 100644
--- a/src/mongo/db/s/balancer/migration_manager.h
+++ b/src/mongo/db/s/balancer/migration_manager.h
@@ -38,10 +38,10 @@
#include "mongo/db/s/balancer/balancer_policy.h"
#include "mongo/db/s/balancer/type_migration.h"
#include "mongo/executor/task_executor.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
#include "mongo/s/catalog/dist_lock_manager.h"
#include "mongo/s/request_types/migration_secondary_throttle_options.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/unordered_map.h"
#include "mongo/util/concurrency/notification.h"
#include "mongo/util/concurrency/with_lock.h"
diff --git a/src/mongo/db/s/config/namespace_serializer.h b/src/mongo/db/s/config/namespace_serializer.h
index f0e6c4b158c..f5b7dbbac3a 100644
--- a/src/mongo/db/s/config/namespace_serializer.h
+++ b/src/mongo/db/s/config/namespace_serializer.h
@@ -36,8 +36,8 @@
#include "mongo/base/status.h"
#include "mongo/base/status_with.h"
#include "mongo/db/namespace_string.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/string_map.h"
namespace mongo {
diff --git a/src/mongo/db/s/implicit_create_collection.cpp b/src/mongo/db/s/implicit_create_collection.cpp
index dfc8cd97cb2..62b086eebc5 100644
--- a/src/mongo/db/s/implicit_create_collection.cpp
+++ b/src/mongo/db/s/implicit_create_collection.cpp
@@ -46,8 +46,8 @@
#include "mongo/s/grid.h"
#include "mongo/s/request_types/create_collection_gen.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/scopeguard.h"
namespace mongo {
diff --git a/src/mongo/db/s/metadata_manager_test.cpp b/src/mongo/db/s/metadata_manager_test.cpp
index e5d3480fa3d..1e367cf7aea 100644
--- a/src/mongo/db/s/metadata_manager_test.cpp
+++ b/src/mongo/db/s/metadata_manager_test.cpp
@@ -42,10 +42,10 @@
#include "mongo/db/server_options.h"
#include "mongo/db/service_context.h"
#include "mongo/executor/task_executor.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/s/catalog/type_chunk.h"
#include "mongo/s/client/shard_registry.h"
#include "mongo/s/shard_server_test_fixture.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/assert_util.h"
diff --git a/src/mongo/db/s/migration_chunk_cloner_source_legacy.h b/src/mongo/db/s/migration_chunk_cloner_source_legacy.h
index 34b41503bec..8e5809093af 100644
--- a/src/mongo/db/s/migration_chunk_cloner_source_legacy.h
+++ b/src/mongo/db/s/migration_chunk_cloner_source_legacy.h
@@ -40,10 +40,10 @@
#include "mongo/db/s/migration_chunk_cloner_source.h"
#include "mongo/db/s/migration_session_id.h"
#include "mongo/db/s/session_catalog_migration_source.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
#include "mongo/s/request_types/move_chunk_request.h"
#include "mongo/s/shard_key_pattern.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/net/hostandport.h"
namespace mongo {
diff --git a/src/mongo/db/s/migration_destination_manager.h b/src/mongo/db/s/migration_destination_manager.h
index 607eec9a68a..910e259fc98 100644
--- a/src/mongo/db/s/migration_destination_manager.h
+++ b/src/mongo/db/s/migration_destination_manager.h
@@ -41,9 +41,9 @@
#include "mongo/db/s/collection_sharding_runtime.h"
#include "mongo/db/s/migration_session_id.h"
#include "mongo/db/s/session_catalog_migration_destination.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
#include "mongo/s/shard_id.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/concurrency/with_lock.h"
#include "mongo/util/timer.h"
diff --git a/src/mongo/db/s/session_catalog_migration_destination.h b/src/mongo/db/s/session_catalog_migration_destination.h
index 185eecbb9ba..b5a85fd6998 100644
--- a/src/mongo/db/s/session_catalog_migration_destination.h
+++ b/src/mongo/db/s/session_catalog_migration_destination.h
@@ -36,9 +36,9 @@
#include "mongo/bson/bsonobj.h"
#include "mongo/db/repl/oplog_entry.h"
#include "mongo/db/s/migration_session_id.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
#include "mongo/s/shard_id.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/concurrency/with_lock.h"
diff --git a/src/mongo/db/s/shard_server_catalog_cache_loader.h b/src/mongo/db/s/shard_server_catalog_cache_loader.h
index 4cbdc31e3e0..2adfe15d9b7 100644
--- a/src/mongo/db/s/shard_server_catalog_cache_loader.h
+++ b/src/mongo/db/s/shard_server_catalog_cache_loader.h
@@ -31,8 +31,8 @@
#include "mongo/db/operation_context_group.h"
#include "mongo/db/s/namespace_metadata_change_notifications.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/s/catalog_cache_loader.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/concurrency/thread_pool.h"
namespace mongo {
diff --git a/src/mongo/db/s/transaction_coordinator_catalog.h b/src/mongo/db/s/transaction_coordinator_catalog.h
index 375fc33d1d9..057c5dfb575 100644
--- a/src/mongo/db/s/transaction_coordinator_catalog.h
+++ b/src/mongo/db/s/transaction_coordinator_catalog.h
@@ -33,7 +33,7 @@
#include <map>
#include "mongo/db/s/transaction_coordinator.h"
-#include "mongo/platform/condition_variable.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/concurrency/with_lock.h"
namespace mongo {
diff --git a/src/mongo/db/service_context.h b/src/mongo/db/service_context.h
index 178a3ff19a6..7a9270061d2 100644
--- a/src/mongo/db/service_context.h
+++ b/src/mongo/db/service_context.h
@@ -39,8 +39,8 @@
#include "mongo/db/logical_session_id.h"
#include "mongo/db/storage/storage_engine.h"
#include "mongo/platform/atomic_word.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/unordered_set.h"
#include "mongo/transport/service_executor.h"
#include "mongo/transport/session.h"
diff --git a/src/mongo/db/service_liaison_mock.h b/src/mongo/db/service_liaison_mock.h
index 72512cbb95b..76af1a8ebf0 100644
--- a/src/mongo/db/service_liaison_mock.h
+++ b/src/mongo/db/service_liaison_mock.h
@@ -33,8 +33,8 @@
#include "mongo/db/service_liaison.h"
#include "mongo/executor/async_timer_mock.h"
#include "mongo/platform/atomic_word.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/periodic_runner.h"
#include "mongo/util/time_support.h"
diff --git a/src/mongo/db/session_catalog.h b/src/mongo/db/session_catalog.h
index ea5226915c7..025fab44676 100644
--- a/src/mongo/db/session_catalog.h
+++ b/src/mongo/db/session_catalog.h
@@ -37,8 +37,8 @@
#include "mongo/db/operation_context.h"
#include "mongo/db/session.h"
#include "mongo/db/session_killer.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/unordered_map.h"
#include "mongo/util/concurrency/with_lock.h"
diff --git a/src/mongo/db/session_killer.h b/src/mongo/db/session_killer.h
index 8e9cd89cdfa..231fd01dc12 100644
--- a/src/mongo/db/session_killer.h
+++ b/src/mongo/db/session_killer.h
@@ -37,8 +37,8 @@
#include "mongo/base/status_with.h"
#include "mongo/db/kill_sessions.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/stdx/unordered_set.h"
#include "mongo/util/net/hostandport.h"
diff --git a/src/mongo/db/storage/biggie/biggie_visibility_manager.h b/src/mongo/db/storage/biggie/biggie_visibility_manager.h
index 8370ba0c990..e0d798aa13b 100644
--- a/src/mongo/db/storage/biggie/biggie_visibility_manager.h
+++ b/src/mongo/db/storage/biggie/biggie_visibility_manager.h
@@ -31,7 +31,7 @@
#include "mongo/db/operation_context.h"
#include "mongo/db/record_id.h"
-#include "mongo/platform/condition_variable.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/concurrency/mutex.h"
namespace mongo {
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.h b/src/mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.h
index 09258c657f2..d4ee1cbf83b 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_oplog_manager.h
@@ -30,8 +30,8 @@
#pragma once
#include "mongo/db/storage/wiredtiger/wiredtiger_record_store.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/concurrency/with_lock.h"
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.h b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.h
index cf82a514969..e647af70929 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.h
@@ -43,8 +43,8 @@
#include "mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.h"
#include "mongo/db/storage/wiredtiger/wiredtiger_size_storer.h"
#include "mongo/platform/atomic_word.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/fail_point.h"
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_oplog_stones.h b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_oplog_stones.h
index 9553ee9f56a..0dcb844f1d0 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_oplog_stones.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store_oplog_stones.h
@@ -33,8 +33,8 @@
#include "mongo/db/storage/wiredtiger/wiredtiger_record_store.h"
#include "mongo/platform/atomic_word.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
namespace mongo {
diff --git a/src/mongo/executor/async_multicaster.cpp b/src/mongo/executor/async_multicaster.cpp
index 3962f8f551d..eb13a1ce385 100644
--- a/src/mongo/executor/async_multicaster.cpp
+++ b/src/mongo/executor/async_multicaster.cpp
@@ -37,8 +37,8 @@
#include "mongo/base/status.h"
#include "mongo/db/operation_context.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/assert_util.h"
namespace mongo {
diff --git a/src/mongo/executor/network_interface_mock.h b/src/mongo/executor/network_interface_mock.h
index af1af78bf5b..2fb1d313500 100644
--- a/src/mongo/executor/network_interface_mock.h
+++ b/src/mongo/executor/network_interface_mock.h
@@ -36,9 +36,9 @@
#include <vector>
#include "mongo/executor/network_interface.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
#include "mongo/rpc/metadata/metadata_hook.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/unordered_map.h"
#include "mongo/stdx/unordered_set.h"
#include "mongo/util/clock_source.h"
diff --git a/src/mongo/executor/network_interface_thread_pool.h b/src/mongo/executor/network_interface_thread_pool.h
index 946519b56f1..3a295b26a5b 100644
--- a/src/mongo/executor/network_interface_thread_pool.h
+++ b/src/mongo/executor/network_interface_thread_pool.h
@@ -32,8 +32,8 @@
#include <cstdint>
#include <vector>
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/concurrency/thread_pool_interface.h"
namespace mongo {
diff --git a/src/mongo/executor/scoped_task_executor.h b/src/mongo/executor/scoped_task_executor.h
index 1582e654002..5b624e10f64 100644
--- a/src/mongo/executor/scoped_task_executor.h
+++ b/src/mongo/executor/scoped_task_executor.h
@@ -34,8 +34,8 @@
#include "mongo/base/status.h"
#include "mongo/executor/task_executor.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/unordered_map.h"
#include "mongo/util/fail_point.h"
diff --git a/src/mongo/executor/task_executor.h b/src/mongo/executor/task_executor.h
index f84321a46b7..d36f5c9bac6 100644
--- a/src/mongo/executor/task_executor.h
+++ b/src/mongo/executor/task_executor.h
@@ -38,7 +38,7 @@
#include "mongo/base/string_data.h"
#include "mongo/executor/remote_command_request.h"
#include "mongo/executor/remote_command_response.h"
-#include "mongo/platform/condition_variable.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/transport/baton.h"
#include "mongo/util/future.h"
#include "mongo/util/out_of_line_executor.h"
diff --git a/src/mongo/executor/thread_pool_task_executor.h b/src/mongo/executor/thread_pool_task_executor.h
index 445c5fc610d..746bfbb3eef 100644
--- a/src/mongo/executor/thread_pool_task_executor.h
+++ b/src/mongo/executor/thread_pool_task_executor.h
@@ -33,8 +33,8 @@
#include <memory>
#include "mongo/executor/task_executor.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/transport/baton.h"
#include "mongo/util/fail_point.h"
diff --git a/src/mongo/platform/SConscript b/src/mongo/platform/SConscript
index 910d1388223..648445c0746 100644
--- a/src/mongo/platform/SConscript
+++ b/src/mongo/platform/SConscript
@@ -8,7 +8,6 @@ env.CppUnitTest(
'atomic_proxy_test.cpp',
'atomic_word_test.cpp',
'bits_test.cpp',
- 'condition_variable_test.cpp',
'endian_test.cpp',
'mutex_test.cpp',
'process_id_test.cpp',
diff --git a/src/mongo/platform/condition_variable.cpp b/src/mongo/platform/condition_variable.cpp
deleted file mode 100644
index ef6e64aaff7..00000000000
--- a/src/mongo/platform/condition_variable.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Copyright (C) 2018-present MongoDB, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the Server Side Public License, version 1,
- * as published by MongoDB, Inc.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * Server Side Public License for more details.
- *
- * You should have received a copy of the Server Side Public License
- * along with this program. If not, see
- * <http://www.mongodb.com/licensing/server-side-public-license>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the Server Side Public License in all respects for
- * all of the code used other than as permitted herein. If you modify file(s)
- * with this exception, you may extend this exception to your version of the
- * file(s), but you are not obligated to do so. If you do not wish to do so,
- * delete this exception statement from your version. If you delete this
- * exception statement from all source files in the program, then also delete
- * it in the license file.
- */
-
-#include "mongo/platform/basic.h"
-
-#include "mongo/platform/condition_variable.h"
-
-namespace mongo {
-
-std::unique_ptr<ConditionVariableActions> ConditionVariable::_conditionVariableActions;
-
-void ConditionVariable::notify_one() noexcept {
- _condvar.notify_one();
-}
-
-void ConditionVariable::notify_all() noexcept {
- _condvar.notify_all();
-}
-
-void ConditionVariable::setConditionVariableActions(
- std::unique_ptr<ConditionVariableActions> actions) {
- _conditionVariableActions = std::move(actions);
-}
-} // namespace mongo
diff --git a/src/mongo/platform/condition_variable.h b/src/mongo/platform/condition_variable.h
deleted file mode 100644
index beca4f4dda9..00000000000
--- a/src/mongo/platform/condition_variable.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/**
- * Copyright (C) 2018-present MongoDB, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the Server Side Public License, version 1,
- * as published by MongoDB, Inc.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * Server Side Public License for more details.
- *
- * You should have received a copy of the Server Side Public License
- * along with this program. If not, see
- * <http://www.mongodb.com/licensing/server-side-public-license>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the Server Side Public License in all respects for
- * all of the code used other than as permitted herein. If you modify file(s)
- * with this exception, you may extend this exception to your version of the
- * file(s), but you are not obligated to do so. If you do not wish to do so,
- * delete this exception statement from your version. If you delete this
- * exception statement from all source files in the program, then also delete
- * it in the license file.
- */
-
-#pragma once
-
-#include <chrono>
-
-#include "mongo/platform/mutex.h"
-#include "mongo/stdx/condition_variable.h"
-#include "mongo/util/duration.h"
-#include "mongo/util/scopeguard.h"
-
-namespace mongo {
-
-class Mutex;
-
-class ConditionVariableActions {
-public:
- virtual ~ConditionVariableActions() = default;
- virtual void onUnfulfilledConditionVariable(const StringData& name) = 0;
- virtual void onFulfilledConditionVariable() = 0;
-};
-
-class ConditionVariable {
-public:
- static constexpr Milliseconds kUnfulfilledConditionVariableTimeout = Milliseconds(100);
-
- template <class Lock>
- void wait(Lock& lock);
-
- template <class Lock, class Predicate>
- void wait(Lock& lock, Predicate pred);
-
- template <class Lock, class Rep, class Period>
- stdx::cv_status wait_for(Lock& lock, const stdx::chrono::duration<Rep, Period>& rel_time);
-
- template <class Lock, class Rep, class Period, class Predicate>
- bool wait_for(Lock& lock, const stdx::chrono::duration<Rep, Period>& rel_time, Predicate pred);
-
- template <class Lock, class Clock, class Duration>
- stdx::cv_status wait_until(Lock& lock,
- const stdx::chrono::time_point<Clock, Duration>& timeout_time);
-
- template <class Lock, class Clock, class Duration, class Predicate>
- bool wait_until(Lock& lock,
- const stdx::chrono::time_point<Clock, Duration>& timeout_time,
- Predicate pred);
-
- void notify_one() noexcept;
- void notify_all() noexcept;
-
- static void setConditionVariableActions(std::unique_ptr<ConditionVariableActions> actions);
-
-protected:
- template <typename Callback>
- friend void runWithNotifyable(ConditionVariable& cv,
- Notifyable& notifyable,
- Callback&& cb) noexcept {
- runWithNotifyable(cv._condvar, notifyable, std::forward<Callback>(cb));
- }
-
-private:
- const Seconds _conditionVariableTimeout = Seconds(604800);
- stdx::condition_variable_any _condvar;
-
- static std::unique_ptr<ConditionVariableActions> _conditionVariableActions;
-
- template <class Lock, class Duration>
- auto _wait(Lock& lock, const Duration& rel_time) {
- const auto guard = makeGuard([&] {
- if (_conditionVariableActions) {
- _conditionVariableActions->onFulfilledConditionVariable();
- }
- });
-
- if (auto cvstatus = _condvar.wait_for(
- lock, std::min(rel_time, kUnfulfilledConditionVariableTimeout.toSystemDuration()));
- cvstatus == stdx::cv_status::no_timeout ||
- rel_time <= kUnfulfilledConditionVariableTimeout.toSystemDuration()) {
- return cvstatus;
- }
-
- if (_conditionVariableActions) {
- if constexpr (std::is_same<decltype(lock), mongo::Mutex>::value) {
- _conditionVariableActions->onUnfulfilledConditionVariable(lock.getName());
- } else {
- _conditionVariableActions->onUnfulfilledConditionVariable("AnonymousLock");
- }
- }
-
- if (auto cvstatus = _condvar.wait_for(
- lock, rel_time - kUnfulfilledConditionVariableTimeout.toSystemDuration());
- cvstatus == stdx::cv_status::no_timeout) {
- return cvstatus;
- }
-
- uasserted(ErrorCodes::InternalError, "Unable to take latch, wait time exceeds set timeout");
- }
-
- template <class Lock, class Duration, class Predicate>
- auto _waitWithPredicate(Lock& lock, const Duration& rel_time, Predicate pred) {
- while (!pred()) {
- if (_wait(lock, rel_time) == stdx::cv_status::timeout) {
- return pred();
- }
- }
- return true;
- }
-};
-
-template <class Lock>
-void ConditionVariable::wait(Lock& lock) {
- _wait(lock, _conditionVariableTimeout.toSystemDuration());
-}
-
-template <class Lock, class Predicate>
-void ConditionVariable::wait(Lock& lock, Predicate pred) {
- _waitWithPredicate(lock, _conditionVariableTimeout.toSystemDuration(), std::move(pred));
-}
-
-template <class Lock, class Rep, class Period>
-stdx::cv_status ConditionVariable::wait_for(Lock& lock,
- const stdx::chrono::duration<Rep, Period>& rel_time) {
- return _wait(lock, rel_time);
-}
-
-template <class Lock, class Rep, class Period, class Predicate>
-bool ConditionVariable::wait_for(Lock& lock,
- const stdx::chrono::duration<Rep, Period>& rel_time,
- Predicate pred) {
- return _waitWithPredicate(lock, rel_time, pred);
-}
-
-template <class Lock, class Clock, class Duration>
-stdx::cv_status ConditionVariable::wait_until(
- Lock& lock, const stdx::chrono::time_point<Clock, Duration>& timeout_time) {
- return _wait(lock, timeout_time - stdx::chrono::steady_clock::now());
-}
-
-template <class Lock, class Clock, class Duration, class Predicate>
-bool ConditionVariable::wait_until(Lock& lock,
- const stdx::chrono::time_point<Clock, Duration>& timeout_time,
- Predicate pred) {
- return _waitWithPredicate(lock, timeout_time - stdx::chrono::steady_clock::now(), pred);
-}
-
-} // namespace mongo
diff --git a/src/mongo/platform/condition_variable_test.cpp b/src/mongo/platform/condition_variable_test.cpp
deleted file mode 100644
index 69631e233f2..00000000000
--- a/src/mongo/platform/condition_variable_test.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * Copyright (C) 2018-present MongoDB, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the Server Side Public License, version 1,
- * as published by MongoDB, Inc.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * Server Side Public License for more details.
- *
- * You should have received a copy of the Server Side Public License
- * along with this program. If not, see
- * <http://www.mongodb.com/licensing/server-side-public-license>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the Server Side Public License in all respects for
- * all of the code used other than as permitted herein. If you modify file(s)
- * with this exception, you may extend this exception to your version of the
- * file(s), but you are not obligated to do so. If you do not wish to do so,
- * delete this exception statement from your version. If you delete this
- * exception statement from all source files in the program, then also delete
- * it in the license file.
- */
-
-#include "mongo/unittest/unittest.h"
-
-#include "mongo/platform/condition_variable.h"
-#include "mongo/platform/mutex.h"
-#include "mongo/stdx/thread.h"
-#include "mongo/unittest/barrier.h"
-
-namespace mongo {
-
-TEST(ConditionVariable, BasicSingleThread) {
- unittest::Barrier barrier(2U);
- ConditionVariable cv;
- stdx::mutex m; // NOLINT
- bool done = false;
-
- stdx::thread worker([&]() {
- stdx::unique_lock<stdx::mutex> lk(m);
- barrier.countDownAndWait();
- ASSERT(!done);
- cv.wait(lk, [&] { return done; });
- ASSERT(done);
- });
-
- barrier.countDownAndWait();
- {
- stdx::unique_lock<stdx::mutex> lk(m);
- done = true;
- }
- cv.notify_one();
- worker.join();
-}
-} // namespace mongo
diff --git a/src/mongo/platform/mutex.cpp b/src/mongo/platform/mutex.cpp
index ba7230f8e94..3f2a18fe58a 100644
--- a/src/mongo/platform/mutex.cpp
+++ b/src/mongo/platform/mutex.cpp
@@ -32,27 +32,60 @@
namespace mongo {
void Mutex::lock() {
- auto hasLock = _mutex.try_lock();
- if (hasLock) {
+ if (_mutex.try_lock()) {
+ _onQuickLock(_name);
return;
}
- if (auto actions = LockActions::getState().actions.load()) {
- actions->onContendedLock(_name);
- }
+
+ _onContendedLock(_name);
_mutex.lock();
+ _onSlowLock(_name);
}
void Mutex::unlock() {
- if (auto actions = LockActions::getState().actions.load()) {
- actions->onUnlock(_name);
- }
+ _onUnlock(_name);
_mutex.unlock();
}
bool Mutex::try_lock() {
- return _mutex.try_lock();
+ if (!_mutex.try_lock()) {
+ return false;
+ }
+
+ _onQuickLock(_name);
+ return true;
+}
+
+void Mutex::addLockListener(LockListener* listener) {
+ auto& state = _getListenerState();
+
+ state.list.push_back(listener);
+}
+
+void Mutex::_onContendedLock(const StringData& name) noexcept {
+ auto& state = _getListenerState();
+ for (auto listener : state.list) {
+ listener->onContendedLock(name);
+ }
+}
+
+void Mutex::_onQuickLock(const StringData& name) noexcept {
+ auto& state = _getListenerState();
+ for (auto listener : state.list) {
+ listener->onQuickLock(name);
+ }
}
-void Mutex::LockActions::add(LockActions* actions) {
- getState().actions.store(actions);
+void Mutex::_onSlowLock(const StringData& name) noexcept {
+ auto& state = _getListenerState();
+ for (auto listener : state.list) {
+ listener->onSlowLock(name);
+ }
+}
+
+void Mutex::_onUnlock(const StringData& name) noexcept {
+ auto& state = _getListenerState();
+ for (auto listener : state.list) {
+ listener->onUnlock(name);
+ }
}
} // namespace mongo
diff --git a/src/mongo/platform/mutex.h b/src/mongo/platform/mutex.h
index fe72b201d3a..dd6bd4996a0 100644
--- a/src/mongo/platform/mutex.h
+++ b/src/mongo/platform/mutex.h
@@ -46,11 +46,18 @@ public:
virtual void lock() = 0;
virtual void unlock() = 0;
virtual bool try_lock() = 0;
+
+ virtual StringData getName() const {
+ return "AnonymousLatch"_sd;
+ }
};
class Mutex : public Latch {
+ class LockNotifier;
+
public:
- class LockActions;
+ class LockListener;
+
static constexpr auto kAnonymousMutexStr = "AnonymousMutex"_sd;
Mutex() : Mutex(kAnonymousMutexStr) {}
@@ -61,11 +68,36 @@ public:
void lock() override;
void unlock() override;
bool try_lock() override;
- const StringData& getName() const {
+ StringData getName() const override {
return _name;
}
+ /**
+ * This function adds a LockListener subclass to the triggers for certain actions.
+ *
+ * LockListeners can only be added and not removed. If you wish to deactivate a LockListeners
+ * subclass, please provide the switch on that subclass to noop its functions. It is only safe
+ * to add a LockListener during a MONGO_INITIALIZER.
+ */
+ static void addLockListener(LockListener* listener);
+
private:
+ static auto& _getListenerState() noexcept {
+ struct State {
+ std::vector<LockListener*> list;
+ };
+
+ // Note that state should no longer be mutated after init-time (ala MONGO_INITIALIZERS). If
+ // this changes, than this state needs to be synchronized.
+ static State state;
+ return state;
+ }
+
+ static void _onContendedLock(const StringData& name) noexcept;
+ static void _onQuickLock(const StringData& name) noexcept;
+ static void _onSlowLock(const StringData& name) noexcept;
+ static void _onUnlock(const StringData& name) noexcept;
+
const StringData _name;
stdx::mutex _mutex; // NOLINT
};
@@ -73,40 +105,31 @@ private:
/**
* A set of actions to happen upon notable events on a Lockable-conceptualized type
*/
-class Mutex::LockActions {
+class Mutex::LockListener {
friend class Mutex;
public:
- virtual ~LockActions() = default;
+ virtual ~LockListener() = default;
+
/**
* Action to do when a lock cannot be immediately acquired
*/
virtual void onContendedLock(const StringData& name) = 0;
/**
- * Action to do when a lock is unlocked
+ * Action to do when a lock was acquired without blocking
*/
- virtual void onUnlock(const StringData& name) = 0;
+ virtual void onQuickLock(const StringData& name) = 0;
/**
- * This function adds a LockActions subclass to the triggers for certain actions.
- *
- * Note that currently there is only one LockActions in use at a time. As part of SERVER-42895,
- * this will change so that there is a list of LockActions maintained.
- *
- * LockActions can only be added and not removed. If you wish to deactivate a LockActions
- * subclass, please provide the switch on that subclass to noop its functions.
+ * Action to do when a lock was acquired after blocking
*/
- static void add(LockActions* actions);
+ virtual void onSlowLock(const StringData& name) = 0;
-private:
- static auto& getState() {
- struct State {
- AtomicWord<LockActions*> actions{nullptr};
- };
- static State state;
- return state;
- }
+ /**
+ * Action to do when a lock is unlocked
+ */
+ virtual void onUnlock(const StringData& name) = 0;
};
} // namespace mongo
diff --git a/src/mongo/s/catalog/replset_dist_lock_manager.h b/src/mongo/s/catalog/replset_dist_lock_manager.h
index 38176244f33..1dfd878703b 100644
--- a/src/mongo/s/catalog/replset_dist_lock_manager.h
+++ b/src/mongo/s/catalog/replset_dist_lock_manager.h
@@ -34,12 +34,12 @@
#include <string>
#include "mongo/base/string_data.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
#include "mongo/s/catalog/dist_lock_catalog.h"
#include "mongo/s/catalog/dist_lock_manager.h"
#include "mongo/s/catalog/dist_lock_ping_info.h"
#include "mongo/stdx/chrono.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/stdx/unordered_map.h"
diff --git a/src/mongo/s/catalog/replset_dist_lock_manager_test.cpp b/src/mongo/s/catalog/replset_dist_lock_manager_test.cpp
index 89a420f50d5..4b7a38b7d21 100644
--- a/src/mongo/s/catalog/replset_dist_lock_manager_test.cpp
+++ b/src/mongo/s/catalog/replset_dist_lock_manager_test.cpp
@@ -36,7 +36,6 @@
#include <vector>
#include "mongo/bson/json.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
#include "mongo/s/balancer_configuration.h"
#include "mongo/s/catalog/dist_lock_catalog_mock.h"
@@ -46,6 +45,7 @@
#include "mongo/s/catalog/type_locks.h"
#include "mongo/s/grid.h"
#include "mongo/s/shard_server_test_fixture.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/unittest/unittest.h"
#include "mongo/util/system_tick_source.h"
#include "mongo/util/tick_source_mock.h"
diff --git a/src/mongo/s/client/shard_registry.h b/src/mongo/s/client/shard_registry.h
index 22a08cef941..2b9e839394f 100644
--- a/src/mongo/s/client/shard_registry.h
+++ b/src/mongo/s/client/shard_registry.h
@@ -36,9 +36,9 @@
#include "mongo/db/jsobj.h"
#include "mongo/executor/task_executor.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
#include "mongo/s/client/shard.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/unordered_map.h"
#include "mongo/util/concurrency/with_lock.h"
diff --git a/src/mongo/s/cluster_identity_loader.h b/src/mongo/s/cluster_identity_loader.h
index 6b6d394f9e1..df2ed8b40d6 100644
--- a/src/mongo/s/cluster_identity_loader.h
+++ b/src/mongo/s/cluster_identity_loader.h
@@ -33,8 +33,8 @@
#include "mongo/bson/oid.h"
#include "mongo/db/repl/read_concern_args.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
namespace mongo {
diff --git a/src/mongo/s/sharding_task_executor.h b/src/mongo/s/sharding_task_executor.h
index e370a5425a5..3f763d120cd 100644
--- a/src/mongo/s/sharding_task_executor.h
+++ b/src/mongo/s/sharding_task_executor.h
@@ -34,8 +34,8 @@
#include "mongo/base/status_with.h"
#include "mongo/executor/task_executor.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
namespace mongo {
namespace executor {
diff --git a/src/mongo/scripting/deadline_monitor.h b/src/mongo/scripting/deadline_monitor.h
index 39862ebf58c..40c8217cb07 100644
--- a/src/mongo/scripting/deadline_monitor.h
+++ b/src/mongo/scripting/deadline_monitor.h
@@ -31,8 +31,8 @@
#include <cstdint>
#include "mongo/platform/atomic_word.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/stdx/unordered_map.h"
#include "mongo/util/concurrency/idle_thread_block.h"
diff --git a/src/mongo/scripting/mozjs/PosixNSPR.cpp b/src/mongo/scripting/mozjs/PosixNSPR.cpp
index 6df76f4ef13..77f0aedd07f 100644
--- a/src/mongo/scripting/mozjs/PosixNSPR.cpp
+++ b/src/mongo/scripting/mozjs/PosixNSPR.cpp
@@ -17,9 +17,9 @@
#include <js/Utility.h>
#include <vm/PosixNSPR.h>
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
#include "mongo/stdx/chrono.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/concurrency/thread_name.h"
#include "mongo/util/time_support.h"
diff --git a/src/mongo/scripting/mozjs/countdownlatch.cpp b/src/mongo/scripting/mozjs/countdownlatch.cpp
index f50735c734c..d9100b4bde0 100644
--- a/src/mongo/scripting/mozjs/countdownlatch.cpp
+++ b/src/mongo/scripting/mozjs/countdownlatch.cpp
@@ -31,10 +31,10 @@
#include "mongo/scripting/mozjs/countdownlatch.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
#include "mongo/scripting/mozjs/implscope.h"
#include "mongo/scripting/mozjs/objectwrapper.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/unordered_map.h"
namespace mongo {
diff --git a/src/mongo/scripting/mozjs/jsthread.cpp b/src/mongo/scripting/mozjs/jsthread.cpp
index fcd3549d21e..d39172bb02b 100644
--- a/src/mongo/scripting/mozjs/jsthread.cpp
+++ b/src/mongo/scripting/mozjs/jsthread.cpp
@@ -38,11 +38,11 @@
#include <vm/PosixNSPR.h>
#include "mongo/db/jsobj.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
#include "mongo/scripting/mozjs/implscope.h"
#include "mongo/scripting/mozjs/valuereader.h"
#include "mongo/scripting/mozjs/valuewriter.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/log.h"
#include "mongo/util/stacktrace.h"
diff --git a/src/mongo/scripting/mozjs/proxyscope.h b/src/mongo/scripting/mozjs/proxyscope.h
index 8d3269c7474..85be843b22d 100644
--- a/src/mongo/scripting/mozjs/proxyscope.h
+++ b/src/mongo/scripting/mozjs/proxyscope.h
@@ -32,9 +32,9 @@
#include "vm/PosixNSPR.h"
#include "mongo/client/dbclient_cursor.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
#include "mongo/scripting/mozjs/engine.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/functional.h"
diff --git a/src/mongo/shell/bench.h b/src/mongo/shell/bench.h
index ea714789d3c..170023917ac 100644
--- a/src/mongo/shell/bench.h
+++ b/src/mongo/shell/bench.h
@@ -38,8 +38,8 @@
#include "mongo/db/logical_session_id.h"
#include "mongo/db/ops/write_ops_parsers.h"
#include "mongo/platform/atomic_word.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/timer.h"
diff --git a/src/mongo/transport/service_entry_point_impl.h b/src/mongo/transport/service_entry_point_impl.h
index 1788ef8a146..58fcb6cf998 100644
--- a/src/mongo/transport/service_entry_point_impl.h
+++ b/src/mongo/transport/service_entry_point_impl.h
@@ -32,8 +32,8 @@
#include <list>
#include "mongo/platform/atomic_word.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/variant.h"
#include "mongo/transport/service_entry_point.h"
#include "mongo/transport/service_executor_reserved.h"
diff --git a/src/mongo/transport/service_executor_adaptive.h b/src/mongo/transport/service_executor_adaptive.h
index a0def9da063..bf3b55b2c5c 100644
--- a/src/mongo/transport/service_executor_adaptive.h
+++ b/src/mongo/transport/service_executor_adaptive.h
@@ -35,7 +35,7 @@
#include "mongo/db/service_context.h"
#include "mongo/platform/atomic_word.h"
-#include "mongo/platform/condition_variable.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/transport/service_executor.h"
#include "mongo/transport/service_executor_task_names.h"
diff --git a/src/mongo/transport/service_executor_reserved.h b/src/mongo/transport/service_executor_reserved.h
index 53bd3b00ade..8a71090bf63 100644
--- a/src/mongo/transport/service_executor_reserved.h
+++ b/src/mongo/transport/service_executor_reserved.h
@@ -33,8 +33,8 @@
#include "mongo/base/status.h"
#include "mongo/platform/atomic_word.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/transport/service_executor.h"
#include "mongo/transport/service_executor_task_names.h"
diff --git a/src/mongo/transport/service_executor_synchronous.h b/src/mongo/transport/service_executor_synchronous.h
index 192583bded7..1f0e2f6dd33 100644
--- a/src/mongo/transport/service_executor_synchronous.h
+++ b/src/mongo/transport/service_executor_synchronous.h
@@ -33,8 +33,8 @@
#include "mongo/base/status.h"
#include "mongo/platform/atomic_word.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/transport/service_executor.h"
#include "mongo/transport/service_executor_task_names.h"
diff --git a/src/mongo/transport/transport_layer_asio.h b/src/mongo/transport/transport_layer_asio.h
index 67ffbc11f0f..77a8e5e555b 100644
--- a/src/mongo/transport/transport_layer_asio.h
+++ b/src/mongo/transport/transport_layer_asio.h
@@ -36,8 +36,8 @@
#include "mongo/base/status_with.h"
#include "mongo/config.h"
#include "mongo/db/server_options.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/transport/transport_layer.h"
#include "mongo/transport/transport_mode.h"
diff --git a/src/mongo/unittest/barrier.h b/src/mongo/unittest/barrier.h
index 4332b2480d7..de21587ea3b 100644
--- a/src/mongo/unittest/barrier.h
+++ b/src/mongo/unittest/barrier.h
@@ -29,8 +29,8 @@
#pragma once
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
namespace mongo {
namespace unittest {
diff --git a/src/mongo/util/alarm_runner_background_thread.h b/src/mongo/util/alarm_runner_background_thread.h
index 5f2b5d486cc..251b6ad89cd 100644
--- a/src/mongo/util/alarm_runner_background_thread.h
+++ b/src/mongo/util/alarm_runner_background_thread.h
@@ -28,7 +28,7 @@
*/
#pragma once
-#include "mongo/platform/condition_variable.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/alarm.h"
#include "mongo/util/concurrency/with_lock.h"
diff --git a/src/mongo/util/background.cpp b/src/mongo/util/background.cpp
index 7f34141dfad..e0bda9a55d9 100644
--- a/src/mongo/util/background.cpp
+++ b/src/mongo/util/background.cpp
@@ -36,8 +36,8 @@
#include <functional>
#include "mongo/config.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/concurrency/idle_thread_block.h"
#include "mongo/util/concurrency/mutex.h"
diff --git a/src/mongo/util/background_thread_clock_source.h b/src/mongo/util/background_thread_clock_source.h
index b7c8feed705..4835ef9eae1 100644
--- a/src/mongo/util/background_thread_clock_source.h
+++ b/src/mongo/util/background_thread_clock_source.h
@@ -34,8 +34,8 @@
#include <thread>
#include "mongo/platform/atomic_word.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/clock_source.h"
#include "mongo/util/time_support.h"
diff --git a/src/mongo/util/concurrency/notification.h b/src/mongo/util/concurrency/notification.h
index 50e6b5e2302..379b6e10d9a 100644
--- a/src/mongo/util/concurrency/notification.h
+++ b/src/mongo/util/concurrency/notification.h
@@ -32,8 +32,8 @@
#include <boost/optional.hpp>
#include "mongo/db/operation_context.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/duration.h"
#include "mongo/util/time_support.h"
diff --git a/src/mongo/util/concurrency/thread_pool.h b/src/mongo/util/concurrency/thread_pool.h
index c382df9544d..91981d1c808 100644
--- a/src/mongo/util/concurrency/thread_pool.h
+++ b/src/mongo/util/concurrency/thread_pool.h
@@ -34,8 +34,8 @@
#include <string>
#include <vector>
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/concurrency/thread_pool_interface.h"
#include "mongo/util/time_support.h"
diff --git a/src/mongo/util/concurrency/thread_pool_test.cpp b/src/mongo/util/concurrency/thread_pool_test.cpp
index 5812a860eab..9545ce99cdb 100644
--- a/src/mongo/util/concurrency/thread_pool_test.cpp
+++ b/src/mongo/util/concurrency/thread_pool_test.cpp
@@ -34,8 +34,8 @@
#include <boost/optional.hpp>
#include "mongo/base/init.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/unittest/barrier.h"
#include "mongo/unittest/death_test.h"
diff --git a/src/mongo/util/concurrency/thread_pool_test_common.cpp b/src/mongo/util/concurrency/thread_pool_test_common.cpp
index 169f5154c18..98c03f8a5d4 100644
--- a/src/mongo/util/concurrency/thread_pool_test_common.cpp
+++ b/src/mongo/util/concurrency/thread_pool_test_common.cpp
@@ -35,8 +35,8 @@
#include <memory>
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/unittest/death_test.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/concurrency/thread_pool_interface.h"
diff --git a/src/mongo/util/concurrency/ticketholder.h b/src/mongo/util/concurrency/ticketholder.h
index d67e6bd04d1..af9baa934ed 100644
--- a/src/mongo/util/concurrency/ticketholder.h
+++ b/src/mongo/util/concurrency/ticketholder.h
@@ -33,8 +33,8 @@
#endif
#include "mongo/db/operation_context.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/concurrency/mutex.h"
#include "mongo/util/time_support.h"
diff --git a/src/mongo/util/diagnostic_info.cpp b/src/mongo/util/diagnostic_info.cpp
index ea6cbe376df..e6bf99a15bf 100644
--- a/src/mongo/util/diagnostic_info.cpp
+++ b/src/mongo/util/diagnostic_info.cpp
@@ -33,25 +33,16 @@
#include "mongo/util/diagnostic_info.h"
-#include "mongo/config.h"
-
-#if defined(__linux__)
-#include <elf.h>
-#include <link.h>
-#endif
-
-#if defined(MONGO_CONFIG_HAVE_EXECINFO_BACKTRACE)
-#include <execinfo.h>
-#endif
+#include <forward_list>
#include <fmt/format.h>
#include <fmt/ostream.h>
#include "mongo/base/init.h"
#include "mongo/db/client.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
#include "mongo/util/clock_source.h"
+#include "mongo/util/interruptible.h"
#include "mongo/util/log.h"
using namespace fmt::literals;
@@ -61,25 +52,37 @@ namespace mongo {
namespace {
MONGO_FAIL_POINT_DEFINE(currentOpSpawnsThreadWaitingForLatch);
-constexpr auto kBlockedOpMutexName = "BlockedOpForTest"_sd;
+constexpr auto kBlockedOpMutexName = "BlockedOpForTestLatch"_sd;
+constexpr auto kBlockedOpInterruptibleName = "BlockedOpForTestInterruptible"_sd;
class BlockedOp {
public:
void start(ServiceContext* serviceContext);
void join();
void setIsContended(bool value);
+ void setIsWaiting(bool value);
private:
- Mutex _testMutex = MONGO_MAKE_LATCH(kBlockedOpMutexName);
-
stdx::condition_variable _cv;
stdx::mutex _m; // NOLINT
- struct State {
+ struct LatchState {
bool isContended = false;
boost::optional<stdx::thread> thread{boost::none};
+
+ Mutex mutex = MONGO_MAKE_LATCH(kBlockedOpMutexName);
};
- State _state;
+ LatchState _latchState;
+
+ struct InterruptibleState {
+ bool isWaiting = false;
+ boost::optional<stdx::thread> thread{boost::none};
+
+ stdx::condition_variable cv;
+ Mutex mutex = MONGO_MAKE_LATCH(kBlockedOpInterruptibleName);
+ bool isDone = false;
+ };
+ InterruptibleState _interruptibleState;
} gBlockedOp;
// This function causes us to make an additional thread with a self-contended lock so that
@@ -88,62 +91,94 @@ private:
void BlockedOp::start(ServiceContext* serviceContext) {
stdx::unique_lock<stdx::mutex> lk(_m);
- invariant(!_state.thread);
+ invariant(!_latchState.thread);
+ invariant(!_interruptibleState.thread);
- _testMutex.lock();
- _state.thread = stdx::thread([this, serviceContext]() mutable {
- ThreadClient tc("DiagnosticCaptureTest", serviceContext);
+ _latchState.mutex.lock();
+ _latchState.thread = stdx::thread([this, serviceContext]() mutable {
+ ThreadClient tc("DiagnosticCaptureTestLatch", serviceContext);
log() << "Entered currentOpSpawnsThreadWaitingForLatch thread";
- stdx::lock_guard testLock(_testMutex);
+ stdx::lock_guard testLock(_latchState.mutex);
log() << "Joining currentOpSpawnsThreadWaitingForLatch thread";
});
- _cv.wait(lk, [this] { return _state.isContended; });
- log() << "Started thread for currentOpSpawnsThreadWaitingForLatch";
+ _interruptibleState.thread = stdx::thread([this, serviceContext]() mutable {
+ ThreadClient tc("DiagnosticCaptureTestInterruptible", serviceContext);
+ auto opCtx = tc->makeOperationContext();
+
+ log() << "Entered currentOpSpawnsThreadWaitingForLatch thread for interruptibles";
+ stdx::unique_lock lk(_interruptibleState.mutex);
+ opCtx->waitForConditionOrInterrupt(
+ _interruptibleState.cv, lk, [&] { return _interruptibleState.isDone; });
+ _interruptibleState.isDone = false;
+
+ log() << "Joining currentOpSpawnsThreadWaitingForLatch thread for interruptibles";
+ });
+
+
+ _cv.wait(lk, [this] { return _latchState.isContended && _interruptibleState.isWaiting; });
+ log() << "Started threads for currentOpSpawnsThreadWaitingForLatch";
}
// This function unlocks testMutex and joins if there are no more callers of BlockedOp::start()
// remaining
void BlockedOp::join() {
- auto thread = [&] {
+ decltype(_latchState.thread) latchThread;
+ decltype(_interruptibleState.thread) interruptibleThread;
+ {
stdx::lock_guard<stdx::mutex> lk(_m);
- invariant(_state.thread);
+ invariant(_latchState.thread);
+ invariant(_interruptibleState.thread);
- _testMutex.unlock();
+ _latchState.mutex.unlock();
+ _latchState.isContended = false;
- _state.isContended = false;
- _cv.notify_one();
+ {
+ stdx::lock_guard lk(_interruptibleState.mutex);
+ _interruptibleState.isDone = true;
+ _interruptibleState.cv.notify_one();
+ }
+ _interruptibleState.isWaiting = false;
+
+ std::swap(_latchState.thread, latchThread);
+ std::swap(_interruptibleState.thread, interruptibleThread);
+ }
- return std::exchange(_state.thread, boost::none);
- }();
- thread->join();
+ latchThread->join();
+ interruptibleThread->join();
}
void BlockedOp::setIsContended(bool value) {
log() << "Setting isContended to " << (value ? "true" : "false");
stdx::lock_guard lk(_m);
- _state.isContended = value;
+ _latchState.isContended = value;
+ _cv.notify_one();
+}
+
+void BlockedOp::setIsWaiting(bool value) {
+ log() << "Setting isWaiting to " << (value ? "true" : "false");
+ stdx::lock_guard lk(_m);
+ _interruptibleState.isWaiting = value;
_cv.notify_one();
}
struct DiagnosticInfoHandle {
stdx::mutex mutex; // NOLINT
- boost::optional<DiagnosticInfo> maybeInfo = boost::none;
+ std::forward_list<DiagnosticInfo> list;
};
const auto getDiagnosticInfoHandle = Client::declareDecoration<DiagnosticInfoHandle>();
-MONGO_INITIALIZER(LockActions)(InitializerContext* context) {
- class LockActionsSubclass : public Mutex::LockActions {
+MONGO_INITIALIZER(LockListener)(InitializerContext* context) {
+ class LockListener : public Mutex::LockListener {
void onContendedLock(const StringData& name) override {
- auto client = Client::getCurrent();
- if (client) {
+ if (auto client = Client::getCurrent()) {
auto& handle = getDiagnosticInfoHandle(client);
stdx::lock_guard<stdx::mutex> lk(handle.mutex);
- handle.maybeInfo.emplace(DiagnosticInfo::capture(name));
+ handle.list.emplace_front(DiagnosticInfo::capture(name));
if (currentOpSpawnsThreadWaitingForLatch.shouldFail() &&
(name == kBlockedOpMutexName)) {
@@ -151,197 +186,98 @@ MONGO_INITIALIZER(LockActions)(InitializerContext* context) {
}
}
}
- void onUnlock(const StringData& name) override {
- auto client = Client::getCurrent();
- if (client) {
+
+ void onQuickLock(const StringData&) override {
+ // Do nothing
+ }
+
+ void onSlowLock(const StringData& name) override {
+ if (auto client = Client::getCurrent()) {
auto& handle = getDiagnosticInfoHandle(client);
stdx::lock_guard<stdx::mutex> lk(handle.mutex);
- handle.maybeInfo.reset();
+
+ invariant(!handle.list.empty());
+ handle.list.pop_front();
}
}
+
+ void onUnlock(const StringData&) override {
+ // Do nothing
+ }
};
// Intentionally leaked, people use Latches in detached threads
- static auto& actions = *new LockActionsSubclass;
- Mutex::LockActions::add(&actions);
+ static auto& listener = *new LockListener;
+ Mutex::addLockListener(&listener);
return Status::OK();
}
-/*
-MONGO_INITIALIZER(ConditionVariableActions)(InitializerContext* context) {
+MONGO_INITIALIZER(InterruptibleWaitListener)(InitializerContext* context) {
+ class WaitListener : public Interruptible::WaitListener {
+ using WakeReason = Interruptible::WakeReason;
+ using WakeSpeed = Interruptible::WakeSpeed;
- class ConditionVariableActionsSubclass : public ConditionVariableActions {
- void onUnfulfilledConditionVariable(const StringData& name) override {
- if (haveClient()) {
- DiagnosticInfo::Diagnostic::set(
- Client::getCurrent(),
- std::make_shared<DiagnosticInfo>(capture(name)));
+ void addInfo(const StringData& name) {
+ if (auto client = Client::getCurrent()) {
+ auto& handle = getDiagnosticInfoHandle(client);
+ stdx::lock_guard<stdx::mutex> lk(handle.mutex);
+ handle.list.emplace_front(DiagnosticInfo::capture(name));
+
+ if (currentOpSpawnsThreadWaitingForLatch.shouldFail() &&
+ (name == kBlockedOpInterruptibleName)) {
+ gBlockedOp.setIsWaiting(true);
+ }
}
}
- void onFulfilledConditionVariable() override {
- DiagnosticInfo::Diagnostic::clearDiagnostic();
- }
- };
-
- std::unique_ptr<ConditionVariableActions> conditionVariablePointer =
- std::make_unique<ConditionVariableActionsSubclass>();
- ConditionVariable::setConditionVariableActions(std::move(conditionVariablePointer));
- return Status::OK();
-}
-*/
+ void removeInfo(const StringData& name) {
+ if (auto client = Client::getCurrent()) {
+ auto& handle = getDiagnosticInfoHandle(client);
+ stdx::lock_guard<stdx::mutex> lk(handle.mutex);
-} // namespace
+ invariant(!handle.list.empty());
+ handle.list.pop_front();
+ }
+ }
-#if defined(__linux__)
-namespace {
+ void onLongSleep(const StringData& name) override {
+ addInfo(name);
+ }
-class DynamicObjectMap {
-public:
- struct Section {
- StringData objectPath;
- uintptr_t sectionOffset = 0;
- size_t sectionSize = 0;
+ void onWake(const StringData& name, WakeReason, WakeSpeed speed) override {
+ if (speed == WakeSpeed::kSlow) {
+ removeInfo(name);
+ }
+ }
};
- // uses dl_iterate_phdr to retrieve information on the shared objects that have been loaded in
- // the form of a map from segment address to object
- void init() {
- ::dl_iterate_phdr(addToMap, &_map);
- }
-
- // return a StackFrame object located at the header address in the map that is immediately
- // preceding or equal to the instruction pointer address
- DiagnosticInfo::StackFrame getFrame(void* instructionPtr) const;
-
- // callback function in dl_iterate_phdr that iterates through the shared objects and creates a
- // map from the section address to object
- static int addToMap(dl_phdr_info* info, size_t size, void* data);
-
-private:
- std::map<uintptr_t, Section> _map;
-} gDynamicObjectMap;
+ // Intentionally leaked, people can use in detached threads
+ static auto& listener = *new WaitListener();
+ Interruptible::addWaitListener(&listener);
-MONGO_INITIALIZER(InitializeDynamicObjectMap)(InitializerContext* context) {
- gDynamicObjectMap.init();
return Status::OK();
-};
-
-int DynamicObjectMap::addToMap(dl_phdr_info* info, size_t size, void* data) {
- auto& addr_map = *reinterpret_cast<decltype(DynamicObjectMap::_map)*>(data);
- for (int j = 0; j < info->dlpi_phnum; j++) {
- auto& header = info->dlpi_phdr[j];
- auto addr = info->dlpi_addr + header.p_vaddr;
- switch (header.p_type) {
- case PT_LOAD:
- case PT_DYNAMIC:
- break;
- default:
- continue;
- }
- auto frame = Section{
- info->dlpi_name, // object name
- static_cast<uintptr_t>(header.p_offset), // section offset in file
- header.p_memsz, // section size in memory
- };
- addr_map.emplace(addr, frame);
- }
- return 0;
-}
-
-DiagnosticInfo::StackFrame DynamicObjectMap::getFrame(void* instructionPtr) const {
- auto address = reinterpret_cast<uintptr_t>(instructionPtr);
-
- // instructionPtr < it->first
- auto it = _map.upper_bound(address);
- // instuctionPtr >= it->first
- --it;
-
- auto& [headerAddress, frame] = *it;
- dassert(address < (headerAddress + frame.sectionSize));
-
- auto fileOffset = address - headerAddress + frame.sectionOffset;
- return DiagnosticInfo::StackFrame{frame.objectPath, fileOffset};
}
} // namespace
-#endif // linux
-
-#if defined(MONGO_CONFIG_HAVE_EXECINFO_BACKTRACE) && defined(__linux__)
-// iterates through the backtrace instruction pointers to
-// find the instruction pointer that refers to a segment in the addr_map
-DiagnosticInfo::StackTrace DiagnosticInfo::makeStackTrace() const {
- DiagnosticInfo::StackTrace trace;
- for (auto address : _backtrace.data) {
- trace.frames.emplace_back(gDynamicObjectMap.getFrame(address));
- }
- return trace;
-}
-
-auto DiagnosticInfo::getBacktrace() -> Backtrace {
- Backtrace list;
- auto len = ::backtrace(list.data.data(), list.data.size());
- list.data.resize(len);
- return list;
-}
-#else
-DiagnosticInfo::StackTrace DiagnosticInfo::makeStackTrace() const {
- return DiagnosticInfo::StackTrace();
-}
-
-auto DiagnosticInfo::getBacktrace() -> Backtrace {
- return {};
-}
-#endif
-
-bool operator==(const DiagnosticInfo::StackFrame& frame1,
- const DiagnosticInfo::StackFrame& frame2) {
- return frame1.objectPath == frame2.objectPath &&
- frame1.instructionOffset == frame2.instructionOffset;
-}
-
-bool operator==(const DiagnosticInfo::StackTrace& trace1,
- const DiagnosticInfo::StackTrace& trace2) {
- return trace1.frames == trace2.frames;
-}
bool operator==(const DiagnosticInfo& info1, const DiagnosticInfo& info2) {
return info1._captureName == info2._captureName && info1._timestamp == info2._timestamp &&
info1._backtrace.data == info2._backtrace.data;
}
-std::string DiagnosticInfo::StackFrame::toString() const {
- return "{{ \"path\": \"{}\", \"addr\": \"0x{:x}\" }}"_format(objectPath, instructionOffset);
-}
-
-std::string DiagnosticInfo::StackTrace::toString() const {
- str::stream stream;
- stream << "{ \"backtrace\": [ ";
- bool isFirst = true;
- for (auto& frame : frames) {
- if (!std::exchange(isFirst, false)) {
- // Sadly, JSON doesn't allow trailing commas
- stream << ", ";
- }
- stream << frame.toString();
- }
- stream << "] }";
- return stream;
-}
-
std::string DiagnosticInfo::toString() const {
return "{{ \"name\": \"{}\", \"time\": \"{}\", \"backtraceSize\": {} }}"_format(
_captureName.toString(), _timestamp.toString(), _backtrace.data.size());
}
DiagnosticInfo DiagnosticInfo::capture(const StringData& captureName, Options options) {
- // uses backtrace to retrieve an array of instruction pointers for currently active
- // function calls of the program
- return DiagnosticInfo(getGlobalServiceContext()->getFastClockSource()->now(),
- captureName,
- options.shouldTakeBacktrace ? DiagnosticInfo::getBacktrace()
- : Backtrace{{}});
+ // Since we don't have a fast enough backtrace implementation at the moment, the Backtrace is
+ // always empty. If SERVER-44091 happens, this should branch on options.shouldTakeBacktrace
+ auto backtrace = Backtrace{};
+ auto currentTime = getGlobalServiceContext()->getFastClockSource()->now();
+
+ return DiagnosticInfo(currentTime, captureName, std::move(backtrace));
}
DiagnosticInfo::BlockedOpGuard::~BlockedOpGuard() {
@@ -366,7 +302,12 @@ auto DiagnosticInfo::maybeMakeBlockedOpForTest(Client* client) -> std::unique_pt
boost::optional<DiagnosticInfo> DiagnosticInfo::get(Client& client) {
auto& handle = getDiagnosticInfoHandle(client);
stdx::lock_guard<stdx::mutex> lk(handle.mutex);
- return handle.maybeInfo;
+
+ if (handle.list.empty()) {
+ return boost::none;
+ }
+
+ return handle.list.front();
}
} // namespace mongo
diff --git a/src/mongo/util/diagnostic_info.h b/src/mongo/util/diagnostic_info.h
index 4c4eb15c7ea..2b457fc50fe 100644
--- a/src/mongo/util/diagnostic_info.h
+++ b/src/mongo/util/diagnostic_info.h
@@ -31,8 +31,8 @@
#include "mongo/base/string_data.h"
#include "mongo/db/client.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/fail_point.h"
#include "mongo/util/time_support.h"
@@ -43,6 +43,12 @@ namespace mongo {
*/
class DiagnosticInfo {
public:
+ // Maximum number of stack frames to appear in a DiagnosticInfo::Backtrace.
+ static constexpr size_t kMaxBackTraceFrames = 100ull;
+ struct Backtrace {
+ std::vector<void*> data = std::vector<void*>(kMaxBackTraceFrames, nullptr);
+ };
+
/**
* A simple RAII guard to attempt to join a blocked op once it is no longer needed
*
@@ -57,32 +63,6 @@ public:
virtual ~DiagnosticInfo() = default;
- // Maximum number of stack frames to appear in a backtrace.
- static constexpr size_t kMaxBackTraceFrames = 100ull;
- struct Backtrace {
- std::vector<void*> data = std::vector<void*>(kMaxBackTraceFrames, nullptr);
- };
-
- struct StackFrame {
- std::string toString() const;
- friend bool operator==(const StackFrame& frame1, const StackFrame& frame2);
- friend bool operator!=(const StackFrame& frame1, const StackFrame& frame2) {
- return !(frame1 == frame2);
- }
-
- StringData objectPath;
- uintptr_t instructionOffset = 0;
- };
- struct StackTrace {
- std::string toString() const;
- friend bool operator==(const StackTrace& trace1, const StackTrace& trace2);
- friend bool operator!=(const StackTrace& trace1, const StackTrace& trace2) {
- return !(trace1 == trace2);
- }
-
- std::vector<StackFrame> frames;
- };
-
Date_t getTimestamp() const {
return _timestamp;
}
@@ -91,10 +71,6 @@ public:
return _captureName;
}
- StackTrace makeStackTrace() const;
-
- static Backtrace getBacktrace();
-
std::string toString() const;
/**
@@ -117,6 +93,10 @@ public:
*/
static std::unique_ptr<BlockedOpGuard> maybeMakeBlockedOpForTest(Client* client);
+ friend std::ostream& operator<<(std::ostream& s, const DiagnosticInfo& info) {
+ return s << info.toString();
+ }
+
private:
friend bool operator==(const DiagnosticInfo& info1, const DiagnosticInfo& info2);
friend bool operator!=(const DiagnosticInfo& info1, const DiagnosticInfo& info2) {
@@ -133,12 +113,4 @@ private:
};
-inline std::ostream& operator<<(std::ostream& s, const DiagnosticInfo::StackFrame& frame) {
- return s << frame.toString();
-}
-
-inline std::ostream& operator<<(std::ostream& s, const DiagnosticInfo& info) {
- return s << info.toString();
-}
-
} // namespace mongo
diff --git a/src/mongo/util/diagnostic_info_test.cpp b/src/mongo/util/diagnostic_info_test.cpp
index dc8ebdda058..3c054d685dc 100644
--- a/src/mongo/util/diagnostic_info_test.cpp
+++ b/src/mongo/util/diagnostic_info_test.cpp
@@ -65,94 +65,4 @@ TEST(DiagnosticInfo, BasicSingleThread) {
clockSourcePointer->advance(Seconds(1));
ASSERT_LT(capture2.getTimestamp(), clockSourcePointer->now());
}
-
-using MaybeDiagnosticInfo = boost::optional<DiagnosticInfo>;
-void recurseAndCaptureInfo(MaybeDiagnosticInfo& info, AtomicWord<int>& i);
-
-TEST(DiagnosticInfo, StackTraceTest) {
- // set up serviceContext and clock source
- auto serviceContext = ServiceContext::make();
- auto clockSource = std::make_unique<ClockSourceMock>();
- serviceContext->setFastClockSource(std::move(clockSource));
- setGlobalServiceContext(std::move(serviceContext));
-
- MaybeDiagnosticInfo infoRecurse0;
- {
- AtomicWord<int> i{0};
- recurseAndCaptureInfo(infoRecurse0, i);
- }
-
- ASSERT(infoRecurse0);
- log() << *infoRecurse0;
- auto trace0 = infoRecurse0->makeStackTrace();
- log() << trace0;
-
-#ifdef __linux__
- auto testRecursion = [&](size_t i, const MaybeDiagnosticInfo& infoRecurse) {
- ASSERT(infoRecurse);
- log() << *infoRecurse;
-
- auto trace = infoRecurse->makeStackTrace();
- log() << trace;
- ASSERT_EQ(trace0.frames.size() + i, trace.frames.size());
-
- auto it = trace.frames.begin();
- auto it0 = trace0.frames.begin();
-
- for (; *it == *it0; ++it, ++it0) {
- // The begining of the trace should be the same
- }
-
- size_t j = 0;
- auto recursiveFrame = *it;
- for (; *it == recursiveFrame; ++it, ++j) {
- // Advance the recursive trace through the recursion
- ASSERT_NE(*it, *it0);
-
- // The recursive frame should always be on the main executable
- ASSERT_EQ(it->objectPath, "");
- }
- ASSERT_EQ(j, i);
-
- // The frame right above the recursion will be a different return
- ASSERT_NE(*it, *it0);
- ++it, ++it0;
-
- for (; it0 != trace0.frames.end() && *it == *it0; ++it, ++it0) {
- // The end of the trace should be the same
- }
-
- ASSERT(it == trace.frames.end());
- };
-
- {
- constexpr auto k = 3;
- AtomicWord<int> i{k};
- MaybeDiagnosticInfo infoRecurse;
- recurseAndCaptureInfo(infoRecurse, i);
- testRecursion(k, infoRecurse);
- }
-
- {
- constexpr auto k = 10;
- AtomicWord<int> i{k};
- MaybeDiagnosticInfo infoRecurse;
- recurseAndCaptureInfo(infoRecurse, i);
- testRecursion(k, infoRecurse);
- }
-#else
- ASSERT_TRUE(trace0.frames.empty());
-#endif
-}
-
-MONGO_COMPILER_NOINLINE void recurseAndCaptureInfo(MaybeDiagnosticInfo& info, AtomicWord<int>& i) {
- if (i.fetchAndSubtract(1) == 0) {
- DiagnosticInfo::Options options;
- options.shouldTakeBacktrace = true;
- info = DiagnosticInfo::capture("Recursion!"_sd, std::move(options));
- return;
- }
-
- recurseAndCaptureInfo(info, i);
-}
} // namespace mongo
diff --git a/src/mongo/util/exit.cpp b/src/mongo/util/exit.cpp
index 49b741c4493..d79c9fde1c8 100644
--- a/src/mongo/util/exit.cpp
+++ b/src/mongo/util/exit.cpp
@@ -37,8 +37,8 @@
#include <functional>
#include <stack>
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/log.h"
#include "mongo/util/quick_exit.h"
diff --git a/src/mongo/util/future_impl.h b/src/mongo/util/future_impl.h
index db83f1c0cbc..a08516191f4 100644
--- a/src/mongo/util/future_impl.h
+++ b/src/mongo/util/future_impl.h
@@ -38,8 +38,8 @@
#include "mongo/base/status.h"
#include "mongo/base/status_with.h"
#include "mongo/platform/atomic_word.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/type_traits.h"
#include "mongo/stdx/utility.h"
#include "mongo/util/assert_util.h"
diff --git a/src/mongo/util/interruptible.h b/src/mongo/util/interruptible.h
index d72be7b77d0..3a036f55201 100644
--- a/src/mongo/util/interruptible.h
+++ b/src/mongo/util/interruptible.h
@@ -29,9 +29,13 @@
#pragma once
+#include <vector>
+
+#include "mongo/platform/mutex.h"
#include "mongo/stdx/condition_variable.h"
-#include "mongo/stdx/mutex.h"
+#include "mongo/util/concepts.h"
#include "mongo/util/lockable_adapter.h"
+#include "mongo/util/scopeguard.h"
#include "mongo/util/time_support.h"
#include "mongo/util/waitable.h"
@@ -201,6 +205,36 @@ private:
}
public:
+ class WaitListener;
+
+ /**
+ * Enum to convey why an Interruptible woke up
+ */
+ enum class WakeReason {
+ kPredicate,
+ kTimeout,
+ kInterrupt,
+ };
+
+ static constexpr auto kFastWakeTimeout = Milliseconds(100);
+
+ /**
+ * Enum to convey if an Interruptible woke up before or after kFastWakeTimeout
+ */
+ enum class WakeSpeed {
+ kFast,
+ kSlow,
+ };
+
+ /**
+ * This function adds a WaitListener subclass to the triggers for certain actions.
+ *
+ * WaitListeners can only be added and not removed. If you wish to deactivate a WaitListeners
+ * subclass, please provide the switch on that subclass to noop its functions. It is only safe
+ * to add a WaitListener during a MONGO_INITIALIZER.
+ */
+ static void addWaitListener(WaitListener* listnener);
+
/**
* Returns a statically allocated instance that cannot be interrupted. Useful as a default
* argument to Interruptible-taking methods.
@@ -257,6 +291,23 @@ public:
}
/**
+ * Get the name for a Latch
+ */
+ TEMPLATE(typename LatchT)
+ REQUIRES(std::is_base_of_v<Latch, LatchT>) //
+ static StringData getLatchName(const stdx::unique_lock<LatchT>& lk) {
+ return lk.mutex()->getName();
+ }
+
+ /**
+ * Get a placeholder name for an arbitrary type
+ */
+ template <typename LockT>
+ static constexpr StringData getLatchName(const LockT&) {
+ return "AnonymousLockable"_sd;
+ }
+
+ /**
* Waits on condition "cv" for "pred" until "pred" returns true, or the given "deadline"
* expires, or this operation is interrupted, or this operation's own deadline expires.
*
@@ -267,20 +318,73 @@ public:
template <typename LockT, typename PredicateT>
bool waitForConditionOrInterruptUntil(stdx::condition_variable& cv,
LockT& m,
- Date_t deadline,
+ Date_t finalDeadline,
PredicateT pred) {
- auto waitUntil = [&](Date_t deadline) {
- // Wrapping this in a lambda because it's a mouthful
- return uassertStatusOK(waitForConditionOrInterruptNoAssertUntil(cv, m, deadline));
+ auto latchName = getLatchName(m);
+
+ auto waitUntil = [&](Date_t deadline, WakeSpeed speed) -> boost::optional<WakeReason> {
+ // If the result of waitForConditionOrInterruptNoAssertUntil() is non-spurious, return
+ // a WakeReason. Otherwise, return boost::none
+
+ auto swResult = waitForConditionOrInterruptNoAssertUntil(cv, m, deadline);
+ if (!swResult.isOK()) {
+ _onWake(latchName, WakeReason::kInterrupt, speed);
+ uassertStatusOK(std::move(swResult));
+ }
+
+ if (pred()) {
+ _onWake(latchName, WakeReason::kPredicate, speed);
+ return WakeReason::kPredicate;
+ }
+
+ if (swResult.getValue() == stdx::cv_status::timeout) {
+ _onWake(latchName, WakeReason::kTimeout, speed);
+ return WakeReason::kTimeout;
+ }
+
+ return boost::none;
};
- while (!pred()) {
- if (waitUntil(deadline) == stdx::cv_status::timeout) {
- return pred();
+ auto waitUntilNonSpurious = [&](Date_t deadline, WakeSpeed speed) -> WakeReason {
+ // Check waitUntil() in a loop until it says it has a genuine WakeReason
+
+ if (pred()) {
+ // Check for the predicate first, just in case
+ _onWake(latchName, WakeReason::kPredicate, speed);
+ return WakeReason::kPredicate;
}
+
+ auto maybeWakeReason = waitUntil(deadline, speed);
+ while (!maybeWakeReason) {
+ maybeWakeReason = waitUntil(deadline, speed);
+ };
+
+ return *maybeWakeReason;
};
- return true;
+ const auto traceDeadline = getExpirationDateForWaitForValue(kFastWakeTimeout);
+ const auto firstDeadline = std::min(traceDeadline, finalDeadline);
+
+ // Wait for the first deadline
+ if (auto wakeReason = waitUntilNonSpurious(firstDeadline, WakeSpeed::kFast);
+ wakeReason == WakeReason::kPredicate) {
+ // If our first wait fulfilled our predicate then return true
+ return true;
+ } else if (firstDeadline == finalDeadline) {
+ // If we didn't fulfill our predicate but finalDeadline was less than traceDeadline,
+ // then the wait should return false
+ return false;
+ }
+
+ _onLongSleep(latchName);
+
+ // Wait for the final deadline
+ if (auto wakeReason = waitUntilNonSpurious(finalDeadline, WakeSpeed::kSlow);
+ wakeReason == WakeReason::kPredicate) {
+ return true;
+ } else {
+ return false;
+ }
}
/**
@@ -329,9 +433,67 @@ public:
protected:
class NotInterruptible;
+
+ void _onLongSleep(const StringData& name);
+ void _onWake(const StringData& name, WakeReason reason, WakeSpeed speed);
+
+ static auto& _getListenerState() {
+ struct State {
+ std::vector<WaitListener*> list;
+ };
+
+ // Note that state should no longer be mutated after init-time (ala MONGO_INITIALIZERS). If
+ // this changes, than this state needs to be synchronized.
+ static State state;
+ return state;
+ }
};
/**
+ * A set of event handles for an Interruptible type
+ */
+class Interruptible::WaitListener {
+public:
+ /**
+ * Action to do when a wait does not resolve quickly
+ *
+ * Any implementation of this function must be safe to invoke when an Interruptible-associated
+ * latch is held. As this is hard to reason about, avoid external latches whenever possible.
+ */
+ virtual void onLongSleep(const StringData& name) = 0;
+
+ /**
+ * Action to do when a wait resolves after a sleep
+ *
+ * Any implementation of this function must be safe to invoke when an Interruptible-associated
+ * latch is held. As this is hard to reason about, avoid external latches whenever possible.
+ */
+ virtual void onWake(const StringData& name, WakeReason reason, WakeSpeed speed) = 0;
+};
+
+inline void Interruptible::addWaitListener(WaitListener* listener) {
+ auto& state = _getListenerState();
+
+ state.list.push_back(listener);
+}
+
+inline void Interruptible::_onLongSleep(const StringData& name) {
+ auto& state = _getListenerState();
+
+ for (auto listener : state.list) {
+ listener->onLongSleep(name);
+ }
+}
+
+inline void Interruptible::_onWake(const StringData& name, WakeReason reason, WakeSpeed speed) {
+ auto& state = _getListenerState();
+
+ for (auto listener : state.list) {
+ listener->onWake(name, reason, speed);
+ }
+}
+
+/**
* A non-interruptible type which can be used as a lightweight default arg for Interruptible-taking
* functions.
*/
diff --git a/src/mongo/util/invalidating_lru_cache.h b/src/mongo/util/invalidating_lru_cache.h
index 6cef29f63c8..9a52136ac4a 100644
--- a/src/mongo/util/invalidating_lru_cache.h
+++ b/src/mongo/util/invalidating_lru_cache.h
@@ -34,8 +34,8 @@
#include <boost/optional.hpp>
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/unordered_map.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/concurrency/with_lock.h"
diff --git a/src/mongo/util/periodic_runner_impl.h b/src/mongo/util/periodic_runner_impl.h
index 07ed7db0ebd..4a89b4b6a05 100644
--- a/src/mongo/util/periodic_runner_impl.h
+++ b/src/mongo/util/periodic_runner_impl.h
@@ -32,8 +32,8 @@
#include <memory>
#include <vector>
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/clock_source.h"
#include "mongo/util/future.h"
diff --git a/src/mongo/util/periodic_runner_impl_test.cpp b/src/mongo/util/periodic_runner_impl_test.cpp
index 21018ea09b7..185d3d2706a 100644
--- a/src/mongo/util/periodic_runner_impl_test.cpp
+++ b/src/mongo/util/periodic_runner_impl_test.cpp
@@ -34,8 +34,8 @@
#include "mongo/util/periodic_runner_impl.h"
#include "mongo/db/service_context_test_fixture.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/clock_source_mock.h"
namespace mongo {
diff --git a/src/mongo/util/producer_consumer_queue.h b/src/mongo/util/producer_consumer_queue.h
index 44a87f93aec..0836bbb28c5 100644
--- a/src/mongo/util/producer_consumer_queue.h
+++ b/src/mongo/util/producer_consumer_queue.h
@@ -35,8 +35,8 @@
#include <numeric>
#include "mongo/db/operation_context.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/util/concurrency/with_lock.h"
#include "mongo/util/interruptible.h"
#include "mongo/util/scopeguard.h"
diff --git a/src/mongo/util/producer_consumer_queue_test.cpp b/src/mongo/util/producer_consumer_queue_test.cpp
index d474c7bb7f9..5ba6a4d43de 100644
--- a/src/mongo/util/producer_consumer_queue_test.cpp
+++ b/src/mongo/util/producer_consumer_queue_test.cpp
@@ -34,8 +34,8 @@
#include "mongo/util/producer_consumer_queue.h"
#include "mongo/db/service_context.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/assert_util.h"
diff --git a/src/mongo/util/queue.h b/src/mongo/util/queue.h
index af652dcb40c..320f036e9ff 100644
--- a/src/mongo/util/queue.h
+++ b/src/mongo/util/queue.h
@@ -34,9 +34,9 @@
#include <limits>
#include <queue>
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
#include "mongo/stdx/chrono.h"
+#include "mongo/stdx/condition_variable.h"
namespace mongo {
diff --git a/src/mongo/watchdog/watchdog.h b/src/mongo/watchdog/watchdog.h
index 289d2dadac9..d7b6c74580f 100644
--- a/src/mongo/watchdog/watchdog.h
+++ b/src/mongo/watchdog/watchdog.h
@@ -35,8 +35,8 @@
#include <vector>
#include "mongo/platform/atomic_word.h"
-#include "mongo/platform/condition_variable.h"
#include "mongo/platform/mutex.h"
+#include "mongo/stdx/condition_variable.h"
#include "mongo/stdx/thread.h"
#include "mongo/util/duration.h"