summaryrefslogtreecommitdiff
path: root/src/mongo/db/concurrency/d_concurrency.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/concurrency/d_concurrency.h')
-rw-r--r--src/mongo/db/concurrency/d_concurrency.h405
1 files changed, 202 insertions, 203 deletions
diff --git a/src/mongo/db/concurrency/d_concurrency.h b/src/mongo/db/concurrency/d_concurrency.h
index f21d356994e..b95b7b46fec 100644
--- a/src/mongo/db/concurrency/d_concurrency.h
+++ b/src/mongo/db/concurrency/d_concurrency.h
@@ -28,257 +28,256 @@
#pragma once
-#include <climits> // For UINT_MAX
+#include <climits> // For UINT_MAX
#include "mongo/db/concurrency/locker.h"
#include "mongo/util/timer.h"
namespace mongo {
- class StringData;
+class StringData;
+
+class Lock {
+public:
+ /**
+ * NOTE: DO NOT add any new usages of TempRelease. It is being deprecated/removed.
+ */
+ class TempRelease {
+ MONGO_DISALLOW_COPYING(TempRelease);
- class Lock {
public:
+ explicit TempRelease(Locker* lockState);
+ ~TempRelease();
- /**
- * NOTE: DO NOT add any new usages of TempRelease. It is being deprecated/removed.
- */
- class TempRelease {
- MONGO_DISALLOW_COPYING(TempRelease);
- public:
- explicit TempRelease(Locker* lockState);
- ~TempRelease();
+ private:
+ // Not owned
+ Locker* const _lockState;
- private:
- // Not owned
- Locker* const _lockState;
+ // If _locksReleased is true, this stores the persisted lock information to be restored
+ // in the destructor. Otherwise it is empty.
+ Locker::LockSnapshot _lockSnapshot;
- // If _locksReleased is true, this stores the persisted lock information to be restored
- // in the destructor. Otherwise it is empty.
- Locker::LockSnapshot _lockSnapshot;
+ // False if locks could not be released because of recursive locking
+ const bool _locksReleased;
+ };
- // False if locks could not be released because of recursive locking
- const bool _locksReleased;
- };
+ /**
+ * General purpose RAII wrapper for a resource managed by the lock manager
+ *
+ * See LockMode for the supported modes. Unlike DBLock/Collection lock, this will not do
+ * any additional checks/upgrades or global locking. Use ResourceLock for locking
+ * resources other than RESOURCE_GLOBAL, RESOURCE_DATABASE and RESOURCE_COLLECTION.
+ */
+ class ResourceLock {
+ MONGO_DISALLOW_COPYING(ResourceLock);
- /**
- * General purpose RAII wrapper for a resource managed by the lock manager
- *
- * See LockMode for the supported modes. Unlike DBLock/Collection lock, this will not do
- * any additional checks/upgrades or global locking. Use ResourceLock for locking
- * resources other than RESOURCE_GLOBAL, RESOURCE_DATABASE and RESOURCE_COLLECTION.
- */
- class ResourceLock {
- MONGO_DISALLOW_COPYING(ResourceLock);
-
- public:
- ResourceLock(Locker* locker, ResourceId rid)
- : _rid(rid),
- _locker(locker),
- _result(LOCK_INVALID) {
- }
-
- ResourceLock(Locker* locker, ResourceId rid, LockMode mode)
- : _rid(rid),
- _locker(locker),
- _result(LOCK_INVALID) {
- lock(mode);
- }
+ public:
+ ResourceLock(Locker* locker, ResourceId rid)
+ : _rid(rid), _locker(locker), _result(LOCK_INVALID) {}
- ~ResourceLock() {
- unlock();
- }
+ ResourceLock(Locker* locker, ResourceId rid, LockMode mode)
+ : _rid(rid), _locker(locker), _result(LOCK_INVALID) {
+ lock(mode);
+ }
- void lock(LockMode mode);
- void unlock();
+ ~ResourceLock() {
+ unlock();
+ }
- bool isLocked() const { return _result == LOCK_OK; }
+ void lock(LockMode mode);
+ void unlock();
- private:
- const ResourceId _rid;
- Locker* const _locker;
+ bool isLocked() const {
+ return _result == LOCK_OK;
+ }
- LockResult _result;
- };
+ private:
+ const ResourceId _rid;
+ Locker* const _locker;
+ LockResult _result;
+ };
- /**
- * Global lock.
- *
- * Grabs global resource lock. Allows further (recursive) acquisition of the global lock
- * in any mode, see LockMode.
- * NOTE: Does not acquire flush lock.
- */
- class GlobalLock {
- public:
- explicit GlobalLock(Locker* locker);
- GlobalLock(Locker* locker, LockMode lockMode, unsigned timeoutMs);
- ~GlobalLock() {
- _unlock();
- }
+ /**
+ * Global lock.
+ *
+ * Grabs global resource lock. Allows further (recursive) acquisition of the global lock
+ * in any mode, see LockMode.
+ * NOTE: Does not acquire flush lock.
+ */
+ class GlobalLock {
+ public:
+ explicit GlobalLock(Locker* locker);
+ GlobalLock(Locker* locker, LockMode lockMode, unsigned timeoutMs);
- bool isLocked() const { return _result == LOCK_OK; }
+ ~GlobalLock() {
+ _unlock();
+ }
- private:
+ bool isLocked() const {
+ return _result == LOCK_OK;
+ }
- void _lock(LockMode lockMode, unsigned timeoutMs);
- void _unlock();
+ private:
+ void _lock(LockMode lockMode, unsigned timeoutMs);
+ void _unlock();
- Locker* const _locker;
- LockResult _result;
- ResourceLock _pbwm;
- };
+ Locker* const _locker;
+ LockResult _result;
+ ResourceLock _pbwm;
+ };
- /**
- * Global exclusive lock
- *
- * Allows exclusive write access to all databases and collections, blocking all other
- * access. Allows further (recursive) acquisition of the global lock in any mode,
- * see LockMode.
- */
- class GlobalWrite : public GlobalLock {
- public:
- explicit GlobalWrite(Locker* locker, unsigned timeoutMs = UINT_MAX)
- : GlobalLock(locker, MODE_X, timeoutMs) {
-
- if (isLocked()) {
- locker->lockMMAPV1Flush();
- }
+ /**
+ * Global exclusive lock
+ *
+ * Allows exclusive write access to all databases and collections, blocking all other
+ * access. Allows further (recursive) acquisition of the global lock in any mode,
+ * see LockMode.
+ */
+ class GlobalWrite : public GlobalLock {
+ public:
+ explicit GlobalWrite(Locker* locker, unsigned timeoutMs = UINT_MAX)
+ : GlobalLock(locker, MODE_X, timeoutMs) {
+ if (isLocked()) {
+ locker->lockMMAPV1Flush();
}
- };
+ }
+ };
- /**
- * Global shared lock
- *
- * Allows concurrent read access to all databases and collections, blocking any writers.
- * Allows further (recursive) acquisition of the global lock in shared (S) or intent-shared
- * (IS) mode, see LockMode.
- */
- class GlobalRead : public GlobalLock {
- public:
- explicit GlobalRead(Locker* locker, unsigned timeoutMs = UINT_MAX)
- : GlobalLock(locker, MODE_S, timeoutMs) {
-
- if (isLocked()) {
- locker->lockMMAPV1Flush();
- }
+ /**
+ * Global shared lock
+ *
+ * Allows concurrent read access to all databases and collections, blocking any writers.
+ * Allows further (recursive) acquisition of the global lock in shared (S) or intent-shared
+ * (IS) mode, see LockMode.
+ */
+ class GlobalRead : public GlobalLock {
+ public:
+ explicit GlobalRead(Locker* locker, unsigned timeoutMs = UINT_MAX)
+ : GlobalLock(locker, MODE_S, timeoutMs) {
+ if (isLocked()) {
+ locker->lockMMAPV1Flush();
}
- };
+ }
+ };
+
+ /**
+ * Database lock with support for collection- and document-level locking
+ *
+ * This lock supports four modes (see Lock_Mode):
+ * MODE_IS: concurrent database access, requiring further collection read locks
+ * MODE_IX: concurrent database access, requiring further collection read or write locks
+ * MODE_S: shared read access to the database, blocking any writers
+ * MODE_X: exclusive access to the database, blocking all other readers and writers
+ *
+ * For MODE_IS or MODE_S also acquires global lock in intent-shared (IS) mode, and
+ * for MODE_IX or MODE_X also acquires global lock in intent-exclusive (IX) mode.
+ * For storage engines that do not support collection-level locking, MODE_IS will be
+ * upgraded to MODE_S and MODE_IX will be upgraded to MODE_X.
+ */
+ class DBLock {
+ public:
+ DBLock(Locker* locker, StringData db, LockMode mode);
+ ~DBLock();
/**
- * Database lock with support for collection- and document-level locking
- *
- * This lock supports four modes (see Lock_Mode):
- * MODE_IS: concurrent database access, requiring further collection read locks
- * MODE_IX: concurrent database access, requiring further collection read or write locks
- * MODE_S: shared read access to the database, blocking any writers
- * MODE_X: exclusive access to the database, blocking all other readers and writers
- *
- * For MODE_IS or MODE_S also acquires global lock in intent-shared (IS) mode, and
- * for MODE_IX or MODE_X also acquires global lock in intent-exclusive (IX) mode.
- * For storage engines that do not support collection-level locking, MODE_IS will be
- * upgraded to MODE_S and MODE_IX will be upgraded to MODE_X.
+ * Releases the DBLock and reacquires it with the new mode. The global intent
+ * lock is retained (so the database can't disappear). Relocking from MODE_IS or
+ * MODE_S to MODE_IX or MODE_X is not allowed to avoid violating the global intent.
+ * Use relockWithMode() instead of upgrading to avoid deadlock.
*/
- class DBLock {
- public:
- DBLock(Locker* locker, StringData db, LockMode mode);
- ~DBLock();
+ void relockWithMode(LockMode newMode);
- /**
- * Releases the DBLock and reacquires it with the new mode. The global intent
- * lock is retained (so the database can't disappear). Relocking from MODE_IS or
- * MODE_S to MODE_IX or MODE_X is not allowed to avoid violating the global intent.
- * Use relockWithMode() instead of upgrading to avoid deadlock.
- */
- void relockWithMode(LockMode newMode);
+ private:
+ const ResourceId _id;
+ Locker* const _locker;
- private:
- const ResourceId _id;
- Locker* const _locker;
+ // May be changed through relockWithMode. The global lock mode won't change though,
+ // because we never change from IS/S to IX/X or vice versa, just convert locks from
+ // IX -> X.
+ LockMode _mode;
- // May be changed through relockWithMode. The global lock mode won't change though,
- // because we never change from IS/S to IX/X or vice versa, just convert locks from
- // IX -> X.
- LockMode _mode;
+ // Acquires the global lock on our behalf.
+ GlobalLock _globalLock;
+ };
- // Acquires the global lock on our behalf.
- GlobalLock _globalLock;
- };
+ /**
+ * Collection lock with support for document-level locking
+ *
+ * This lock supports four modes (see Lock_Mode):
+ * MODE_IS: concurrent collection access, requiring document level locking read locks
+ * MODE_IX: concurrent collection access, requiring document level read or write locks
+ * MODE_S: shared read access to the collection, blocking any writers
+ * MODE_X: exclusive access to the collection, blocking all other readers and writers
+ *
+ * An appropriate DBLock must already be held before locking a collection: it is an error,
+ * checked with a dassert(), to not have a suitable database lock before locking the
+ * collection. For storage engines that do not support document-level locking, MODE_IS
+ * will be upgraded to MODE_S and MODE_IX will be upgraded to MODE_X.
+ */
+ class CollectionLock {
+ MONGO_DISALLOW_COPYING(CollectionLock);
- /**
- * Collection lock with support for document-level locking
- *
- * This lock supports four modes (see Lock_Mode):
- * MODE_IS: concurrent collection access, requiring document level locking read locks
- * MODE_IX: concurrent collection access, requiring document level read or write locks
- * MODE_S: shared read access to the collection, blocking any writers
- * MODE_X: exclusive access to the collection, blocking all other readers and writers
- *
- * An appropriate DBLock must already be held before locking a collection: it is an error,
- * checked with a dassert(), to not have a suitable database lock before locking the
- * collection. For storage engines that do not support document-level locking, MODE_IS
- * will be upgraded to MODE_S and MODE_IX will be upgraded to MODE_X.
- */
- class CollectionLock {
- MONGO_DISALLOW_COPYING(CollectionLock);
- public:
- CollectionLock(Locker* lockState, StringData ns, LockMode mode);
- ~CollectionLock();
-
- /**
- * When holding the collection in MODE_IX or MODE_X, calling this will release the
- * collection and database locks, and relocks the database in MODE_X. This is typically
- * used if the collection still needs to be created. Upgrading would not be safe as
- * it could lead to deadlock, similarly for relocking the database without releasing
- * the collection lock. The collection lock will also be reacquired even though it is
- * not really needed, as it simplifies invariant checking: the CollectionLock class
- * has as invariant that a collection lock is being held.
- */
- void relockAsDatabaseExclusive(Lock::DBLock& dbLock);
-
- private:
- const ResourceId _id;
- Locker* const _lockState;
- };
+ public:
+ CollectionLock(Locker* lockState, StringData ns, LockMode mode);
+ ~CollectionLock();
/**
- * Like the CollectionLock, but optimized for the local oplog. Always locks in MODE_IX,
- * must call serializeIfNeeded() before doing any concurrent operations in order to
- * support storage engines without document level locking. It is an error, checked with a
- * dassert(), to not have a suitable database lock when taking this lock.
+ * When holding the collection in MODE_IX or MODE_X, calling this will release the
+ * collection and database locks, and relocks the database in MODE_X. This is typically
+ * used if the collection still needs to be created. Upgrading would not be safe as
+ * it could lead to deadlock, similarly for relocking the database without releasing
+ * the collection lock. The collection lock will also be reacquired even though it is
+ * not really needed, as it simplifies invariant checking: the CollectionLock class
+ * has as invariant that a collection lock is being held.
*/
- class OplogIntentWriteLock {
- MONGO_DISALLOW_COPYING(OplogIntentWriteLock);
- public:
- explicit OplogIntentWriteLock(Locker* lockState);
- ~OplogIntentWriteLock();
- void serializeIfNeeded();
- private:
- Locker* const _lockState;
- bool _serialized;
- };
+ void relockAsDatabaseExclusive(Lock::DBLock& dbLock);
+ private:
+ const ResourceId _id;
+ Locker* const _lockState;
+ };
- /**
- * Turn on "parallel batch writer mode" by locking the global ParallelBatchWriterMode
- * resource in exclusive mode. This mode is off by default.
- * Note that only one thread creates a ParallelBatchWriterMode object; the other batch
- * writers just call setIsBatchWriter().
- */
- class ParallelBatchWriterMode {
- MONGO_DISALLOW_COPYING(ParallelBatchWriterMode);
+ /**
+ * Like the CollectionLock, but optimized for the local oplog. Always locks in MODE_IX,
+ * must call serializeIfNeeded() before doing any concurrent operations in order to
+ * support storage engines without document level locking. It is an error, checked with a
+ * dassert(), to not have a suitable database lock when taking this lock.
+ */
+ class OplogIntentWriteLock {
+ MONGO_DISALLOW_COPYING(OplogIntentWriteLock);
+
+ public:
+ explicit OplogIntentWriteLock(Locker* lockState);
+ ~OplogIntentWriteLock();
+ void serializeIfNeeded();
- public:
- explicit ParallelBatchWriterMode(Locker* lockState);
+ private:
+ Locker* const _lockState;
+ bool _serialized;
+ };
+
+
+ /**
+ * Turn on "parallel batch writer mode" by locking the global ParallelBatchWriterMode
+ * resource in exclusive mode. This mode is off by default.
+ * Note that only one thread creates a ParallelBatchWriterMode object; the other batch
+ * writers just call setIsBatchWriter().
+ */
+ class ParallelBatchWriterMode {
+ MONGO_DISALLOW_COPYING(ParallelBatchWriterMode);
+
+ public:
+ explicit ParallelBatchWriterMode(Locker* lockState);
- private:
- ResourceLock _pbwm;
- };
+ private:
+ ResourceLock _pbwm;
};
+};
}