diff options
author | Andrew Morrow <acm@mongodb.com> | 2015-06-19 17:18:25 -0400 |
---|---|---|
committer | Andrew Morrow <acm@mongodb.com> | 2015-06-30 12:16:55 -0400 |
commit | 6abd1d0e9cdc691e6daf30ce3316ffb820b9bb70 (patch) | |
tree | 00b5311c157c3623f92e70234bf4e8cc687c4917 | |
parent | 112ab99be08e3217aa87586a697c576dba0de5fd (diff) | |
download | mongo-6abd1d0e9cdc691e6daf30ce3316ffb820b9bb70.tar.gz |
SERVER-19099 Consistently use concurrency and time names via stdx
57 files changed, 352 insertions, 245 deletions
diff --git a/SConstruct b/SConstruct index 3ebde7845b3..bc0904be4b1 100644 --- a/SConstruct +++ b/SConstruct @@ -2039,14 +2039,21 @@ def doConfigure(myenv): myenv.ConfError("Cannot find wiredtiger headers") conf.FindSysLibDep("wiredtiger", ["wiredtiger"]) + conf.env.Append( + CPPDEFINES=[ + ("BOOST_THREAD_VERSION", "4"), + # Boost thread v4's variadic thread support doesn't + # permit more than four parameters. + "BOOST_THREAD_DONT_PROVIDE_VARIADIC_THREAD", + ] + ) + if use_system_version_of_library("boost"): if not conf.CheckCXXHeader( "boost/filesystem/operations.hpp" ): myenv.ConfError("can't find boost headers") if not conf.CheckBoostMinVersion(): myenv.ConfError("system's version of boost is too old. version 1.49 or better required") - conf.env.Append(CPPDEFINES=[("BOOST_THREAD_VERSION", "2")]) - # Note that on Windows with using-system-boost builds, the following # FindSysLibDep calls do nothing useful (but nothing problematic either) # diff --git a/jstests/parallel/del.js b/jstests/parallel/del.js index c2994924097..f197ec51bab 100644 --- a/jstests/parallel/del.js +++ b/jstests/parallel/del.js @@ -75,5 +75,5 @@ for ( i=0; i<10; i++ ){ a.del_parallel.save({done: 1}) b.del_parallel.save({done: 1}) -all[0].join() - +for ( i=0; i<all.length; i++ ) + all[i].join() diff --git a/src/mongo/client/examples/mongoperf.cpp b/src/mongo/client/examples/mongoperf.cpp index 56a06205485..0e45db2ff4d 100644 --- a/src/mongo/client/examples/mongoperf.cpp +++ b/src/mongo/client/examples/mongoperf.cpp @@ -216,6 +216,7 @@ void go() { syncDelaySecs = options["syncDelay"].numberInt(); if (syncDelaySecs) { stdx::thread t(syncThread); + t.detach(); } } @@ -241,6 +242,7 @@ void go() { while (nthr < wthr && nthr < d) { nthr++; stdx::thread w(workerThread); + w.detach(); } cout << "new thread, total running : " << nthr << endl; d *= 2; diff --git a/src/mongo/client/replica_set_monitor.cpp b/src/mongo/client/replica_set_monitor.cpp index 0c3fc67fe16..6cdc4341920 100644 --- a/src/mongo/client/replica_set_monitor.cpp +++ b/src/mongo/client/replica_set_monitor.cpp @@ -127,7 +127,7 @@ protected: // using it. if (!inShutdown() && !StaticObserver::_destroyingStatics) { stdx::unique_lock<stdx::mutex> sl(_monitorMutex); - _stopRequestedCV.timed_wait(sl, boost::posix_time::seconds(10)); + _stopRequestedCV.wait_for(sl, stdx::chrono::seconds(10)); } while (!inShutdown() && !StaticObserver::_destroyingStatics) { @@ -151,7 +151,7 @@ protected: break; } - _stopRequestedCV.timed_wait(sl, boost::posix_time::seconds(10)); + _stopRequestedCV.wait_for(sl, stdx::chrono::seconds(10)); } } diff --git a/src/mongo/client/scoped_db_conn_test.cpp b/src/mongo/client/scoped_db_conn_test.cpp index 52bfb8241db..bfdc8dab4dc 100644 --- a/src/mongo/client/scoped_db_conn_test.cpp +++ b/src/mongo/client/scoped_db_conn_test.cpp @@ -29,10 +29,8 @@ #include "mongo/platform/basic.h" -#include <mutex> #include <vector> #include <string> -#include <thread> #include "mongo/client/connpool.h" #include "mongo/client/global_conn_pool.h" @@ -40,6 +38,8 @@ #include "mongo/rpc/factory.h" #include "mongo/rpc/reply_builder_interface.h" #include "mongo/rpc/request_interface.h" +#include "mongo/stdx/mutex.h" +#include "mongo/stdx/thread.h" #include "mongo/unittest/unittest.h" #include "mongo/util/fail_point_service.h" #include "mongo/util/log.h" @@ -68,14 +68,14 @@ class OperationContext; namespace { -std::mutex shutDownMutex; +stdx::mutex shutDownMutex; bool shuttingDown = false; } // namespace // Symbols defined to build the binary correctly. bool inShutdown() { - std::lock_guard<std::mutex> sl(shutDownMutex); + stdx::lock_guard<stdx::mutex> sl(shutDownMutex); return shuttingDown; } @@ -87,7 +87,7 @@ DBClientBase* createDirectClient(OperationContext* txn) { void dbexit(ExitCode rc, const char* why) { { - std::lock_guard<std::mutex> sl(shutDownMutex); + stdx::lock_guard<stdx::mutex> sl(shutDownMutex); shuttingDown = true; } @@ -172,12 +172,12 @@ public: options.port = _port; { - std::lock_guard<std::mutex> sl(shutDownMutex); + stdx::lock_guard<stdx::mutex> sl(shutDownMutex); shuttingDown = false; } _server.reset(createServer(options, messsageHandler)); - _serverThread = std::thread(runServer, _server.get()); + _serverThread = stdx::thread(runServer, _server.get()); } /** @@ -189,7 +189,7 @@ public: } { - std::lock_guard<std::mutex> sl(shutDownMutex); + stdx::lock_guard<stdx::mutex> sl(shutDownMutex); shuttingDown = true; } @@ -222,7 +222,7 @@ public: private: const int _port; - std::thread _serverThread; + stdx::thread _serverThread; unique_ptr<MessageServer> _server; }; diff --git a/src/mongo/db/concurrency/lock_state.cpp b/src/mongo/db/concurrency/lock_state.cpp index 008646a586e..3268e2cbac0 100644 --- a/src/mongo/db/concurrency/lock_state.cpp +++ b/src/mongo/db/concurrency/lock_state.cpp @@ -226,7 +226,7 @@ void CondVarLockGrantNotification::clear() { LockResult CondVarLockGrantNotification::wait(unsigned timeoutMs) { stdx::unique_lock<stdx::mutex> lock(_mutex); while (_result == LOCK_INVALID) { - if (boost::cv_status::timeout == _cond.wait_for(lock, Milliseconds(timeoutMs))) { + if (stdx::cv_status::timeout == _cond.wait_for(lock, Milliseconds(timeoutMs))) { // Timeout return LOCK_TIMEOUT; } diff --git a/src/mongo/db/curop_test.cpp b/src/mongo/db/curop_test.cpp index 098ead0674f..aaf0933f484 100644 --- a/src/mongo/db/curop_test.cpp +++ b/src/mongo/db/curop_test.cpp @@ -65,6 +65,7 @@ void timeTrackerSetup() { MONGO_INITIALIZER(CurOpTest)(InitializerContext* context) { stdx::thread t(timeTrackerSetup); + t.detach(); // Wait for listener thread to start tracking time. while (Listener::getElapsedTimeMillis() == 0) { diff --git a/src/mongo/db/instance.cpp b/src/mongo/db/instance.cpp index 257193b53c9..c34daf48d6b 100644 --- a/src/mongo/db/instance.cpp +++ b/src/mongo/db/instance.cpp @@ -1163,6 +1163,7 @@ static void shutdownServer() { /* must do this before unmapping mem or you may get a seg fault */ log(LogComponent::kNetwork) << "shutdown: going to close sockets..." << endl; stdx::thread close_socket_thread(stdx::bind(MessagingPort::closeAllSockets, 0)); + close_socket_thread.detach(); getGlobalServiceContext()->shutdownGlobalStorageEngineCleanly(); } diff --git a/src/mongo/db/log_process_details.cpp b/src/mongo/db/log_process_details.cpp index 9ba6c91299a..777777d7a40 100644 --- a/src/mongo/db/log_process_details.cpp +++ b/src/mongo/db/log_process_details.cpp @@ -44,15 +44,12 @@ namespace mongo { -using std::cout; -using std::endl; - bool is32bit() { return (sizeof(int*) == 4); } void logProcessDetails() { - log() << mongodVersion() << endl; + log() << mongodVersion(); printGitVersion(); printOpenSSLVersion(); printAllocator(); diff --git a/src/mongo/db/range_deleter.cpp b/src/mongo/db/range_deleter.cpp index 036f8e7c4d4..7bb98bbc01f 100644 --- a/src/mongo/db/range_deleter.cpp +++ b/src/mongo/db/range_deleter.cpp @@ -436,7 +436,8 @@ void RangeDeleter::doWork() { { stdx::unique_lock<stdx::mutex> sl(_queueMutex); while (_taskQueue.empty()) { - _taskQueueNotEmptyCV.timed_wait(sl, duration::milliseconds(kNotEmptyTimeoutMillis)); + _taskQueueNotEmptyCV.wait_for(sl, + stdx::chrono::milliseconds(kNotEmptyTimeoutMillis)); if (stopRequested()) { log() << "stopping range deleter worker" << endl; diff --git a/src/mongo/db/range_deleter_test.cpp b/src/mongo/db/range_deleter_test.cpp index 782b7235d60..3db312b7f98 100644 --- a/src/mongo/db/range_deleter_test.cpp +++ b/src/mongo/db/range_deleter_test.cpp @@ -36,8 +36,10 @@ #include "mongo/db/service_context.h" #include "mongo/db/write_concern_options.h" #include "mongo/stdx/functional.h" +#include "mongo/stdx/future.h" #include "mongo/stdx/thread.h" #include "mongo/unittest/unittest.h" +#include "mongo/util/scopeguard.h" namespace { @@ -49,10 +51,11 @@ using mongo::DeletedRange; using mongo::FieldParser; using mongo::KeyRange; using mongo::Notification; +using mongo::OperationContext; using mongo::RangeDeleter; using mongo::RangeDeleterMockEnv; using mongo::RangeDeleterOptions; -using mongo::OperationContext; +using mongo::MakeGuard; namespace stdx = mongo::stdx; @@ -163,13 +166,6 @@ TEST(QueuedDelete, StopWhileWaitingCursor) { ASSERT_FALSE(env->deleteOccured()); } -static void rangeDeleterDeleteNow(RangeDeleter* deleter, - OperationContext* txn, - const RangeDeleterOptions& deleterOptions, - std::string* errMsg) { - deleter->deleteNow(txn, deleterOptions, errMsg); -} - // Should not start delete if the set of cursors that were open when the // deleteNow method is called is still open. TEST(ImmediateDelete, ShouldWaitCursor) { @@ -191,8 +187,16 @@ TEST(ImmediateDelete, ShouldWaitCursor) { RangeDeleterOptions deleterOption( KeyRange(ns, BSON("x" << 0), BSON("x" << 10), BSON("x" << 1))); deleterOption.waitForOpenCursors = true; - stdx::thread deleterThread = stdx::thread( - mongo::stdx::bind(rangeDeleterDeleteNow, &deleter, noTxn, deleterOption, &errMsg)); + + stdx::packaged_task<void()> deleterTask( + [&] { deleter.deleteNow(noTxn, deleterOption, &errMsg); }); + stdx::future<void> deleterFuture = deleterTask.get_future(); + stdx::thread deleterThread(std::move(deleterTask)); + + auto guard = MakeGuard([&] { + deleter.stopWorkers(); + deleterThread.join(); + }); env->waitForNthGetCursor(1u); @@ -206,8 +210,8 @@ TEST(ImmediateDelete, ShouldWaitCursor) { env->addCursorId(ns, 200); env->removeCursorId(ns, 345); - ASSERT_TRUE( - deleterThread.timed_join(boost::posix_time::seconds(MAX_IMMEDIATE_DELETE_WAIT_SECS))); + ASSERT_TRUE(stdx::future_status::ready == + deleterFuture.wait_for(stdx::chrono::seconds(MAX_IMMEDIATE_DELETE_WAIT_SECS))); ASSERT_TRUE(env->deleteOccured()); const DeletedRange deletedChunk(env->getLastDelete()); @@ -216,8 +220,6 @@ TEST(ImmediateDelete, ShouldWaitCursor) { ASSERT_TRUE(deletedChunk.min.equal(BSON("x" << 0))); ASSERT_TRUE(deletedChunk.max.equal(BSON("x" << 10))); ASSERT_TRUE(deletedChunk.shardKeyPattern.equal(BSON("x" << 1))); - - deleter.stopWorkers(); } // Should terminate when stop is requested. @@ -240,8 +242,14 @@ TEST(ImmediateDelete, StopWhileWaitingCursor) { RangeDeleterOptions deleterOption( KeyRange(ns, BSON("x" << 0), BSON("x" << 10), BSON("x" << 1))); deleterOption.waitForOpenCursors = true; - stdx::thread deleterThread = stdx::thread( - mongo::stdx::bind(rangeDeleterDeleteNow, &deleter, noTxn, deleterOption, &errMsg)); + + stdx::packaged_task<void()> deleterTask( + [&] { deleter.deleteNow(noTxn, deleterOption, &errMsg); }); + stdx::future<void> deleterFuture = deleterTask.get_future(); + stdx::thread deleterThread(std::move(deleterTask)); + + auto join_thread_guard = MakeGuard([&] { deleterThread.join(); }); + auto stop_deleter_guard = MakeGuard([&] { deleter.stopWorkers(); }); env->waitForNthGetCursor(1u); @@ -251,10 +259,10 @@ TEST(ImmediateDelete, StopWhileWaitingCursor) { ASSERT_FALSE(env->deleteOccured()); - deleter.stopWorkers(); + stop_deleter_guard.Execute(); - ASSERT_TRUE( - deleterThread.timed_join(boost::posix_time::seconds(MAX_IMMEDIATE_DELETE_WAIT_SECS))); + ASSERT_TRUE(stdx::future_status::ready == + deleterFuture.wait_for(stdx::chrono::seconds(MAX_IMMEDIATE_DELETE_WAIT_SECS))); ASSERT_FALSE(env->deleteOccured()); } diff --git a/src/mongo/db/repl/data_replicator.cpp b/src/mongo/db/repl/data_replicator.cpp index 11c55208268..feb2ec711b2 100644 --- a/src/mongo/db/repl/data_replicator.cpp +++ b/src/mongo/db/repl/data_replicator.cpp @@ -33,7 +33,6 @@ #include "data_replicator.h" #include <algorithm> -#include <thread> #include "mongo/base/status.h" #include "mongo/client/query_fetcher.h" diff --git a/src/mongo/db/repl/data_replicator_test.cpp b/src/mongo/db/repl/data_replicator_test.cpp index 84cd64c1866..661c97d6e57 100644 --- a/src/mongo/db/repl/data_replicator_test.cpp +++ b/src/mongo/db/repl/data_replicator_test.cpp @@ -356,7 +356,7 @@ protected: } void verifySync(Status s = Status::OK()) { - verifySync(_isbr->getResult().getStatus().code()); + ASSERT_EQ(_isbr->getResult().getStatus(), s) << "status objects differ"; } void verifySync(ErrorCodes::Error code) { diff --git a/src/mongo/db/repl/master_slave.cpp b/src/mongo/db/repl/master_slave.cpp index 074a7fcbe77..7a9eea27a98 100644 --- a/src/mongo/db/repl/master_slave.cpp +++ b/src/mongo/db/repl/master_slave.cpp @@ -1348,12 +1348,14 @@ void startMasterSlave(OperationContext* txn) { verify(replSettings.slave == SimpleSlave); LOG(1) << "slave=true" << endl; stdx::thread repl_thread(replSlaveThread); + repl_thread.detach(); } if (replSettings.master) { LOG(1) << "master=true" << endl; createOplog(txn); stdx::thread t(replMasterThread); + t.detach(); } if (replSettings.fastsync) { diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp index 213cb9f38a6..1f7334e5481 100644 --- a/src/mongo/db/repl/oplog.cpp +++ b/src/mongo/db/repl/oplog.cpp @@ -824,7 +824,7 @@ void waitUpToOneSecondForTimestampChange(const Timestamp& referenceTime) { stdx::unique_lock<stdx::mutex> lk(newOpMutex); while (referenceTime == getLastSetTimestamp()) { - if (!newTimestampNotifier.timed_wait(lk, boost::posix_time::seconds(1))) + if (stdx::cv_status::timeout == newTimestampNotifier.wait_for(lk, stdx::chrono::seconds(1))) return; } } diff --git a/src/mongo/db/repl/replication_coordinator_impl_test.cpp b/src/mongo/db/repl/replication_coordinator_impl_test.cpp index de1e0eb1e05..0f811630297 100644 --- a/src/mongo/db/repl/replication_coordinator_impl_test.cpp +++ b/src/mongo/db/repl/replication_coordinator_impl_test.cpp @@ -30,7 +30,6 @@ #include "mongo/platform/basic.h" -#include <future> #include <iostream> #include <memory> #include <set> @@ -57,6 +56,7 @@ #include "mongo/db/write_concern_options.h" #include "mongo/executor/network_interface_mock.h" #include "mongo/stdx/functional.h" +#include "mongo/stdx/future.h" #include "mongo/stdx/thread.h" #include "mongo/unittest/unittest.h" #include "mongo/util/assert_util.h" @@ -1872,7 +1872,6 @@ TEST_F(ReplCoordTest, AwaitReplicationReconfigNodeCountExceedsNumberOfNodes) { getNet()->exitNetwork(); reconfigThread.join(); ASSERT_OK(status); - std::cout << "asdf" << std::endl; // writeconcern feasability should be reevaluated and an error should be returned ReplicationCoordinator::StatusAndDuration statusAndDur = awaiter.getResult(); @@ -2162,11 +2161,11 @@ TEST_F(ReplCoordTest, ReadAfterDeferredGreaterOpTime) { getReplCoord()->setMyLastOptime(OpTimeWithTermZero(0, 0)); - auto pseudoLogOp = std::async(std::launch::async, - [this]() { - // Not guaranteed to be scheduled after waitUnitl blocks... - getReplCoord()->setMyLastOptime(OpTimeWithTermZero(200, 0)); - }); + auto pseudoLogOp = stdx::async(stdx::launch::async, + [this]() { + // Not guaranteed to be scheduled after waitUntil blocks... + getReplCoord()->setMyLastOptime(OpTimeWithTermZero(200, 0)); + }); auto result = getReplCoord()->waitUntilOpTime(&txn, ReadAfterOpTimeArgs(OpTimeWithTermZero(100, 0))); @@ -2189,11 +2188,11 @@ TEST_F(ReplCoordTest, ReadAfterDeferredEqualOpTime) { OpTimeWithTermZero opTimeToWait(100, 0); - auto pseudoLogOp = std::async(std::launch::async, - [this, &opTimeToWait]() { - // Not guaranteed to be scheduled after waitUnitl blocks... - getReplCoord()->setMyLastOptime(opTimeToWait); - }); + auto pseudoLogOp = stdx::async(stdx::launch::async, + [this, &opTimeToWait]() { + // Not guaranteed to be scheduled after waitUntil blocks... + getReplCoord()->setMyLastOptime(opTimeToWait); + }); auto result = getReplCoord()->waitUntilOpTime(&txn, ReadAfterOpTimeArgs(opTimeToWait)); pseudoLogOp.get(); diff --git a/src/mongo/db/repl/replication_executor.cpp b/src/mongo/db/repl/replication_executor.cpp index 30c0b0ef733..0c366836bb2 100644 --- a/src/mongo/db/repl/replication_executor.cpp +++ b/src/mongo/db/repl/replication_executor.cpp @@ -33,7 +33,6 @@ #include "mongo/db/repl/replication_executor.h" #include <limits> -#include <thread> #include "mongo/db/repl/database_task.h" #include "mongo/db/repl/storage_interface.h" diff --git a/src/mongo/db/repl/snapshot_thread.h b/src/mongo/db/repl/snapshot_thread.h index 71aeede08d8..c657ee0d554 100644 --- a/src/mongo/db/repl/snapshot_thread.h +++ b/src/mongo/db/repl/snapshot_thread.h @@ -28,11 +28,10 @@ #pragma once -#include <functional> - #include "mongo/base/disallow_copying.h" #include "mongo/db/service_context.h" #include "mongo/db/storage/snapshot_manager.h" +#include "mongo/stdx/functional.h" #include "mongo/stdx/thread.h" namespace mongo { @@ -48,7 +47,7 @@ class SnapshotThread { MONGO_DISALLOW_COPYING(SnapshotThread); public: - using Callback = std::function<void(SnapshotName)>; + using Callback = stdx::function<void(SnapshotName)>; /** * Starts a thread to take periodic snapshots if supported by the storageEngine. diff --git a/src/mongo/db/storage/mmap_v1/dur.cpp b/src/mongo/db/storage/mmap_v1/dur.cpp index a17a7a80d51..359e231f1b3 100644 --- a/src/mongo/db/storage/mmap_v1/dur.cpp +++ b/src/mongo/db/storage/mmap_v1/dur.cpp @@ -687,7 +687,7 @@ static void durThread() { stdx::unique_lock<stdx::mutex> lock(flushMutex); for (unsigned i = 0; i <= 2; i++) { - if (boost::cv_status::no_timeout == + if (stdx::cv_status::no_timeout == flushRequested.wait_for(lock, Milliseconds(oneThird))) { // Someone forced a flush break; diff --git a/src/mongo/db/storage/mmap_v1/file_allocator.cpp b/src/mongo/db/storage/mmap_v1/file_allocator.cpp index f033e1c6a5a..04fa0e6f420 100644 --- a/src/mongo/db/storage/mmap_v1/file_allocator.cpp +++ b/src/mongo/db/storage/mmap_v1/file_allocator.cpp @@ -129,6 +129,7 @@ FileAllocator::FileAllocator() : _failed() {} void FileAllocator::start() { stdx::thread t(stdx::bind(&FileAllocator::run, this)); + t.detach(); } void FileAllocator::requestAllocation(const string& name, long& size) { diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp index 536eb8c2ac3..8611347b206 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_record_store.cpp @@ -620,7 +620,7 @@ int64_t WiredTigerRecordStore::cappedDeleteAsNeeded(OperationContext* txn, // Don't wait forever: we're in a transaction, we could block eviction. if (!lock.try_lock()) { Date_t before = Date_t::now(); - (void)lock.timed_lock(boost::posix_time::millisec(200)); + (void)lock.try_lock_for(stdx::chrono::milliseconds(200)); stdx::chrono::milliseconds delay = Date_t::now() - before; _cappedSleep.fetchAndAdd(1); _cappedSleepMS.fetchAndAdd(delay.count()); @@ -635,7 +635,7 @@ int64_t WiredTigerRecordStore::cappedDeleteAsNeeded(OperationContext* txn, // Don't wait forever: we're in a transaction, we could block eviction. Date_t before = Date_t::now(); - bool gotLock = lock.timed_lock(boost::posix_time::millisec(200)); + bool gotLock = lock.try_lock_for(stdx::chrono::milliseconds(200)); stdx::chrono::milliseconds delay = Date_t::now() - before; _cappedSleep.fetchAndAdd(1); _cappedSleepMS.fetchAndAdd(delay.count()); @@ -823,7 +823,7 @@ bool WiredTigerRecordStore::isCappedHidden(const RecordId& loc) const { } RecordId WiredTigerRecordStore::lowestCappedHiddenRecord() const { - boost::lock_guard<boost::mutex> lk(_uncommittedDiskLocsMutex); + stdx::lock_guard<stdx::mutex> lk(_uncommittedDiskLocsMutex); return _uncommittedDiskLocs.empty() ? RecordId() : _uncommittedDiskLocs.front(); } diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp index 1d45be06a97..d08e6c6fbc9 100644 --- a/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp +++ b/src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp @@ -62,7 +62,7 @@ struct WaitUntilDurableData { stdx::unique_lock<stdx::mutex> lk(mutex); long long start = lastSyncTime; numWaitingForSync.fetchAndAdd(1); - condvar.timed_wait(lk, boost::posix_time::milliseconds(50)); + condvar.wait_for(lk, stdx::chrono::milliseconds(50)); numWaitingForSync.fetchAndAdd(-1); return lastSyncTime > start; } diff --git a/src/mongo/dbtests/threadedtests.cpp b/src/mongo/dbtests/threadedtests.cpp index 76c0d5b8255..1ad45c337bf 100644 --- a/src/mongo/dbtests/threadedtests.cpp +++ b/src/mongo/dbtests/threadedtests.cpp @@ -33,6 +33,7 @@ #include "mongo/platform/basic.h" +#include <boost/thread/barrier.hpp> #include <boost/version.hpp> #include <iostream> diff --git a/src/mongo/executor/network_interface_asio.cpp b/src/mongo/executor/network_interface_asio.cpp index 3c238ed83c4..459c8b36606 100644 --- a/src/mongo/executor/network_interface_asio.cpp +++ b/src/mongo/executor/network_interface_asio.cpp @@ -335,7 +335,7 @@ void NetworkInterfaceASIO::_completeOperation(AsyncOp* op) { } void NetworkInterfaceASIO::startup() { - _serviceRunner = std::thread([this]() { + _serviceRunner = stdx::thread([this]() { asio::io_service::work work(_io_service); _io_service.run(); }); @@ -411,7 +411,7 @@ void NetworkInterfaceASIO::startCommand(const TaskExecutor::CallbackHandle& cbHa } // connect in a separate thread to avoid blocking the rest of the system - std::thread t([this, op]() { + stdx::thread t([this, op]() { try { // The call to connect() will throw if: // - we cannot get a new connection from the pool diff --git a/src/mongo/executor/network_interface_asio.h b/src/mongo/executor/network_interface_asio.h index 8c179c7f1e1..8d2e9ba91cd 100644 --- a/src/mongo/executor/network_interface_asio.h +++ b/src/mongo/executor/network_interface_asio.h @@ -155,7 +155,7 @@ private: void _signalWorkAvailable_inlock(); asio::io_service _io_service; - std::thread _serviceRunner; + stdx::thread _serviceRunner; std::atomic<State> _state; diff --git a/src/mongo/executor/network_test_env.h b/src/mongo/executor/network_test_env.h index 5606d71d504..e7d56151ebd 100644 --- a/src/mongo/executor/network_test_env.h +++ b/src/mongo/executor/network_test_env.h @@ -28,13 +28,14 @@ #pragma once -#include <functional> -#include <future> #include <type_traits> #include <vector> #include "mongo/db/repl/replication_executor.h" #include "mongo/executor/network_interface_mock.h" +#include "mongo/stdx/thread.h" +#include "mongo/stdx/functional.h" +#include "mongo/stdx/future.h" namespace mongo { @@ -62,7 +63,7 @@ public: template <class T> class FutureHandle { public: - FutureHandle<T>(std::future<T> future, + FutureHandle<T>(stdx::future<T> future, executor::TaskExecutor* executor, executor::NetworkInterfaceMock* network) : _future(std::move(future)), _executor(executor), _network(network) {} @@ -100,8 +101,8 @@ public: } template <class Rep, class Period> - std::future_status wait_for( - const std::chrono::duration<Rep, Period>& timeout_duration) const { + stdx::future_status wait_for( + const stdx::chrono::duration<Rep, Period>& timeout_duration) const { return _future.wait_for(timeout_duration); } @@ -114,7 +115,7 @@ public: } private: - std::future<T> _future; + stdx::future<T> _future; executor::TaskExecutor* _executor; executor::NetworkInterfaceMock* _network; }; @@ -129,16 +130,16 @@ public: */ template <typename Lambda> FutureHandle<typename std::result_of<Lambda()>::type> launchAsync(Lambda&& func) const { - auto future = async(std::launch::async, std::forward<Lambda>(func)); + auto future = async(stdx::launch::async, std::forward<Lambda>(func)); return NetworkTestEnv::FutureHandle<typename std::result_of<Lambda()>::type>{ std::move(future), _executor, _mockNetwork}; } - using OnCommandFunction = std::function<StatusWith<BSONObj>(const RemoteCommandRequest&)>; + using OnCommandFunction = stdx::function<StatusWith<BSONObj>(const RemoteCommandRequest&)>; using OnFindCommandFunction = - std::function<StatusWith<std::vector<BSONObj>>(const RemoteCommandRequest&)>; + stdx::function<StatusWith<std::vector<BSONObj>>(const RemoteCommandRequest&)>; /** * Create a new environment based on the given network. diff --git a/src/mongo/logger/logstream_builder.h b/src/mongo/logger/logstream_builder.h index 3cf67ea75d5..275ce871bdd 100644 --- a/src/mongo/logger/logstream_builder.h +++ b/src/mongo/logger/logstream_builder.h @@ -192,7 +192,10 @@ public: template <typename Rep, typename Period> LogstreamBuilder& operator<<(stdx::chrono::duration<Rep, Period> d) { - stream() << d; + // We can't rely on ADL to find our custom stream out class, + // since neither the class (ostream) nor the argument are in + // our namespace. Just manually invoke + mongo::operator<<(stream(), d); return *this; } diff --git a/src/mongo/logger/rotatable_file_writer.h b/src/mongo/logger/rotatable_file_writer.h index b20fb818a9f..06b254b7ef5 100644 --- a/src/mongo/logger/rotatable_file_writer.h +++ b/src/mongo/logger/rotatable_file_writer.h @@ -27,6 +27,8 @@ #pragma once +#include <memory> +#include <ostream> #include <string> #include "mongo/base/disallow_copying.h" diff --git a/src/mongo/s/catalog/catalog_cache.h b/src/mongo/s/catalog/catalog_cache.h index a138c793c64..2547da29960 100644 --- a/src/mongo/s/catalog/catalog_cache.h +++ b/src/mongo/s/catalog/catalog_cache.h @@ -29,6 +29,7 @@ #pragma once #include <map> +#include <memory> #include <string> #include "mongo/base/disallow_copying.h" diff --git a/src/mongo/s/catalog/dist_lock_catalog_impl_test.cpp b/src/mongo/s/catalog/dist_lock_catalog_impl_test.cpp index c95c57c9269..a2f17bdfc60 100644 --- a/src/mongo/s/catalog/dist_lock_catalog_impl_test.cpp +++ b/src/mongo/s/catalog/dist_lock_catalog_impl_test.cpp @@ -46,6 +46,7 @@ #include "mongo/s/client/shard_registry.h" #include "mongo/s/type_lockpings.h" #include "mongo/s/type_locks.h" +#include "mongo/stdx/future.h" #include "mongo/stdx/memory.h" #include "mongo/stdx/thread.h" #include "mongo/unittest/unittest.h" diff --git a/src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp b/src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp index 7711be835a4..0db9a2ea5d4 100644 --- a/src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp +++ b/src/mongo/s/catalog/legacy/catalog_manager_legacy.cpp @@ -417,7 +417,10 @@ void CatalogManagerLegacy::shutDown() { _inShutdown = true; _consistencyCheckerCV.notify_one(); } - _consistencyCheckerThread.join(); + + // Only try to join the thread if we actually started it. + if (_consistencyCheckerThread.joinable()) + _consistencyCheckerThread.join(); invariant(_distLockManager); _distLockManager->shutDown(); diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp index 795b822e0a2..ab825acd12c 100644 --- a/src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp +++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set.cpp @@ -123,7 +123,7 @@ ConnectionString CatalogManagerReplicaSet::connectionString() const { void CatalogManagerReplicaSet::shutDown() { LOG(1) << "CatalogManagerReplicaSet::shutDown() called."; { - std::lock_guard<std::mutex> lk(_mutex); + stdx::lock_guard<stdx::mutex> lk(_mutex); _inShutdown = true; } diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set.h b/src/mongo/s/catalog/replset/catalog_manager_replica_set.h index b66432fdd0f..6409fe2f619 100644 --- a/src/mongo/s/catalog/replset/catalog_manager_replica_set.h +++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set.h @@ -29,7 +29,6 @@ #pragma once #include <memory> -#include <mutex> #include <string> #include <vector> @@ -37,6 +36,7 @@ #include "mongo/client/connection_string.h" #include "mongo/platform/atomic_word.h" #include "mongo/s/catalog/catalog_manager.h" +#include "mongo/stdx/mutex.h" namespace mongo { @@ -162,7 +162,7 @@ private: AtomicInt32 _changeLogCollectionCreated; // protects _inShutdown - std::mutex _mutex; + stdx::mutex _mutex; // True if shutDown() has been called. False, otherwise. bool _inShutdown = false; diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set_log_action_test.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set_log_action_test.cpp index 9d3d5d688f4..727e942bfa0 100644 --- a/src/mongo/s/catalog/replset/catalog_manager_replica_set_log_action_test.cpp +++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set_log_action_test.cpp @@ -30,8 +30,6 @@ #include "mongo/platform/basic.h" -#include <chrono> - #include "mongo/client/remote_command_targeter_mock.h" #include "mongo/db/commands.h" #include "mongo/executor/network_interface_mock.h" @@ -42,6 +40,8 @@ #include "mongo/s/client/shard_registry.h" #include "mongo/s/write_ops/batched_command_request.h" #include "mongo/s/write_ops/batched_command_response.h" +#include "mongo/stdx/chrono.h" +#include "mongo/stdx/future.h" #include "mongo/util/log.h" namespace mongo { @@ -51,7 +51,7 @@ using executor::NetworkInterfaceMock; using executor::TaskExecutor; using unittest::assertGet; -static const std::chrono::seconds kFutureTimeout{5}; +static const stdx::chrono::seconds kFutureTimeout{5}; class LogActionTest : public CatalogManagerReplSetTestFixture { public: diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set_log_change_test.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set_log_change_test.cpp index 22a83224f28..86d175b63e1 100644 --- a/src/mongo/s/catalog/replset/catalog_manager_replica_set_log_change_test.cpp +++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set_log_change_test.cpp @@ -30,8 +30,6 @@ #include "mongo/platform/basic.h" -#include <chrono> -#include <future> #include <vector> #include "mongo/client/remote_command_targeter_mock.h" @@ -44,6 +42,8 @@ #include "mongo/s/client/shard_registry.h" #include "mongo/s/write_ops/batched_command_request.h" #include "mongo/s/write_ops/batched_command_response.h" +#include "mongo/stdx/chrono.h" +#include "mongo/stdx/future.h" #include "mongo/util/log.h" #include "mongo/util/mongoutils/str.h" #include "mongo/util/text.h" @@ -53,10 +53,10 @@ namespace { using executor::NetworkInterfaceMock; using executor::TaskExecutor; -using std::async; +using stdx::async; using unittest::assertGet; -static const std::chrono::seconds kFutureTimeout{5}; +static const stdx::chrono::seconds kFutureTimeout{5}; class LogChangeTest : public CatalogManagerReplSetTestFixture { public: @@ -129,7 +129,7 @@ TEST_F(LogChangeTest, LogChangeNoRetryAfterSuccessfulCreate) { expectedChangeLog.setWhat("moved a chunk"); expectedChangeLog.setDetails(BSON("min" << 3 << "max" << 4)); - auto future = async(std::launch::async, + auto future = async(stdx::launch::async, [this, &expectedChangeLog] { catalogManager()->logChange(expectedChangeLog.getClientAddr(), expectedChangeLog.getWhat(), @@ -144,7 +144,7 @@ TEST_F(LogChangeTest, LogChangeNoRetryAfterSuccessfulCreate) { future.wait_for(kFutureTimeout); // Now log another change and confirm that we don't re-attempt to create the collection - future = async(std::launch::async, + future = async(stdx::launch::async, [this, &expectedChangeLog] { catalogManager()->logChange(expectedChangeLog.getClientAddr(), expectedChangeLog.getWhat(), @@ -171,7 +171,7 @@ TEST_F(LogChangeTest, LogActionNoRetryCreateIfAlreadyExists) { expectedChangeLog.setWhat("moved a chunk"); expectedChangeLog.setDetails(BSON("min" << 3 << "max" << 4)); - auto future = async(std::launch::async, + auto future = async(stdx::launch::async, [this, &expectedChangeLog] { catalogManager()->logChange(expectedChangeLog.getClientAddr(), expectedChangeLog.getWhat(), @@ -189,7 +189,7 @@ TEST_F(LogChangeTest, LogActionNoRetryCreateIfAlreadyExists) { future.wait_for(kFutureTimeout); // Now log another change and confirm that we don't re-attempt to create the collection - future = async(std::launch::async, + future = async(stdx::launch::async, [this, &expectedChangeLog] { catalogManager()->logChange(expectedChangeLog.getClientAddr(), expectedChangeLog.getWhat(), @@ -216,7 +216,7 @@ TEST_F(LogChangeTest, LogActionCreateFailure) { expectedChangeLog.setWhat("moved a chunk"); expectedChangeLog.setDetails(BSON("min" << 3 << "max" << 4)); - auto future = async(std::launch::async, + auto future = async(stdx::launch::async, [this, &expectedChangeLog] { catalogManager()->logChange(expectedChangeLog.getClientAddr(), expectedChangeLog.getWhat(), @@ -233,7 +233,7 @@ TEST_F(LogChangeTest, LogActionCreateFailure) { future.wait_for(kFutureTimeout); // Now log another change and confirm that we *do* attempt to create the collection - future = async(std::launch::async, + future = async(stdx::launch::async, [this, &expectedChangeLog] { catalogManager()->logChange(expectedChangeLog.getClientAddr(), expectedChangeLog.getWhat(), diff --git a/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp b/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp index 07da0c6d6a0..36b7a3b85bd 100644 --- a/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp +++ b/src/mongo/s/catalog/replset/catalog_manager_replica_set_test.cpp @@ -30,8 +30,6 @@ #include "mongo/platform/basic.h" -#include <chrono> - #include "mongo/client/remote_command_targeter_mock.h" #include "mongo/db/commands.h" #include "mongo/db/query/lite_parsed_query.h" @@ -52,6 +50,8 @@ #include "mongo/s/write_ops/batched_command_response.h" #include "mongo/s/write_ops/batched_insert_request.h" #include "mongo/s/write_ops/batched_update_request.h" +#include "mongo/stdx/chrono.h" +#include "mongo/stdx/future.h" #include "mongo/util/log.h" namespace mongo { @@ -64,7 +64,7 @@ using std::vector; using stdx::chrono::milliseconds; using unittest::assertGet; -static const std::chrono::seconds kFutureTimeout{5}; +static const stdx::chrono::seconds kFutureTimeout{5}; TEST_F(CatalogManagerReplSetTestFixture, GetCollectionExisting) { RemoteCommandTargeterMock* targeter = @@ -1388,7 +1388,7 @@ TEST_F(CatalogManagerReplSetTestFixture, ApplyChunkOpsDeprecated) { << BSON("precondition2" << "second precondition")); - auto future = async(std::launch::async, + auto future = async(stdx::launch::async, [this, updateOps, preCondition] { auto status = catalogManager()->applyChunkOpsDeprecated(updateOps, preCondition); @@ -1421,7 +1421,7 @@ TEST_F(CatalogManagerReplSetTestFixture, ApplyChunkOpsDeprecatedCommandFailed) { << BSON("precondition2" << "second precondition")); - auto future = async(std::launch::async, + auto future = async(stdx::launch::async, [this, updateOps, preCondition] { auto status = catalogManager()->applyChunkOpsDeprecated(updateOps, preCondition); diff --git a/src/mongo/s/catalog/replset/replset_dist_lock_manager.cpp b/src/mongo/s/catalog/replset/replset_dist_lock_manager.cpp index d057402115c..90f8288c3db 100644 --- a/src/mongo/s/catalog/replset/replset_dist_lock_manager.cpp +++ b/src/mongo/s/catalog/replset/replset_dist_lock_manager.cpp @@ -30,8 +30,6 @@ #include "mongo/platform/basic.h" -#include <chrono> - #include "mongo/s/catalog/replset/replset_dist_lock_manager.h" #include "mongo/base/status.h" @@ -40,6 +38,7 @@ #include "mongo/s/catalog/dist_lock_catalog.h" #include "mongo/s/type_lockpings.h" #include "mongo/s/type_locks.h" +#include "mongo/stdx/chrono.h" #include "mongo/stdx/memory.h" #include "mongo/util/concurrency/thread_name.h" #include "mongo/util/log.h" @@ -51,7 +50,7 @@ namespace mongo { using std::string; using std::unique_ptr; using stdx::chrono::milliseconds; -using std::chrono::duration_cast; +using stdx::chrono::duration_cast; ReplSetDistLockManager::ReplSetDistLockManager(ServiceContext* globalContext, StringData processID, diff --git a/src/mongo/s/client/shard_registry.cpp b/src/mongo/s/client/shard_registry.cpp index 158fd48013b..830354b7867 100644 --- a/src/mongo/s/client/shard_registry.cpp +++ b/src/mongo/s/client/shard_registry.cpp @@ -68,7 +68,7 @@ ShardRegistry::ShardRegistry(std::unique_ptr<RemoteCommandTargeterFactory> targe _network(network), _catalogManager(catalogManager) { // add config shard registry entry so know it's always there - std::lock_guard<std::mutex> lk(_mutex); + stdx::lock_guard<stdx::mutex> lk(_mutex); _addConfigShard_inlock(); } @@ -92,7 +92,7 @@ void ShardRegistry::reload() { LOG(1) << "found " << numShards << " shards listed on config server(s)"; - std::lock_guard<std::mutex> lk(_mutex); + stdx::lock_guard<stdx::mutex> lk(_mutex); _lookup.clear(); _rsLookup.clear(); @@ -125,14 +125,14 @@ shared_ptr<Shard> ShardRegistry::getShard(const ShardId& shardId) { } shared_ptr<Shard> ShardRegistry::lookupRSName(const string& name) const { - std::lock_guard<std::mutex> lk(_mutex); + stdx::lock_guard<stdx::mutex> lk(_mutex); ShardMap::const_iterator i = _rsLookup.find(name); return (i == _rsLookup.end()) ? nullptr : i->second; } void ShardRegistry::remove(const ShardId& id) { - std::lock_guard<std::mutex> lk(_mutex); + stdx::lock_guard<stdx::mutex> lk(_mutex); for (ShardMap::iterator i = _lookup.begin(); i != _lookup.end();) { shared_ptr<Shard> s = i->second; @@ -157,7 +157,7 @@ void ShardRegistry::getAllShardIds(vector<ShardId>* all) const { std::set<string> seen; { - std::lock_guard<std::mutex> lk(_mutex); + stdx::lock_guard<stdx::mutex> lk(_mutex); for (ShardMap::const_iterator i = _lookup.begin(); i != _lookup.end(); ++i) { const shared_ptr<Shard>& s = i->second; if (s->getId() == "config") { @@ -177,7 +177,7 @@ void ShardRegistry::getAllShardIds(vector<ShardId>* all) const { void ShardRegistry::toBSON(BSONObjBuilder* result) { BSONObjBuilder b(_lookup.size() + 50); - std::lock_guard<std::mutex> lk(_mutex); + stdx::lock_guard<stdx::mutex> lk(_mutex); for (ShardMap::const_iterator i = _lookup.begin(); i != _lookup.end(); ++i) { b.append(i->first, i->second->getConnString().toString()); @@ -242,7 +242,7 @@ void ShardRegistry::_addShard_inlock(const ShardType& shardType) { } shared_ptr<Shard> ShardRegistry::_findUsingLookUp(const ShardId& shardId) { - std::lock_guard<std::mutex> lk(_mutex); + stdx::lock_guard<stdx::mutex> lk(_mutex); ShardMap::iterator it = _lookup.find(shardId); if (it != _lookup.end()) { return it->second; diff --git a/src/mongo/s/client/shard_registry.h b/src/mongo/s/client/shard_registry.h index 5bd91b42098..a5fd0366049 100644 --- a/src/mongo/s/client/shard_registry.h +++ b/src/mongo/s/client/shard_registry.h @@ -30,12 +30,12 @@ #include <boost/optional.hpp> #include <memory> -#include <mutex> #include <string> #include <vector> #include "mongo/base/disallow_copying.h" #include "mongo/s/client/shard.h" +#include "mongo/stdx/mutex.h" namespace mongo { @@ -172,7 +172,7 @@ private: CatalogManager* const _catalogManager; // Protects the maps below - mutable std::mutex _mutex; + mutable stdx::mutex _mutex; // Map of both shardName -> Shard and hostName -> Shard ShardMap _lookup; diff --git a/src/mongo/s/d_migrate.cpp b/src/mongo/s/d_migrate.cpp index 6054a8cc32f..f8266c05db5 100644 --- a/src/mongo/s/d_migrate.cpp +++ b/src/mongo/s/d_migrate.cpp @@ -31,12 +31,8 @@ #include "mongo/platform/basic.h" #include <algorithm> -#include <chrono> -#include <condition_variable> #include <map> -#include <mutex> #include <string> -#include <thread> #include <vector> #include "mongo/client/connpool.h" @@ -55,7 +51,6 @@ #include "mongo/db/dbhelpers.h" #include "mongo/db/exec/plan_stage.h" #include "mongo/db/field_parser.h" -#include "mongo/db/service_context.h" #include "mongo/db/hasher.h" #include "mongo/db/jsobj.h" #include "mongo/db/namespace_string.h" @@ -67,21 +62,26 @@ #include "mongo/db/range_deleter_service.h" #include "mongo/db/repl/repl_client_info.h" #include "mongo/db/repl/replication_coordinator_global.h" +#include "mongo/db/service_context.h" #include "mongo/db/storage/mmap_v1/dur.h" #include "mongo/db/write_concern.h" #include "mongo/logger/ramlog.h" #include "mongo/s/catalog/catalog_manager.h" +#include "mongo/s/catalog/dist_lock_manager.h" #include "mongo/s/catalog/type_chunk.h" #include "mongo/s/chunk.h" #include "mongo/s/chunk_version.h" -#include "mongo/s/config.h" -#include "mongo/s/d_state.h" -#include "mongo/s/catalog/dist_lock_manager.h" #include "mongo/s/client/shard.h" #include "mongo/s/client/shard_registry.h" +#include "mongo/s/config.h" +#include "mongo/s/d_state.h" #include "mongo/s/grid.h" #include "mongo/s/shard_key_pattern.h" +#include "mongo/stdx/chrono.h" +#include "mongo/stdx/condition_variable.h" #include "mongo/stdx/memory.h" +#include "mongo/stdx/mutex.h" +#include "mongo/stdx/thread.h" #include "mongo/util/assert_util.h" #include "mongo/util/elapsed_tracker.h" #include "mongo/util/exit.h" @@ -98,7 +98,7 @@ namespace mongo { -using namespace std::chrono; +using namespace stdx::chrono; using std::list; using std::set; using std::string; @@ -194,7 +194,7 @@ public: CurOp* op = CurOp::get(_txn); { - std::lock_guard<Client> lk(*_txn->getClient()); + stdx::lock_guard<Client> lk(*_txn->getClient()); op->setMessage_inlock(s.c_str()); } @@ -266,7 +266,7 @@ public: // Get global shared to synchronize with logOp. Also see comments in the class // members declaration for more details. Lock::GlobalRead globalShared(txn->lockState()); - std::lock_guard<std::mutex> lk(_mutex); + stdx::lock_guard<stdx::mutex> lk(_mutex); if (_active) { return false; @@ -283,7 +283,7 @@ public: _active = true; - std::lock_guard<std::mutex> tLock(_cloneLocsMutex); + stdx::lock_guard<stdx::mutex> tLock(_cloneLocsMutex); verify(_cloneLocs.size() == 0); return true; @@ -296,7 +296,7 @@ public: // Get global shared to synchronize with logOp. Also see comments in the class // members declaration for more details. Lock::GlobalRead globalShared(txn->lockState()); - std::lock_guard<std::mutex> lk(_mutex); + stdx::lock_guard<stdx::mutex> lk(_mutex); _active = false; _deleteNotifyExec.reset(NULL); @@ -307,7 +307,7 @@ public: _reload.clear(); _memoryUsed = 0; - std::lock_guard<std::mutex> cloneLock(_cloneLocsMutex); + stdx::lock_guard<stdx::mutex> cloneLock(_cloneLocsMutex); _cloneLocs.clear(); } @@ -434,7 +434,7 @@ public: { AutoGetCollectionForRead ctx(txn, getNS()); - std::lock_guard<std::mutex> sl(_mutex); + stdx::lock_guard<stdx::mutex> sl(_mutex); if (!_active) { errmsg = "no active migration!"; return false; @@ -493,7 +493,7 @@ public: // It's alright not to lock _mutex all the way through based on the assumption // that this is only called by the main thread that drives the migration and // only it can start and stop the current migration. - std::lock_guard<std::mutex> sl(_mutex); + stdx::lock_guard<stdx::mutex> sl(_mutex); invariant(_deleteNotifyExec.get() == NULL); unique_ptr<WorkingSet> ws = stdx::make_unique<WorkingSet>(); @@ -540,7 +540,7 @@ public: RecordId dl; while (PlanExecutor::ADVANCED == exec->getNext(NULL, &dl)) { if (!isLargeChunk) { - std::lock_guard<std::mutex> lk(_cloneLocsMutex); + stdx::lock_guard<stdx::mutex> lk(_cloneLocsMutex); _cloneLocs.insert(dl); } @@ -553,7 +553,7 @@ public: exec.reset(); if (isLargeChunk) { - std::lock_guard<std::mutex> sl(_mutex); + stdx::lock_guard<stdx::mutex> sl(_mutex); warning() << "cannot move chunk: the maximum number of documents for a chunk is " << maxRecsWhenFull << " , the maximum chunk size is " << maxChunkSize << " , average document size is " << avgRecSize << ". Found " << recCount @@ -579,7 +579,7 @@ public: { AutoGetCollectionForRead ctx(txn, getNS()); - std::lock_guard<std::mutex> sl(_mutex); + stdx::lock_guard<stdx::mutex> sl(_mutex); if (!_active) { errmsg = "not active"; return false; @@ -601,7 +601,7 @@ public: while (!isBufferFilled) { AutoGetCollectionForRead ctx(txn, getNS()); - std::lock_guard<std::mutex> sl(_mutex); + stdx::lock_guard<stdx::mutex> sl(_mutex); if (!_active) { errmsg = "not active"; return false; @@ -616,7 +616,7 @@ public: return false; } - std::lock_guard<std::mutex> lk(_cloneLocsMutex); + stdx::lock_guard<stdx::mutex> lk(_cloneLocsMutex); set<RecordId>::iterator cloneLocsIter = _cloneLocs.begin(); for (; cloneLocsIter != _cloneLocs.end(); ++cloneLocsIter) { if (tracker.intervalHasElapsed()) // should I yield? @@ -659,33 +659,33 @@ public: // that check only works for non-mmapv1 engines, and this is needed // for mmapv1. - std::lock_guard<std::mutex> lk(_cloneLocsMutex); + stdx::lock_guard<stdx::mutex> lk(_cloneLocsMutex); _cloneLocs.erase(dl); } std::size_t cloneLocsRemaining() { - std::lock_guard<std::mutex> lk(_cloneLocsMutex); + stdx::lock_guard<stdx::mutex> lk(_cloneLocsMutex); return _cloneLocs.size(); } long long mbUsed() const { - std::lock_guard<std::mutex> lk(_mutex); + stdx::lock_guard<stdx::mutex> lk(_mutex); return _memoryUsed / (1024 * 1024); } bool getInCriticalSection() const { - std::lock_guard<std::mutex> lk(_mutex); + stdx::lock_guard<stdx::mutex> lk(_mutex); return _inCriticalSection; } void setInCriticalSection(bool b) { - std::lock_guard<std::mutex> lk(_mutex); + stdx::lock_guard<stdx::mutex> lk(_mutex); _inCriticalSection = b; _inCriticalSectionCV.notify_all(); } std::string getNS() const { - std::lock_guard<std::mutex> sl(_mutex); + stdx::lock_guard<stdx::mutex> sl(_mutex); return _ns; } @@ -694,9 +694,9 @@ public: */ bool waitTillNotInCriticalSection(int maxSecondsToWait) { const auto deadline = system_clock::now() + seconds(maxSecondsToWait); - std::unique_lock<std::mutex> lk(_mutex); + stdx::unique_lock<stdx::mutex> lk(_mutex); while (_inCriticalSection) { - if (std::cv_status::timeout == _inCriticalSectionCV.wait_until(lk, deadline)) + if (stdx::cv_status::timeout == _inCriticalSectionCV.wait_until(lk, deadline)) return false; } @@ -709,11 +709,11 @@ public: private: bool _getActive() const { - std::lock_guard<std::mutex> lk(_mutex); + stdx::lock_guard<stdx::mutex> lk(_mutex); return _active; } void _setActive(bool b) { - std::lock_guard<std::mutex> lk(_mutex); + stdx::lock_guard<stdx::mutex> lk(_mutex); _active = b; } @@ -735,7 +735,7 @@ private: virtual void commit() { switch (_op) { case 'd': { - std::lock_guard<std::mutex> sl(_migrateFromStatus->_mutex); + stdx::lock_guard<stdx::mutex> sl(_migrateFromStatus->_mutex); _migrateFromStatus->_deleted.push_back(_idObj); _migrateFromStatus->_memoryUsed += _idObj.firstElement().size() + 5; break; @@ -743,7 +743,7 @@ private: case 'i': case 'u': { - std::lock_guard<std::mutex> sl(_migrateFromStatus->_mutex); + stdx::lock_guard<stdx::mutex> sl(_migrateFromStatus->_mutex); _migrateFromStatus->_reload.push_back(_idObj); _migrateFromStatus->_memoryUsed += _idObj.firstElement().size() + 5; break; @@ -819,9 +819,9 @@ private: // // Global Lock -> _mutex -> _cloneLocsMutex - mutable std::mutex _mutex; + mutable stdx::mutex _mutex; - std::condition_variable _inCriticalSectionCV; // (M) + stdx::condition_variable _inCriticalSectionCV; // (M) // Is migration currently in critical section. This can be used to block new writes. bool _inCriticalSection; // (M) @@ -845,7 +845,7 @@ private: BSONObj _max; // (MG) BSONObj _shardKeyPattern; // (MG) - mutable std::mutex _cloneLocsMutex; + mutable stdx::mutex _cloneLocsMutex; // List of record id that needs to be transferred from here to the other side. set<RecordId> _cloneLocs; // (C) @@ -1804,12 +1804,12 @@ public: _state(READY) {} void setState(State newState) { - std::lock_guard<std::mutex> sl(_mutex); + stdx::lock_guard<stdx::mutex> sl(_mutex); _state = newState; } State getState() const { - std::lock_guard<std::mutex> sl(_mutex); + stdx::lock_guard<stdx::mutex> sl(_mutex); return _state; } @@ -1821,7 +1821,7 @@ public: const BSONObj& min, const BSONObj& max, const BSONObj& shardKeyPattern) { - std::lock_guard<std::mutex> lk(_mutex); + stdx::lock_guard<stdx::mutex> lk(_mutex); if (_active) { return Status(ErrorCodes::ConflictingOperationInProgress, @@ -1861,7 +1861,7 @@ public: _go(txn, ns, min, max, shardKeyPattern, fromShard, epoch, writeConcern); } catch (std::exception& e) { { - std::lock_guard<std::mutex> sl(_mutex); + stdx::lock_guard<stdx::mutex> sl(_mutex); _state = FAIL; _errmsg = e.what(); } @@ -1869,7 +1869,7 @@ public: error() << "migrate failed: " << e.what() << migrateLog; } catch (...) { { - std::lock_guard<std::mutex> sl(_mutex); + stdx::lock_guard<stdx::mutex> sl(_mutex); _state = FAIL; _errmsg = "UNKNOWN ERROR"; } @@ -2146,7 +2146,7 @@ public: thisTime++; { - std::lock_guard<std::mutex> statsLock(_mutex); + stdx::lock_guard<stdx::mutex> statsLock(_mutex); _numCloned++; _clonedBytes += docToClone.objsize(); } @@ -2320,7 +2320,7 @@ public: } void status(BSONObjBuilder& b) { - std::lock_guard<std::mutex> sl(_mutex); + stdx::lock_guard<stdx::mutex> sl(_mutex); b.appendBool("active", _active); @@ -2536,7 +2536,7 @@ public: } bool startCommit() { - std::unique_lock<std::mutex> lock(_mutex); + stdx::unique_lock<stdx::mutex> lock(_mutex); if (_state != STEADY) { return false; @@ -2545,7 +2545,7 @@ public: const auto deadline = system_clock::now() + seconds(30); _state = COMMIT_START; while (_active) { - if (std::cv_status::timeout == isActiveCV.wait_until(lock, deadline)) { + if (stdx::cv_status::timeout == isActiveCV.wait_until(lock, deadline)) { _state = FAIL; log() << "startCommit never finished!" << migrateLog; return false; @@ -2561,25 +2561,25 @@ public: } void abort() { - std::lock_guard<std::mutex> sl(_mutex); + stdx::lock_guard<stdx::mutex> sl(_mutex); _state = ABORT; _errmsg = "aborted"; } bool getActive() const { - std::lock_guard<std::mutex> lk(_mutex); + stdx::lock_guard<stdx::mutex> lk(_mutex); return _active; } void setActive(bool b) { - std::lock_guard<std::mutex> lk(_mutex); + stdx::lock_guard<stdx::mutex> lk(_mutex); _active = b; isActiveCV.notify_all(); } // Guards all fields. - mutable std::mutex _mutex; + mutable stdx::mutex _mutex; bool _active; - std::condition_variable isActiveCV; + stdx::condition_variable isActiveCV; std::string _ns; std::string _from; @@ -2778,14 +2778,14 @@ public: return appendCommandStatus(result, prepareStatus); } - std::thread m(migrateThread, - ns, - min, - max, - shardKeyPattern, - fromShard, - currentVersion.epoch(), - writeConcern); + stdx::thread m(migrateThread, + ns, + min, + max, + shardKeyPattern, + fromShard, + currentVersion.epoch(), + writeConcern); m.detach(); result.appendBool("started", true); diff --git a/src/mongo/s/mongos_options_init.cpp b/src/mongo/s/mongos_options_init.cpp index 335ddef25d8..85528114de4 100644 --- a/src/mongo/s/mongos_options_init.cpp +++ b/src/mongo/s/mongos_options_init.cpp @@ -28,6 +28,8 @@ #include "mongo/s/mongos_options.h" +#include <iostream> + #include "mongo/util/options_parser/startup_option_init.h" #include "mongo/util/options_parser/startup_options.h" #include "mongo/util/quick_exit.h" diff --git a/src/mongo/shell/bench.cpp b/src/mongo/shell/bench.cpp index bd446e49018..5a02ef00317 100644 --- a/src/mongo/shell/bench.cpp +++ b/src/mongo/shell/bench.cpp @@ -345,7 +345,7 @@ BenchRunWorker::BenchRunWorker(size_t id, BenchRunWorker::~BenchRunWorker() {} void BenchRunWorker::start() { - stdx::thread(stdx::bind(&BenchRunWorker::run, this)); + stdx::thread(stdx::bind(&BenchRunWorker::run, this)).detach(); } bool BenchRunWorker::shouldStop() const { diff --git a/src/mongo/shell/shell_utils_launcher.cpp b/src/mongo/shell/shell_utils_launcher.cpp index 56356ba4c6c..e4eb10124af 100644 --- a/src/mongo/shell/shell_utils_launcher.cpp +++ b/src/mongo/shell/shell_utils_launcher.cpp @@ -558,6 +558,7 @@ BSONObj StartMongoProgram(const BSONObj& a, void* data) { ProgramRunner r(a); r.start(); stdx::thread t(r); + t.detach(); return BSON(string("") << r.pid().asLongLong()); } @@ -565,6 +566,7 @@ BSONObj RunMongoProgram(const BSONObj& a, void* data) { ProgramRunner r(a); r.start(); stdx::thread t(r); + t.detach(); int exit_code = -123456; // sentinel value wait_for_pid(r.pid(), true, &exit_code); if (r.port() > 0) { @@ -579,6 +581,7 @@ BSONObj RunProgram(const BSONObj& a, void* data) { ProgramRunner r(a); r.start(); stdx::thread t(r); + t.detach(); int exit_code = -123456; // sentinel value wait_for_pid(r.pid(), true, &exit_code); registry.deletePid(r.pid()); diff --git a/src/mongo/shell/shell_utils_launcher.h b/src/mongo/shell/shell_utils_launcher.h index 49ec94f91d9..9fdb07cf3f7 100644 --- a/src/mongo/shell/shell_utils_launcher.h +++ b/src/mongo/shell/shell_utils_launcher.h @@ -38,6 +38,7 @@ #include "mongo/bson/bsonobj.h" #include "mongo/platform/process_id.h" +#include "mongo/stdx/mutex.h" namespace mongo { @@ -95,7 +96,7 @@ public: private: std::map<int, std::pair<ProcessId, int>> _ports; std::map<ProcessId, int> _pids; - mutable boost::recursive_mutex _mutex; + mutable stdx::recursive_mutex _mutex; #ifdef _WIN32 public: diff --git a/src/mongo/stdx/future.h b/src/mongo/stdx/future.h new file mode 100644 index 00000000000..bbc46efac14 --- /dev/null +++ b/src/mongo/stdx/future.h @@ -0,0 +1,44 @@ +/** + * Copyright (C) 2015 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * 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 + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * 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 GNU Affero General 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 <boost/thread/future.hpp> + +namespace mongo { +namespace stdx { + +using boost::async; +using boost::future; +using boost::future_status; +using boost::launch; +using boost::packaged_task; +using boost::promise; + +} // namespace stdx +} // namespace mongo diff --git a/src/mongo/stdx/mutex.h b/src/mongo/stdx/mutex.h index bdb5f2f6486..9dc0f0c07b1 100644 --- a/src/mongo/stdx/mutex.h +++ b/src/mongo/stdx/mutex.h @@ -28,7 +28,7 @@ #pragma once -#include <boost/thread/lock_guard.hpp> +#include <boost/thread/locks.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/recursive_mutex.hpp> diff --git a/src/mongo/tools/bridge.cpp b/src/mongo/tools/bridge.cpp index b22153a3db9..e24df98dc67 100644 --- a/src/mongo/tools/bridge.cpp +++ b/src/mongo/tools/bridge.cpp @@ -142,6 +142,7 @@ public: ports.insert(mp); Forwarder f(*mp); stdx::thread t(f); + t.detach(); } }; diff --git a/src/mongo/util/background.cpp b/src/mongo/util/background.cpp index a98d92a0a41..f316f31e683 100644 --- a/src/mongo/util/background.cpp +++ b/src/mongo/util/background.cpp @@ -33,13 +33,11 @@ #include "mongo/util/background.h" -#include <chrono> -#include <condition_variable> -#include <functional> -#include <mutex> -#include <thread> - #include "mongo/config.h" +#include "mongo/stdx/condition_variable.h" +#include "mongo/stdx/functional.h" +#include "mongo/stdx/mutex.h" +#include "mongo/stdx/thread.h" #include "mongo/util/concurrency/mutex.h" #include "mongo/util/concurrency/spin_lock.h" #include "mongo/util/concurrency/thread_name.h" @@ -82,11 +80,11 @@ private: void _runTask(PeriodicTask* task); // _mutex protects the _shutdownRequested flag and the _tasks vector. - std::mutex _mutex; + stdx::mutex _mutex; // The condition variable is used to sleep for the interval between task // executions, and is notified when the _shutdownRequested flag is toggled. - std::condition_variable _cond; + stdx::condition_variable _cond; // Used to break the loop. You should notify _cond after changing this to true // so that shutdown proceeds promptly. @@ -133,8 +131,8 @@ bool runnerDestroyed; struct BackgroundJob::JobStatus { JobStatus() : state(NotStarted) {} - std::mutex mutex; - std::condition_variable done; + stdx::mutex mutex; + stdx::condition_variable done; State state; }; @@ -172,7 +170,7 @@ void BackgroundJob::jobBody() { { // It is illegal to access any state owned by this BackgroundJob after leaving this // scope, with the exception of the call to 'delete this' below. - std::unique_lock<std::mutex> l(_status->mutex); + stdx::unique_lock<stdx::mutex> l(_status->mutex); _status->state = Done; _status->done.notify_all(); } @@ -182,7 +180,7 @@ void BackgroundJob::jobBody() { } void BackgroundJob::go() { - std::unique_lock<std::mutex> l(_status->mutex); + stdx::unique_lock<stdx::mutex> l(_status->mutex); massert(17234, mongoutils::str::stream() << "backgroundJob already running: " << name(), _status->state != Running); @@ -190,14 +188,14 @@ void BackgroundJob::go() { // If the job is already 'done', for instance because it was cancelled or already // finished, ignore additional requests to run the job. if (_status->state == NotStarted) { - std::thread t(std::bind(&BackgroundJob::jobBody, this)); + stdx::thread t(stdx::bind(&BackgroundJob::jobBody, this)); t.detach(); _status->state = Running; } } Status BackgroundJob::cancel() { - std::unique_lock<std::mutex> l(_status->mutex); + stdx::unique_lock<stdx::mutex> l(_status->mutex); if (_status->state == Running) return Status(ErrorCodes::IllegalOperation, "Cannot cancel a running BackgroundJob"); @@ -212,11 +210,11 @@ Status BackgroundJob::cancel() { bool BackgroundJob::wait(unsigned msTimeOut) { verify(!_selfDelete); // you cannot call wait on a self-deleting job - const auto deadline = std::chrono::system_clock::now() + std::chrono::milliseconds(msTimeOut); - std::unique_lock<std::mutex> l(_status->mutex); + const auto deadline = stdx::chrono::system_clock::now() + stdx::chrono::milliseconds(msTimeOut); + stdx::unique_lock<stdx::mutex> l(_status->mutex); while (_status->state != Done) { if (msTimeOut) { - if (std::cv_status::timeout == _status->done.wait_until(l, deadline)) + if (stdx::cv_status::timeout == _status->done.wait_until(l, deadline)) return false; } else { _status->done.wait(l); @@ -226,12 +224,12 @@ bool BackgroundJob::wait(unsigned msTimeOut) { } BackgroundJob::State BackgroundJob::getState() const { - std::unique_lock<std::mutex> l(_status->mutex); + stdx::unique_lock<stdx::mutex> l(_status->mutex); return _status->state; } bool BackgroundJob::running() const { - std::unique_lock<std::mutex> l(_status->mutex); + stdx::unique_lock<stdx::mutex> l(_status->mutex); return _status->state == Running; } @@ -286,12 +284,12 @@ Status PeriodicTask::stopRunningPeriodicTasks(int gracePeriodMillis) { } void PeriodicTaskRunner::add(PeriodicTask* task) { - std::lock_guard<std::mutex> lock(_mutex); + stdx::lock_guard<stdx::mutex> lock(_mutex); _tasks.push_back(task); } void PeriodicTaskRunner::remove(PeriodicTask* task) { - std::lock_guard<std::mutex> lock(_mutex); + stdx::lock_guard<stdx::mutex> lock(_mutex); for (size_t i = 0; i != _tasks.size(); i++) { if (_tasks[i] == task) { _tasks[i] = NULL; @@ -302,7 +300,7 @@ void PeriodicTaskRunner::remove(PeriodicTask* task) { Status PeriodicTaskRunner::stop(int gracePeriodMillis) { { - std::lock_guard<std::mutex> lock(_mutex); + stdx::lock_guard<stdx::mutex> lock(_mutex); _shutdownRequested = true; _cond.notify_one(); } @@ -316,11 +314,11 @@ Status PeriodicTaskRunner::stop(int gracePeriodMillis) { void PeriodicTaskRunner::run() { // Use a shorter cycle time in debug mode to help catch race conditions. - const std::chrono::seconds waitTime(kDebugBuild ? 5 : 60); + const stdx::chrono::seconds waitTime(kDebugBuild ? 5 : 60); - std::unique_lock<std::mutex> lock(_mutex); + stdx::unique_lock<stdx::mutex> lock(_mutex); while (!_shutdownRequested) { - if (std::cv_status::timeout == _cond.wait_for(lock, waitTime)) + if (stdx::cv_status::timeout == _cond.wait_for(lock, waitTime)) _runTasks(); } } diff --git a/src/mongo/util/concurrency/rwlockimpl.h b/src/mongo/util/concurrency/rwlockimpl.h index 898197a9777..d0d4c8fad99 100644 --- a/src/mongo/util/concurrency/rwlockimpl.h +++ b/src/mongo/util/concurrency/rwlockimpl.h @@ -30,7 +30,8 @@ #pragma once -#include "mutex.h" +#include "mongo/stdx/chrono.h" +#include "mongo/util/concurrency/mutex.h" #if defined(NTDDI_VERSION) && defined(NTDDI_WIN7) && (NTDDI_VERSION >= NTDDI_WIN7) @@ -115,20 +116,25 @@ public: #if defined(_WIN32) #include "shared_mutex_win.hpp" namespace mongo { -typedef boost::modified_shared_mutex shared_mutex; -} +namespace detail { +using rwlock_underlying_shared_mutex = boost::modified_shared_mutex; +} // namespace detail +} // namespace mongo #else +#include <boost/chrono.hpp> #include <boost/thread/shared_mutex.hpp> namespace mongo { -using boost::shared_mutex; -} +namespace detail { +using rwlock_underlying_shared_mutex = boost::shared_mutex; +} // namespace detail +} // namespace mongo #endif namespace mongo { class RWLockBase { MONGO_DISALLOW_COPYING(RWLockBase); friend class SimpleRWLock; - shared_mutex _m; + detail::rwlock_underlying_shared_mutex _m; protected: RWLockBase() = default; @@ -155,10 +161,18 @@ protected: _m.unlock_shared(); } bool lock_shared_try(int millis) { +#if defined(_WIN32) return _m.timed_lock_shared(boost::posix_time::milliseconds(millis)); +#else + return _m.try_lock_shared_for(boost::chrono::milliseconds(millis)); +#endif } bool lock_try(int millis = 0) { +#if defined(_WIN32) return _m.timed_lock(boost::posix_time::milliseconds(millis)); +#else + return _m.try_lock_for(boost::chrono::milliseconds(millis)); +#endif } public: diff --git a/src/mongo/util/concurrency/ticketholder.cpp b/src/mongo/util/concurrency/ticketholder.cpp index 17efed9300d..34535fa98b6 100644 --- a/src/mongo/util/concurrency/ticketholder.cpp +++ b/src/mongo/util/concurrency/ticketholder.cpp @@ -30,6 +30,9 @@ #include "mongo/platform/basic.h" #include "mongo/util/concurrency/ticketholder.h" + +#include <iostream> + #include "mongo/util/log.h" #include "mongo/util/mongoutils/str.h" diff --git a/src/mongo/util/net/message_server_port.cpp b/src/mongo/util/net/message_server_port.cpp index 0a56c9203c1..ac9a8aac083 100644 --- a/src/mongo/util/net/message_server_port.cpp +++ b/src/mongo/util/net/message_server_port.cpp @@ -32,6 +32,7 @@ #include "mongo/platform/basic.h" #include <memory> +#include <system_error> #include "mongo/base/disallow_copying.h" #include "mongo/config.h" @@ -116,7 +117,10 @@ public: try { #ifndef __linux__ // TODO: consider making this ifdef _WIN32 - { stdx::thread thr(stdx::bind(&handleIncomingMsg, portWithHandler.get())); } + { + stdx::thread thr(stdx::bind(&handleIncomingMsg, portWithHandler.get())); + thr.detach(); + } #else pthread_attr_t attrs; pthread_attr_init(&attrs); @@ -147,18 +151,16 @@ public: if (failed) { log() << "pthread_create failed: " << errnoWithDescription(failed) << endl; - throw boost::thread_resource_error(); // for consistency with boost::thread + throw std::system_error( + std::make_error_code(std::errc::resource_unavailable_try_again)); } #endif // __linux__ portWithHandler.release(); sleepAfterClosingPort.Dismiss(); - } catch (boost::thread_resource_error&) { - Listener::globalTicketHolder.release(); - log() << "can't create new thread, closing connection" << endl; } catch (...) { Listener::globalTicketHolder.release(); - log() << "unknown error accepting new socket" << endl; + log() << "failed to create thread after accepting new connection, closing connection"; } } diff --git a/src/mongo/util/net/sock_test.cpp b/src/mongo/util/net/sock_test.cpp index 26f0c2c821a..e294bb1b738 100644 --- a/src/mongo/util/net/sock_test.cpp +++ b/src/mongo/util/net/sock_test.cpp @@ -154,6 +154,7 @@ SocketPair socketPair(const int type, const int protocol) { stdx::bind(&detail::awaitConnect, &connectSock, *connectRes, boost::ref(connected))); connected.waitToBeNotified(); + connector.join(); if (connectSock == INVALID_SOCKET) { closesocket(listenSock); ::freeaddrinfo(res); @@ -164,6 +165,7 @@ SocketPair socketPair(const int type, const int protocol) { } accepted.waitToBeNotified(); + acceptor.join(); if (acceptSock == INVALID_SOCKET) { closesocket(listenSock); ::freeaddrinfo(res); diff --git a/src/mongo/util/ntservice.cpp b/src/mongo/util/ntservice.cpp index e4c0eb70348..b70835d1ab6 100644 --- a/src/mongo/util/ntservice.cpp +++ b/src/mongo/util/ntservice.cpp @@ -39,6 +39,9 @@ #include "mongo/db/client.h" #include "mongo/db/instance.h" +#include "mongo/stdx/chrono.h" +#include "mongo/stdx/future.h" +#include "mongo/stdx/thread.h" #include "mongo/util/assert_util.h" #include "mongo/util/exit.h" #include "mongo/util/log.h" @@ -502,15 +505,6 @@ bool reportStatus(DWORD reportState, DWORD waitHint, DWORD exitCode) { return SetServiceStatus(_statusHandle, &ssStatus); } -static void serviceStopWorker() { - Client::initThread("serviceStopWorker"); - - // Stop the process - // TODO: SERVER-5703, separate the "cleanup for shutdown" functionality from - // the "terminate process" functionality in exitCleanly. - exitCleanly(EXIT_WINDOWS_SERVICE_STOP); -} - // Minimum of time we tell Windows to wait before we are guilty of a hung shutdown const int kStopWaitHintMillis = 30000; @@ -519,12 +513,23 @@ const int kStopWaitHintMillis = 30000; // On client OSes, SERVICE_CONTROL_SHUTDOWN has a 5 second timeout configured in // HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control static void serviceStop() { - stdx::thread serviceWorkerThread(serviceStopWorker); + stdx::packaged_task<void()> exitCleanlyTask([] { + Client::initThread("serviceStopWorker"); + // Stop the process + // TODO: SERVER-5703, separate the "cleanup for shutdown" functionality from + // the "terminate process" functionality in exitCleanly. + exitCleanly(EXIT_WINDOWS_SERVICE_STOP); + }); + stdx::future<void> exitedCleanly = exitCleanlyTask.get_future(); + + // Launch the packaged task in a thread. We needn't ever join it, + // so it doesn't even need a name. + stdx::thread(std::move(exitCleanlyTask)).detach(); + + const auto timeout = stdx::chrono::milliseconds(kStopWaitHintMillis / 2); // We periodically check if we are done exiting by polling at half of each wait interval - // - while ( - !serviceWorkerThread.try_join_for(boost::chrono::milliseconds(kStopWaitHintMillis / 2))) { + while (exitedCleanly.wait_for(timeout) != stdx::future_status::ready) { reportStatus(SERVICE_STOP_PENDING, kStopWaitHintMillis); log() << "Service Stop is waiting for storage engine to finish shutdown"; } diff --git a/src/mongo/util/queue.h b/src/mongo/util/queue.h index b2475fbebfd..f204abb2484 100644 --- a/src/mongo/util/queue.h +++ b/src/mongo/util/queue.h @@ -29,12 +29,11 @@ #pragma once -#include <chrono> -#include <condition_variable> -#include <mutex> #include <limits> #include <queue> +#include "mongo/stdx/chrono.h" +#include "mongo/stdx/condition_variable.h" #include "mongo/base/disallow_copying.h" namespace mongo { @@ -66,7 +65,7 @@ public: BlockingQueue(size_t size, getSizeFunc f) : _maxSize(size), _currentSize(0), _getSize(f) {} void push(T const& t) { - std::unique_lock<std::mutex> l(_lock); + stdx::unique_lock<stdx::mutex> l(_lock); size_t tSize = _getSize(t); while (_currentSize + tSize > _maxSize) { _cvNoLongerFull.wait(l); @@ -77,7 +76,7 @@ public: } bool empty() const { - std::lock_guard<std::mutex> l(_lock); + stdx::lock_guard<stdx::mutex> l(_lock); return _queue.empty(); } @@ -85,7 +84,7 @@ public: * The size as measured by the size function. Default to counting each item */ size_t size() const { - std::lock_guard<std::mutex> l(_lock); + stdx::lock_guard<stdx::mutex> l(_lock); return _currentSize; } @@ -100,19 +99,19 @@ public: * The number/count of items in the queue ( _queue.size() ) */ size_t count() const { - std::lock_guard<std::mutex> l(_lock); + stdx::lock_guard<stdx::mutex> l(_lock); return _queue.size(); } void clear() { - std::lock_guard<std::mutex> l(_lock); + stdx::lock_guard<stdx::mutex> l(_lock); _queue = std::queue<T>(); _currentSize = 0; _cvNoLongerFull.notify_one(); } bool tryPop(T& t) { - std::lock_guard<std::mutex> l(_lock); + stdx::lock_guard<stdx::mutex> l(_lock); if (_queue.empty()) return false; @@ -125,7 +124,7 @@ public: } T blockingPop() { - std::unique_lock<std::mutex> l(_lock); + stdx::unique_lock<stdx::mutex> l(_lock); while (_queue.empty()) _cvNoLongerEmpty.wait(l); @@ -144,11 +143,11 @@ public: * otherwise return false and t won't be changed */ bool blockingPop(T& t, int maxSecondsToWait) { - using namespace std::chrono; + using namespace stdx::chrono; const auto deadline = system_clock::now() + seconds(maxSecondsToWait); - std::unique_lock<std::mutex> l(_lock); + stdx::unique_lock<stdx::mutex> l(_lock); while (_queue.empty()) { - if (std::cv_status::timeout == _cvNoLongerEmpty.wait_until(l, deadline)) + if (stdx::cv_status::timeout == _cvNoLongerEmpty.wait_until(l, deadline)) return false; } @@ -162,11 +161,11 @@ public: // Obviously, this should only be used when you have // only one consumer bool blockingPeek(T& t, int maxSecondsToWait) { - using namespace std::chrono; + using namespace stdx::chrono; const auto deadline = system_clock::now() + seconds(maxSecondsToWait); - std::unique_lock<std::mutex> l(_lock); + stdx::unique_lock<stdx::mutex> l(_lock); while (_queue.empty()) { - if (std::cv_status::timeout == _cvNoLongerEmpty.wait_until(l, deadline)) + if (stdx::cv_status::timeout == _cvNoLongerEmpty.wait_until(l, deadline)) return false; } @@ -177,7 +176,7 @@ public: // Obviously, this should only be used when you have // only one consumer bool peek(T& t) { - std::unique_lock<std::mutex> l(_lock); + stdx::unique_lock<stdx::mutex> l(_lock); if (_queue.empty()) { return false; } @@ -187,13 +186,13 @@ public: } private: - mutable std::mutex _lock; + mutable stdx::mutex _lock; std::queue<T> _queue; const size_t _maxSize; size_t _currentSize; getSizeFunc _getSize; - std::condition_variable _cvNoLongerFull; - std::condition_variable _cvNoLongerEmpty; + stdx::condition_variable _cvNoLongerFull; + stdx::condition_variable _cvNoLongerEmpty; }; } diff --git a/src/mongo/util/tick_source_mock.cpp b/src/mongo/util/tick_source_mock.cpp index 15930a1b18a..a64c4f146b3 100644 --- a/src/mongo/util/tick_source_mock.cpp +++ b/src/mongo/util/tick_source_mock.cpp @@ -28,6 +28,8 @@ #include "mongo/util/tick_source_mock.h" +#include <utility> + namespace mongo { namespace { diff --git a/src/mongo/util/time_support.h b/src/mongo/util/time_support.h index 2ec19ed12eb..8991ba85ec1 100644 --- a/src/mongo/util/time_support.h +++ b/src/mongo/util/time_support.h @@ -54,7 +54,10 @@ void time_t_to_Struct(time_t t, struct tm* buf, bool local = false); std::string time_t_to_String_short(time_t t); // -// Operators for putting durations to streams. +// Operators for putting durations to streams. Note that these will +// *not* normally be found by ADL since the duration types are +// typedefs, but see the handling of chrono::duration in +// logstream_builder.h for why they are useful. // std::ostream& operator<<(std::ostream& os, Microseconds us); diff --git a/src/mongo/util/time_support_test.cpp b/src/mongo/util/time_support_test.cpp index dfdd01863cb..64a6b3b16bf 100644 --- a/src/mongo/util/time_support_test.cpp +++ b/src/mongo/util/time_support_test.cpp @@ -824,8 +824,9 @@ TEST(SystemTime, ConvertDateToSystemTime) { const std::string isoTimeString = "2015-05-14T17:28:33.123Z"; const Date_t aDate = unittest::assertGet(dateFromISOString(isoTimeString)); const auto aTimePoint = aDate.toSystemTimePoint(); - ASSERT_EQUALS(aDate.toDurationSinceEpoch(), - aTimePoint - stdx::chrono::system_clock::from_time_t(0)); + const auto actual = aTimePoint - stdx::chrono::system_clock::from_time_t(0); + ASSERT(aDate.toDurationSinceEpoch() == actual) << "Expected " << aDate << "; but found " + << Date_t::fromDurationSinceEpoch(actual); ASSERT_EQUALS(aDate, Date_t(aTimePoint)); } |