diff options
Diffstat (limited to 'src/mongo/db/concurrency/d_concurrency.h')
-rw-r--r-- | src/mongo/db/concurrency/d_concurrency.h | 123 |
1 files changed, 55 insertions, 68 deletions
diff --git a/src/mongo/db/concurrency/d_concurrency.h b/src/mongo/db/concurrency/d_concurrency.h index ae8501303a7..b999c6103da 100644 --- a/src/mongo/db/concurrency/d_concurrency.h +++ b/src/mongo/db/concurrency/d_concurrency.h @@ -37,7 +37,6 @@ namespace mongo { -class StringData; class NamespaceStringOrUUID; class Lock { @@ -50,61 +49,60 @@ public: * resources other than RESOURCE_GLOBAL, RESOURCE_DATABASE and RESOURCE_COLLECTION. */ class ResourceLock { - ResourceLock(const ResourceLock&) = delete; - ResourceLock& operator=(const ResourceLock&) = delete; - public: - ResourceLock(Locker* locker, ResourceId rid, LockMode mode) - : ResourceLock(nullptr, locker, rid, mode) {} - ResourceLock(OperationContext* opCtx, - Locker* locker, ResourceId rid, LockMode mode, Date_t deadline = Date_t::max()) - : _rid(rid), _locker(locker), _result(LOCK_INVALID) { - lock(opCtx, mode, deadline); + : _opCtx(opCtx), _locker(_opCtx->lockState()), _rid(rid) { + _lock(mode, deadline); + } + + // TODO (SERVER-69461): Do not any new usages of this constructor and get rid of it + ResourceLock(Locker* locker, ResourceId rid, LockMode mode) + : _opCtx(nullptr), _locker(locker), _rid(rid) { + _lock(mode); } ResourceLock(ResourceLock&& otherLock) - : _rid(otherLock._rid), _locker(otherLock._locker), _result(otherLock._result) { - // Mark as moved so the destructor doesn't invalidate the newly- - // constructed lock. + : _opCtx(otherLock._opCtx), + _locker(otherLock._locker), + _rid(std::move(otherLock._rid)), + _result(otherLock._result) { + otherLock._opCtx = nullptr; + otherLock._locker = nullptr; otherLock._result = LOCK_INVALID; } ~ResourceLock() { - if (isLocked()) { - unlock(); - } + _unlock(); } + protected: /** * Acquires lock on this specified resource in the specified mode. * - * If 'opCtx' is provided, it will be used to interrupt a LOCK_WAITING state. * If 'deadline' is provided, we will wait until 'deadline' for the lock to be granted. * Otherwise, this parameter defaults to an infinite deadline. * * This function may throw an exception if it is interrupted. */ - void lock(OperationContext* opCtx, LockMode mode, Date_t deadline = Date_t::max()); - - void unlock(); - - bool isLocked() const { + void _lock(LockMode mode, Date_t deadline = Date_t::max()); + void _unlock(); + bool _isLocked() const { return _result == LOCK_OK; } - private: - const ResourceId _rid; - Locker* const _locker; + OperationContext* _opCtx; - LockResult _result; - }; + // TODO (SERVER-69461): Get rid of this field when the Locker-only constructor is removed. + Locker* _locker; - class SharedLock; - class ExclusiveLock; + ResourceId _rid; + + private: + LockResult _result{LOCK_INVALID}; + }; /** * For use as general mutex or readers/writers lock, outside the general multi-granularity @@ -118,7 +116,14 @@ public: std::string getName() const { return getName(_rid); - }; + } + + /** + * Each instantiation of this class allocates a new ResourceId. + */ + ResourceId getRid() const { + return _rid; + } static std::string getName(ResourceId resourceId); @@ -127,16 +132,6 @@ public: bool isAtLeastReadLocked(Locker* locker); private: - friend class Lock::SharedLock; - friend class Lock::ExclusiveLock; - - /** - * Each instantiation of this class allocates a new ResourceId. - */ - ResourceId rid() const { - return _rid; - } - const ResourceId _rid; }; @@ -145,23 +140,25 @@ public: */ class ExclusiveLock : public ResourceLock { public: - ExclusiveLock(Locker* locker, ResourceMutex mutex) - : ExclusiveLock(nullptr, locker, mutex) {} + ExclusiveLock(OperationContext* opCtx, ResourceMutex mutex) + : ResourceLock(opCtx, mutex.getRid(), MODE_X) {} - /** - * Interruptible lock acquisition. - */ - ExclusiveLock(OperationContext* opCtx, Locker* locker, ResourceMutex mutex) - : ResourceLock(opCtx, locker, mutex.rid(), MODE_X) {} + ExclusiveLock(Locker* locker, ResourceMutex mutex) + : ResourceLock(locker, mutex.getRid(), MODE_X) {} - using ResourceLock::lock; + // Lock/unlock overloads to allow ExclusiveLock to be used with with stdx::unique_lock and + // stdx::condition_variable_any - /** - * Parameterless overload to allow ExclusiveLock to be used with stdx::unique_lock and - * stdx::condition_variable_any - */ void lock() { - lock(nullptr, MODE_X); + _lock(MODE_X); + } + + void unlock() { + _unlock(); + } + + bool isLocked() const { + return _isLocked(); } }; @@ -172,13 +169,11 @@ public: */ class SharedLock : public ResourceLock { public: - SharedLock(Locker* locker, ResourceMutex mutex) : SharedLock(nullptr, locker, mutex) {} + SharedLock(OperationContext* opCtx, ResourceMutex mutex) + : ResourceLock(opCtx, mutex.getRid(), MODE_IS) {} - /** - * Interruptible lock acquisition. - */ - SharedLock(OperationContext* opCtx, Locker* locker, ResourceMutex mutex) - : ResourceLock(opCtx, locker, mutex.rid(), MODE_IS) {} + SharedLock(Locker* locker, ResourceMutex mutex) + : ResourceLock(locker, mutex.getRid(), MODE_IS) {} }; /** @@ -315,14 +310,6 @@ public: DBLock(DBLock&&); ~DBLock(); - /** - * 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); - bool isLocked() const { return _result == LOCK_OK; } @@ -386,7 +373,7 @@ public: ParallelBatchWriterMode& operator=(const ParallelBatchWriterMode&) = delete; public: - explicit ParallelBatchWriterMode(Locker* lockState); + explicit ParallelBatchWriterMode(OperationContext* opCtx); private: ResourceLock _pbwm; |