diff options
Diffstat (limited to 'src/mongo/db/concurrency/d_concurrency.h')
-rw-r--r-- | src/mongo/db/concurrency/d_concurrency.h | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/src/mongo/db/concurrency/d_concurrency.h b/src/mongo/db/concurrency/d_concurrency.h index 9cf4aef7c7e..aacd3b6d724 100644 --- a/src/mongo/db/concurrency/d_concurrency.h +++ b/src/mongo/db/concurrency/d_concurrency.h @@ -29,6 +29,8 @@ #pragma once +#include <climits> // For UINT_MAX + #include "mongo/db/concurrency/locker.h" #include "mongo/db/operation_context.h" #include "mongo/util/timer.h" @@ -244,7 +246,24 @@ public: GlobalLock(GlobalLock&&); - ~GlobalLock(); + ~GlobalLock() { + // Preserve the original lock result which will be overridden by unlock(). + auto lockResult = _result; + if (isLocked()) { + // Abandon our snapshot if destruction of the GlobalLock object results in actually + // unlocking the global lock. Recursive locking and the two-phase locking protocol + // may prevent lock release. + const bool willReleaseLock = _isOutermostLock && + !(_opCtx->lockState() && _opCtx->lockState()->inAWriteUnitOfWork()); + if (willReleaseLock) { + _opCtx->recoveryUnit()->abandonSnapshot(); + } + _unlock(); + } + if (!_skipRSTLLock && (lockResult == LOCK_OK || lockResult == LOCK_WAITING)) { + _opCtx->lockState()->unlock(resourceIdReplicationStateTransitionLock); + } + } bool isLocked() const { return _result == LOCK_OK; |