diff options
author | Andy Schwerin <schwerin@mongodb.com> | 2015-06-11 18:32:23 -0400 |
---|---|---|
committer | Andy Schwerin <schwerin@mongodb.com> | 2015-06-16 10:36:48 -0400 |
commit | b06861044ad1610cef2f2fa8a9e24e5b72ee7345 (patch) | |
tree | a957920ed04330a170d219a9a95f069a00c5babf | |
parent | e9aee4b9bc04a4aaad478aeeee561fcba970bcb5 (diff) | |
download | mongo-b06861044ad1610cef2f2fa8a9e24e5b72ee7345.tar.gz |
SERVER-6686 Remove all uses of boost::xtime outside of time_support.cpp.
-rw-r--r-- | src/mongo/db/repl/bgsync.h | 3 | ||||
-rw-r--r-- | src/mongo/s/d_migrate.cpp | 135 | ||||
-rw-r--r-- | src/mongo/scripting/v8-3.25_utils.cpp | 1 | ||||
-rw-r--r-- | src/mongo/scripting/v8_utils.cpp | 1 | ||||
-rw-r--r-- | src/mongo/util/background.cpp | 59 | ||||
-rw-r--r-- | src/mongo/util/concurrency/mutex.h | 44 | ||||
-rw-r--r-- | src/mongo/util/queue.h | 65 | ||||
-rw-r--r-- | src/mongo/util/time_support.cpp | 7 | ||||
-rw-r--r-- | src/mongo/util/time_support.h | 14 |
9 files changed, 145 insertions, 184 deletions
diff --git a/src/mongo/db/repl/bgsync.h b/src/mongo/db/repl/bgsync.h index bc03f755f1f..ad16f4cdc99 100644 --- a/src/mongo/db/repl/bgsync.h +++ b/src/mongo/db/repl/bgsync.h @@ -28,6 +28,7 @@ #pragma once +#include <boost/thread/condition.hpp> #include <boost/thread/mutex.hpp> #include "mongo/util/queue.h" @@ -50,7 +51,7 @@ namespace repl { public: virtual ~BackgroundSyncInterface(); - // Gets the head of the buffer, but does not remove it. + // Gets the head of the buffer, but does not remove it. // Returns true if an element was present at the head; // false if the queue was empty. virtual bool peek(BSONObj* op) = 0; diff --git a/src/mongo/s/d_migrate.cpp b/src/mongo/s/d_migrate.cpp index a74198e6464..9dffd676e7f 100644 --- a/src/mongo/s/d_migrate.cpp +++ b/src/mongo/s/d_migrate.cpp @@ -33,9 +33,12 @@ #include "mongo/platform/basic.h" #include <algorithm> -#include <boost/thread/thread.hpp> +#include <chrono> +#include <condition_variable> #include <map> +#include <mutex> #include <string> +#include <thread> #include <vector> #include "mongo/client/connpool.h" @@ -86,7 +89,6 @@ #include "mongo/util/fail_point_service.h" #include "mongo/util/log.h" #include "mongo/util/processinfo.h" -#include "mongo/util/queue.h" #include "mongo/util/startup_test.h" // Pause while a fail point is enabled. @@ -94,6 +96,7 @@ namespace mongo { + using namespace std::chrono; using std::list; using std::set; using std::string; @@ -193,7 +196,7 @@ namespace { CurOp * op = CurOp::get(_txn); { - stdx::lock_guard<Client> lk(*_txn->getClient()); + std::lock_guard<Client> lk(*_txn->getClient()); op->setMessage_inlock(s.c_str()); } @@ -266,7 +269,7 @@ namespace { // Get global shared to synchronize with logOp. Also see comments in the class // members declaration for more details. Lock::GlobalRead globalShared(txn->lockState()); - boost::lock_guard<boost::mutex> lk(_mutex); + std::lock_guard<std::mutex> lk(_mutex); if (_active) { return false; @@ -283,7 +286,7 @@ namespace { _active = true; - boost::lock_guard<boost::mutex> tLock(_cloneLocsMutex); + std::lock_guard<std::mutex> tLock(_cloneLocsMutex); verify(_cloneLocs.size() == 0); return true; @@ -296,7 +299,7 @@ namespace { // Get global shared to synchronize with logOp. Also see comments in the class // members declaration for more details. Lock::GlobalRead globalShared(txn->lockState()); - boost::lock_guard<boost::mutex> lk(_mutex); + std::lock_guard<std::mutex> lk(_mutex); _active = false; _deleteNotifyExec.reset( NULL ); @@ -307,7 +310,7 @@ namespace { _reload.clear(); _memoryUsed = 0; - boost::lock_guard<boost::mutex> cloneLock(_cloneLocsMutex); + std::lock_guard<std::mutex> cloneLock(_cloneLocsMutex); _cloneLocs.clear(); } @@ -435,7 +438,7 @@ namespace { { AutoGetCollectionForRead ctx(txn, getNS()); - boost::lock_guard<boost::mutex> sl(_mutex); + std::lock_guard<std::mutex> sl(_mutex); if (!_active) { errmsg = "no active migration!"; return false; @@ -494,7 +497,7 @@ namespace { // 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. - boost::lock_guard<boost::mutex> sl(_mutex); + std::lock_guard<std::mutex> sl(_mutex); invariant( _deleteNotifyExec.get() == NULL ); WorkingSet* ws = new WorkingSet(); @@ -536,7 +539,7 @@ namespace { avgRecSize = 0; maxRecsWhenFull = Chunk::MaxObjectPerChunk + 1; } - + // do a full traversal of the chunk and don't stop even if we think it is a large chunk // we want the number of records to better report, in that case bool isLargeChunk = false; @@ -544,7 +547,7 @@ namespace { RecordId dl; while (PlanExecutor::ADVANCED == exec->getNext(NULL, &dl)) { if ( ! isLargeChunk ) { - boost::lock_guard<boost::mutex> lk(_cloneLocsMutex); + std::lock_guard<std::mutex> lk(_cloneLocsMutex); _cloneLocs.insert( dl ); } @@ -557,7 +560,7 @@ namespace { exec.reset(); if ( isLargeChunk ) { - boost::lock_guard<boost::mutex> sl(_mutex); + std::lock_guard<std::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 @@ -585,7 +588,7 @@ namespace { { AutoGetCollectionForRead ctx(txn, getNS()); - boost::lock_guard<boost::mutex> sl(_mutex); + std::lock_guard<std::mutex> sl(_mutex); if (!_active) { errmsg = "not active"; return false; @@ -608,7 +611,7 @@ namespace { while (!isBufferFilled) { AutoGetCollectionForRead ctx(txn, getNS()); - boost::lock_guard<boost::mutex> sl(_mutex); + std::lock_guard<std::mutex> sl(_mutex); if (!_active) { errmsg = "not active"; return false; @@ -623,7 +626,7 @@ namespace { return false; } - boost::lock_guard<boost::mutex> lk(_cloneLocsMutex); + std::lock_guard<std::mutex> lk(_cloneLocsMutex); set<RecordId>::iterator cloneLocsIter = _cloneLocs.begin(); for ( ; cloneLocsIter != _cloneLocs.end(); ++cloneLocsIter) { if (tracker.intervalHasElapsed()) // should I yield? @@ -666,33 +669,33 @@ namespace { // that check only works for non-mmapv1 engines, and this is needed // for mmapv1. - boost::lock_guard<boost::mutex> lk(_cloneLocsMutex); + std::lock_guard<std::mutex> lk(_cloneLocsMutex); _cloneLocs.erase( dl ); } std::size_t cloneLocsRemaining() { - boost::lock_guard<boost::mutex> lk(_cloneLocsMutex); + std::lock_guard<std::mutex> lk(_cloneLocsMutex); return _cloneLocs.size(); } long long mbUsed() const { - boost::lock_guard<boost::mutex> lk(_mutex); + std::lock_guard<std::mutex> lk(_mutex); return _memoryUsed / ( 1024 * 1024 ); } bool getInCriticalSection() const { - boost::lock_guard<boost::mutex> lk(_mutex); + std::lock_guard<std::mutex> lk(_mutex); return _inCriticalSection; } void setInCriticalSection( bool b ) { - boost::lock_guard<boost::mutex> lk(_mutex); + std::lock_guard<std::mutex> lk(_mutex); _inCriticalSection = b; _inCriticalSectionCV.notify_all(); } std::string getNS() const { - boost::lock_guard<boost::mutex> sl(_mutex); + std::lock_guard<std::mutex> sl(_mutex); return _ns; } @@ -700,13 +703,10 @@ namespace { * @return true if we are NOT in the critical section */ bool waitTillNotInCriticalSection( int maxSecondsToWait ) { - boost::xtime xt; - boost::xtime_get(&xt, MONGO_BOOST_TIME_UTC); - xt.sec += maxSecondsToWait; - - boost::unique_lock<boost::mutex> lk(_mutex); + const auto deadline = system_clock::now() + seconds(maxSecondsToWait); + std::unique_lock<std::mutex> lk(_mutex); while (_inCriticalSection) { - if (!_inCriticalSectionCV.timed_wait(lk, xt)) + if (std::cv_status::timeout == _inCriticalSectionCV.wait_until(lk, deadline)) return false; } @@ -716,8 +716,8 @@ namespace { bool isActive() const { return _getActive(); } private: - bool _getActive() const { boost::lock_guard<boost::mutex> lk(_mutex); return _active; } - void _setActive( bool b ) { boost::lock_guard<boost::mutex> lk(_mutex); _active = b; } + bool _getActive() const { std::lock_guard<std::mutex> lk(_mutex); return _active; } + void _setActive( bool b ) { std::lock_guard<std::mutex> lk(_mutex); _active = b; } /** * Used to commit work for LogOpForSharding. Used to keep track of changes in documents @@ -740,7 +740,7 @@ namespace { virtual void commit() { switch (_op) { case 'd': { - boost::lock_guard<boost::mutex> sl(_migrateFromStatus->_mutex); + std::lock_guard<std::mutex> sl(_migrateFromStatus->_mutex); _migrateFromStatus->_deleted.push_back(_idObj); _migrateFromStatus->_memoryUsed += _idObj.firstElement().size() + 5; break; @@ -749,7 +749,7 @@ namespace { case 'i': case 'u': { - boost::lock_guard<boost::mutex> sl(_migrateFromStatus->_mutex); + std::lock_guard<std::mutex> sl(_migrateFromStatus->_mutex); _migrateFromStatus->_reload.push_back(_idObj); _migrateFromStatus->_memoryUsed += _idObj.firstElement().size() + 5; break; @@ -829,9 +829,9 @@ namespace { // // Global Lock -> _mutex -> _cloneLocsMutex - mutable mongo::mutex _mutex; + mutable std::mutex _mutex; - boost::condition _inCriticalSectionCV; // (M) + std::condition_variable _inCriticalSectionCV; // (M) // Is migration currently in critical section. This can be used to block new writes. bool _inCriticalSection; // (M) @@ -855,7 +855,7 @@ namespace { BSONObj _max; // (MG) BSONObj _shardKeyPattern; // (MG) - mutable mongo::mutex _cloneLocsMutex; + mutable std::mutex _cloneLocsMutex; // List of record id that needs to be transferred from here to the other side. set<RecordId> _cloneLocs; // (C) @@ -1155,7 +1155,7 @@ namespace { MONGO_FP_PAUSE_WHILE(moveChunkHangAtStep1); // 2. - + if ( migrateFromStatus.isActive() ) { errmsg = "migration already in progress"; warning() << errmsg; @@ -1261,7 +1261,7 @@ namespace { // 3. MigrateStatusHolder statusHolder(txn, ns, min, max, shardKeyPattern); - + if (statusHolder.isAnotherMigrationActive()) { errmsg = "moveChunk is already in progress from this shard"; warning() << errmsg; @@ -1279,7 +1279,7 @@ namespace { str::stream() << "Source shard " << fromShardName << " is missing. This indicates metadata corruption.", fromShard); - + fromShardCS = fromShard->getConnString(); std::shared_ptr<Shard> toShard = grid.shardRegistry()->findIfExists(toShardName); @@ -1630,7 +1630,7 @@ namespace { Status applyOpsStatus{Status::OK()}; try { - + // For testing migration failures if ( MONGO_FAIL_POINT(failMigrationConfigWritePrepare) ) { throw DBException( "mock migration failure before config write", @@ -1838,12 +1838,12 @@ namespace { } void setState(State newState) { - boost::lock_guard<boost::mutex> sl(_mutex); + std::lock_guard<std::mutex> sl(_mutex); _state = newState; } State getState() const { - boost::lock_guard<boost::mutex> sl(_mutex); + std::lock_guard<std::mutex> sl(_mutex); return _state; } @@ -1855,7 +1855,7 @@ namespace { const BSONObj& min, const BSONObj& max, const BSONObj& shardKeyPattern) { - boost::lock_guard<boost::mutex> lk(_mutex); + std::lock_guard<std::mutex> lk(_mutex); if (_active) { return Status(ErrorCodes::ConflictingOperationInProgress, @@ -1898,7 +1898,7 @@ namespace { } catch ( std::exception& e ) { { - boost::lock_guard<boost::mutex> sl(_mutex); + std::lock_guard<std::mutex> sl(_mutex); _state = FAIL; _errmsg = e.what(); } @@ -1907,7 +1907,7 @@ namespace { } catch ( ... ) { { - boost::lock_guard<boost::mutex> sl(_mutex); + std::lock_guard<std::mutex> sl(_mutex); _state = FAIL; _errmsg = "UNKNOWN ERROR"; } @@ -1994,9 +1994,9 @@ namespace { } } - { + { // 1. copy indexes - + vector<BSONObj> indexSpecs; { const std::list<BSONObj> indexes = conn->getIndexSpecs(ns); @@ -2192,7 +2192,7 @@ namespace { thisTime++; { - boost::lock_guard<boost::mutex> statsLock(_mutex); + std::lock_guard<std::mutex> statsLock(_mutex); _numCloned++; _clonedBytes += docToClone.objsize(); } @@ -2244,7 +2244,7 @@ namespace { break; apply(txn, ns, min, max, shardKeyPattern, res, &lastOpApplied); - + const int maxIterations = 3600*50; int i; for ( i=0;i<maxIterations; i++) { @@ -2257,10 +2257,10 @@ namespace { return; } - + if (opReplicatedEnough(txn, lastOpApplied, writeConcern)) break; - + if ( i > 100 ) { warning() << "secondaries having hard time keeping up with migrate" << migrateLog; } @@ -2274,14 +2274,14 @@ namespace { conn.done(); setState(FAIL); return; - } + } } timing.done(4); MONGO_FP_PAUSE_WHILE(migrateThreadHangAtStep4); } - { + { // pause to wait for replication // this will prevent us from going into critical section until we're ready Timer t; @@ -2340,7 +2340,7 @@ namespace { if ( getState() == ABORT ) { return; } - + // We know we're finished when: // 1) The from side has told us that it has locked writes (COMMIT_START) // 2) We've checked at least one more time for un-transmitted mods @@ -2348,7 +2348,7 @@ namespace { if (flushPendingWrites(txn, ns, min, max, lastOpApplied, writeConcern)) break; } - + // Only sleep if we aren't committing if ( getState() == STEADY ) sleepmillis( 10 ); } @@ -2367,7 +2367,7 @@ namespace { } void status(BSONObjBuilder& b) { - boost::lock_guard<boost::mutex> sl(_mutex); + std::lock_guard<std::mutex> sl(_mutex); b.appendBool("active", _active); @@ -2582,20 +2582,16 @@ namespace { } bool startCommit() { - boost::unique_lock<boost::mutex> lock(_mutex); + std::unique_lock<std::mutex> lock(_mutex); if (_state != STEADY) { return false; } - boost::xtime xt; - boost::xtime_get(&xt, MONGO_BOOST_TIME_UTC); - xt.sec += 30; - + const auto deadline = system_clock::now() + seconds(30); _state = COMMIT_START; while (_active) { - if ( ! isActiveCV.timed_wait( lock, xt ) ){ - // TIMEOUT + if (std::cv_status::timeout == isActiveCV.wait_until(lock, deadline)) { _state = FAIL; log() << "startCommit never finished!" << migrateLog; return false; @@ -2611,22 +2607,22 @@ namespace { } void abort() { - boost::lock_guard<boost::mutex> sl(_mutex); + std::lock_guard<std::mutex> sl(_mutex); _state = ABORT; _errmsg = "aborted"; } - bool getActive() const { boost::lock_guard<boost::mutex> lk(_mutex); return _active; } - void setActive( bool b ) { - boost::lock_guard<boost::mutex> lk(_mutex); + bool getActive() const { std::lock_guard<std::mutex> lk(_mutex); return _active; } + void setActive( bool b ) { + std::lock_guard<std::mutex> lk(_mutex); _active = b; - isActiveCV.notify_all(); + isActiveCV.notify_all(); } // Guards all fields. - mutable mongo::mutex _mutex; + mutable std::mutex _mutex; bool _active; - boost::condition isActiveCV; + std::condition_variable isActiveCV; std::string _ns; std::string _from; @@ -2827,7 +2823,7 @@ namespace { return appendCommandStatus(result, prepareStatus); } - boost::thread m(migrateThread, + std::thread m(migrateThread, ns, min, max, @@ -2836,6 +2832,7 @@ namespace { currentVersion.epoch(), writeConcern); + m.detach(); result.appendBool( "started" , true ); return true; } diff --git a/src/mongo/scripting/v8-3.25_utils.cpp b/src/mongo/scripting/v8-3.25_utils.cpp index ef90819cdbb..a33f4ff723f 100644 --- a/src/mongo/scripting/v8-3.25_utils.cpp +++ b/src/mongo/scripting/v8-3.25_utils.cpp @@ -34,7 +34,6 @@ #include <boost/thread/condition_variable.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/thread.hpp> -#include <boost/thread/xtime.hpp> #include <iostream> #include <map> #include <sstream> diff --git a/src/mongo/scripting/v8_utils.cpp b/src/mongo/scripting/v8_utils.cpp index f9e53904ebe..13909d87fd9 100644 --- a/src/mongo/scripting/v8_utils.cpp +++ b/src/mongo/scripting/v8_utils.cpp @@ -34,7 +34,6 @@ #include <boost/thread/condition_variable.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/thread.hpp> -#include <boost/thread/xtime.hpp> #include <iostream> #include <map> #include <sstream> diff --git a/src/mongo/util/background.cpp b/src/mongo/util/background.cpp index cad78c9ddc7..6dfa29f5d40 100644 --- a/src/mongo/util/background.cpp +++ b/src/mongo/util/background.cpp @@ -33,13 +33,13 @@ #include "mongo/util/background.h" -#include <boost/thread/condition.hpp> -#include <boost/thread/mutex.hpp> -#include <boost/thread/once.hpp> -#include <boost/thread/thread.hpp> +#include <chrono> +#include <condition_variable> +#include <functional> +#include <mutex> +#include <thread> #include "mongo/config.h" -#include "mongo/stdx/functional.h" #include "mongo/util/concurrency/mutex.h" #include "mongo/util/concurrency/spin_lock.h" #include "mongo/util/concurrency/thread_name.h" @@ -47,7 +47,6 @@ #include "mongo/util/log.h" #include "mongo/util/mongoutils/str.h" #include "mongo/util/net/ssl_manager.h" -#include "mongo/util/time_support.h" #include "mongo/util/timer.h" using namespace std; @@ -85,11 +84,11 @@ namespace mongo { void _runTask( PeriodicTask* task ); // _mutex protects the _shutdownRequested flag and the _tasks vector. - boost::mutex _mutex; + std::mutex _mutex; // The condition variable is used to sleep for the interval between task // executions, and is notified when the _shutdownRequested flag is toggled. - boost::condition _cond; + std::condition_variable _cond; // Used to break the loop. You should notify _cond after changing this to true // so that shutdown proceeds promptly. @@ -135,8 +134,8 @@ namespace mongo { struct BackgroundJob::JobStatus { JobStatus() : state(NotStarted) {} - boost::mutex mutex; - boost::condition done; + std::mutex mutex; + std::condition_variable done; State state; }; @@ -179,7 +178,7 @@ namespace mongo { { // 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. - boost::unique_lock<boost::mutex> l( _status->mutex ); + std::unique_lock<std::mutex> l( _status->mutex ); _status->state = Done; _status->done.notify_all(); } @@ -189,7 +188,7 @@ namespace mongo { } void BackgroundJob::go() { - boost::unique_lock<boost::mutex> l( _status->mutex ); + std::unique_lock<std::mutex> l( _status->mutex ); massert( 17234, mongoutils::str::stream() << "backgroundJob already running: " << name(), _status->state != Running ); @@ -197,13 +196,14 @@ namespace mongo { // 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) { - boost::thread t( stdx::bind( &BackgroundJob::jobBody , this ) ); + std::thread t( std::bind( &BackgroundJob::jobBody , this ) ); + t.detach(); _status->state = Running; } } Status BackgroundJob::cancel() { - boost::unique_lock<boost::mutex> l( _status->mutex ); + std::unique_lock<std::mutex> l( _status->mutex ); if ( _status->state == Running ) return Status( ErrorCodes::IllegalOperation, @@ -219,27 +219,28 @@ namespace mongo { bool BackgroundJob::wait( unsigned msTimeOut ) { verify( !_selfDelete ); // you cannot call wait on a self-deleting job - boost::unique_lock<boost::mutex> l( _status->mutex ); + const auto deadline = + std::chrono::system_clock::now() + std::chrono::milliseconds(msTimeOut); + std::unique_lock<std::mutex> l( _status->mutex ); while ( _status->state != Done ) { if ( msTimeOut ) { - boost::xtime deadline = incxtimemillis( msTimeOut ); - if ( !_status->done.timed_wait( l , deadline ) ) + if (std::cv_status::timeout == _status->done.wait_until(l, deadline)) return false; } else { - _status->done.wait( l ); + _status->done.wait(l); } } return true; } BackgroundJob::State BackgroundJob::getState() const { - boost::unique_lock<boost::mutex> l( _status->mutex ); + std::unique_lock<std::mutex> l( _status->mutex ); return _status->state; } bool BackgroundJob::running() const { - boost::unique_lock<boost::mutex> l( _status->mutex ); + std::unique_lock<std::mutex> l( _status->mutex ); return _status->state == Running; } @@ -294,12 +295,12 @@ namespace mongo { } void PeriodicTaskRunner::add( PeriodicTask* task ) { - boost::lock_guard<boost::mutex> lock( _mutex ); + std::lock_guard<std::mutex> lock( _mutex ); _tasks.push_back( task ); } void PeriodicTaskRunner::remove( PeriodicTask* task ) { - boost::lock_guard<boost::mutex> lock( _mutex ); + std::lock_guard<std::mutex> lock( _mutex ); for ( size_t i = 0; i != _tasks.size(); i++ ) { if ( _tasks[i] == task ) { _tasks[i] = NULL; @@ -310,7 +311,7 @@ namespace mongo { Status PeriodicTaskRunner::stop( int gracePeriodMillis ) { { - boost::lock_guard<boost::mutex> lock( _mutex ); + std::lock_guard<std::mutex> lock( _mutex ); _shutdownRequested = true; _cond.notify_one(); } @@ -324,15 +325,11 @@ namespace mongo { void PeriodicTaskRunner::run() { // Use a shorter cycle time in debug mode to help catch race conditions. - const size_t waitMillis = (kDebugBuild ? 5 : 60) * 1000; + const std::chrono::seconds waitTime(kDebugBuild ? 5 : 60); - const stdx::function<bool()> predicate = - stdx::bind( &PeriodicTaskRunner::_isShutdownRequested, this ); - - boost::unique_lock<boost::mutex> lock( _mutex ); - while ( !predicate() ) { - const boost::xtime deadline = incxtimemillis( waitMillis ); - if ( !_cond.timed_wait( lock, deadline, predicate ) ) + std::unique_lock<std::mutex> lock(_mutex); + while (!_shutdownRequested) { + if (std::cv_status::timeout == _cond.wait_for(lock, waitTime)) _runTasks(); } } diff --git a/src/mongo/util/concurrency/mutex.h b/src/mongo/util/concurrency/mutex.h index e342105e8b5..b9f9a361290 100644 --- a/src/mongo/util/concurrency/mutex.h +++ b/src/mongo/util/concurrency/mutex.h @@ -35,36 +35,12 @@ #include <boost/noncopyable.hpp> #include <boost/thread/mutex.hpp> -#include <boost/thread/xtime.hpp> -#include "mongo/bson/inline_decls.h" #include "mongo/util/assert_util.h" #include "mongo/util/concurrency/threadlocal.h" -#include "mongo/util/time_support.h" - -// Macro to get line as a std::string constant -#define MONGO_STRINGIFY(X) #X -// Double-expansion trick to get preproc to actually substitute __LINE__ -#define _MONGO_LINE_STRING(LINE) MONGO_STRINGIFY( LINE ) -#define MONGO_LINE_STRING _MONGO_LINE_STRING( __LINE__ ) - -// Mutex names should be as <file>::<line> string -#define MONGO_FILE_LINE __FILE__ "::" MONGO_LINE_STRING namespace mongo { - inline boost::xtime incxtimemillis( long long s ) { - boost::xtime xt; - boost::xtime_get(&xt, MONGO_BOOST_TIME_UTC); - xt.sec += (int)( s / 1000 ); - xt.nsec += (int)(( s % 1000 ) * 1000000); - if ( xt.nsec >= 1000000000 ) { - xt.nsec -= 1000000000; - xt.sec++; - } - return xt; - } - // If you create a local static instance of this class, that instance will be destroyed // before all global static objects are destroyed, so _destroyingStatics will be set // to true before the global static variables are destroyed. @@ -76,8 +52,8 @@ namespace mongo { using mutex = boost::mutex; - /** The concept with SimpleMutex is that it is a basic lock/unlock with no - special functionality (such as try and try timeout). Thus it can be + /** The concept with SimpleMutex is that it is a basic lock/unlock with no + special functionality (such as try and try timeout). Thus it can be implemented using OS-specific facilities in all environments (if desired). On Windows, the implementation below is faster than boost mutex. */ @@ -109,9 +85,9 @@ namespace mongo { public: void dassertLocked() const { } SimpleMutex(StringData name) { verify( pthread_mutex_init(&_lock,0) == 0 ); } - ~SimpleMutex(){ - if ( ! StaticObserver::_destroyingStatics ) { - verify( pthread_mutex_destroy(&_lock) == 0 ); + ~SimpleMutex(){ + if ( ! StaticObserver::_destroyingStatics ) { + verify( pthread_mutex_destroy(&_lock) == 0 ); } } @@ -142,14 +118,14 @@ namespace mongo { RecursiveMutex& rm; int& nLocksByMe; public: - scoped_lock( RecursiveMutex &m ) : rm(m), nLocksByMe(rm.n.getRef()) { - if( nLocksByMe++ == 0 ) - rm.m.lock(); + scoped_lock( RecursiveMutex &m ) : rm(m), nLocksByMe(rm.n.getRef()) { + if( nLocksByMe++ == 0 ) + rm.m.lock(); } - ~scoped_lock() { + ~scoped_lock() { verify( nLocksByMe > 0 ); if( --nLocksByMe == 0 ) { - rm.m.unlock(); + rm.m.unlock(); } } }; diff --git a/src/mongo/util/queue.h b/src/mongo/util/queue.h index 7ae46f97325..c6305394e0e 100644 --- a/src/mongo/util/queue.h +++ b/src/mongo/util/queue.h @@ -29,13 +29,13 @@ #pragma once -#include <boost/noncopyable.hpp> -#include <boost/thread/condition.hpp> +#include <chrono> +#include <condition_variable> +#include <mutex> #include <limits> #include <queue> -#include "mongo/util/concurrency/mutex.h" -#include "mongo/util/timer.h" +#include "mongo/base/disallow_copying.h" namespace mongo { @@ -49,10 +49,12 @@ namespace mongo { * A custom sizing function can optionally be given. By default the getSize function * returns 1 for each item, resulting in size equaling the number of items queued. * - * Note that use of this class is deprecated. This class only works with a single consumer and * a single producer. + * Note that use of this class is deprecated. This class only works with a single consumer and + * a single producer. */ template<typename T> - class BlockingQueue : boost::noncopyable { + class BlockingQueue { + MONGO_DISALLOW_COPYING(BlockingQueue); typedef size_t (*getSizeFunc)(const T& t); public: BlockingQueue() : @@ -69,7 +71,7 @@ namespace mongo { _getSize(f) {} void push(T const& t) { - boost::unique_lock<boost::mutex> l( _lock ); + std::unique_lock<std::mutex> l( _lock ); size_t tSize = _getSize(t); while (_currentSize + tSize > _maxSize) { _cvNoLongerFull.wait( l ); @@ -80,7 +82,7 @@ namespace mongo { } bool empty() const { - boost::lock_guard<boost::mutex> l( _lock ); + std::lock_guard<std::mutex> l( _lock ); return _queue.empty(); } @@ -88,7 +90,7 @@ namespace mongo { * The size as measured by the size function. Default to counting each item */ size_t size() const { - boost::lock_guard<boost::mutex> l( _lock ); + std::lock_guard<std::mutex> l( _lock ); return _currentSize; } @@ -103,19 +105,19 @@ namespace mongo { * The number/count of items in the queue ( _queue.size() ) */ size_t count() const { - boost::lock_guard<boost::mutex> l( _lock ); + std::lock_guard<std::mutex> l( _lock ); return _queue.size(); } void clear() { - boost::lock_guard<boost::mutex> l(_lock); + std::lock_guard<std::mutex> l(_lock); _queue = std::queue<T>(); _currentSize = 0; _cvNoLongerFull.notify_one(); } bool tryPop( T & t ) { - boost::lock_guard<boost::mutex> l( _lock ); + std::lock_guard<std::mutex> l( _lock ); if ( _queue.empty() ) return false; @@ -129,7 +131,7 @@ namespace mongo { T blockingPop() { - boost::unique_lock<boost::mutex> l( _lock ); + std::unique_lock<std::mutex> l( _lock ); while( _queue.empty() ) _cvNoLongerEmpty.wait( l ); @@ -148,16 +150,11 @@ namespace mongo { * otherwise return false and t won't be changed */ bool blockingPop( T& t , int maxSecondsToWait ) { - - Timer timer; - - boost::xtime xt; - boost::xtime_get(&xt, MONGO_BOOST_TIME_UTC); - xt.sec += maxSecondsToWait; - - boost::unique_lock<boost::mutex> l( _lock ); - while( _queue.empty() ) { - if ( ! _cvNoLongerEmpty.timed_wait( l , xt ) ) + using namespace std::chrono; + const auto deadline = system_clock::now() + seconds(maxSecondsToWait); + std::unique_lock<std::mutex> l(_lock); + while(_queue.empty()) { + if (std::cv_status::timeout == _cvNoLongerEmpty.wait_until(l, deadline)) return false; } @@ -171,15 +168,11 @@ namespace mongo { // Obviously, this should only be used when you have // only one consumer bool blockingPeek(T& t, int maxSecondsToWait) { - Timer timer; - - boost::xtime xt; - boost::xtime_get(&xt, MONGO_BOOST_TIME_UTC); - xt.sec += maxSecondsToWait; - - boost::unique_lock<boost::mutex> l( _lock ); - while( _queue.empty() ) { - if ( ! _cvNoLongerEmpty.timed_wait( l , xt ) ) + using namespace std::chrono; + const auto deadline = system_clock::now() + seconds(maxSecondsToWait); + std::unique_lock<std::mutex> l(_lock); + while(_queue.empty()) { + if (std::cv_status::timeout == _cvNoLongerEmpty.wait_until(l, deadline)) return false; } @@ -191,7 +184,7 @@ namespace mongo { // only one consumer bool peek(T& t) { - boost::unique_lock<boost::mutex> l( _lock ); + std::unique_lock<std::mutex> l( _lock ); if (_queue.empty()) { return false; } @@ -201,14 +194,14 @@ namespace mongo { } private: - mutable mongo::mutex _lock; + mutable std::mutex _lock; std::queue<T> _queue; const size_t _maxSize; size_t _currentSize; getSizeFunc _getSize; - boost::condition _cvNoLongerFull; - boost::condition _cvNoLongerEmpty; + std::condition_variable _cvNoLongerFull; + std::condition_variable _cvNoLongerEmpty; }; } diff --git a/src/mongo/util/time_support.cpp b/src/mongo/util/time_support.cpp index a6f6e407adf..07759e890ba 100644 --- a/src/mongo/util/time_support.cpp +++ b/src/mongo/util/time_support.cpp @@ -35,6 +35,7 @@ #include <boost/thread/thread.hpp> #include <boost/thread/tss.hpp> #include <boost/thread/xtime.hpp> +#include <boost/version.hpp> #include "mongo/base/init.h" #include "mongo/base/parse_number.h" @@ -43,6 +44,12 @@ #include "mongo/util/assert_util.h" #include "mongo/util/mongoutils/str.h" +#if BOOST_VERSION >= 105000 +#define MONGO_BOOST_TIME_UTC boost::TIME_UTC_ +#else +#define MONGO_BOOST_TIME_UTC boost::TIME_UTC +#endif + #ifdef _WIN32 #include <boost/date_time/filetime_functions.hpp> #include "mongo/util/concurrency/mutex.h" diff --git a/src/mongo/util/time_support.h b/src/mongo/util/time_support.h index 1d1e0cb29ed..850a6e90ca6 100644 --- a/src/mongo/util/time_support.h +++ b/src/mongo/util/time_support.h @@ -29,12 +29,11 @@ #pragma once -#include <iosfwd> +#include <boost/date_time/gregorian/gregorian_types.hpp> +#include <boost/date_time/posix_time/posix_time_types.hpp> #include <ctime> +#include <iosfwd> #include <string> -#include <boost/date_time/posix_time/posix_time_types.hpp> -#include <boost/thread/xtime.hpp> -#include <boost/version.hpp> #include "mongo/base/status_with.h" #include "mongo/stdx/chrono.h" @@ -355,11 +354,4 @@ namespace mongo { struct tm *gmtime(const time_t *timep); struct tm *localtime(const time_t *timep); -#if defined(MONGO_BOOST_TIME_UTC_HACK) || (BOOST_VERSION >= 105000) -#define MONGO_BOOST_TIME_UTC boost::TIME_UTC_ -#else -#define MONGO_BOOST_TIME_UTC boost::TIME_UTC -#endif - } // namespace mongo - |