diff options
Diffstat (limited to 'src/mongo/db/concurrency/d_concurrency.cpp')
-rw-r--r-- | src/mongo/db/concurrency/d_concurrency.cpp | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/src/mongo/db/concurrency/d_concurrency.cpp b/src/mongo/db/concurrency/d_concurrency.cpp index fe7daed7201..9fe447c15f0 100644 --- a/src/mongo/db/concurrency/d_concurrency.cpp +++ b/src/mongo/db/concurrency/d_concurrency.cpp @@ -29,11 +29,9 @@ #include "mongo/db/concurrency/d_concurrency.h" -#include <memory> #include <string> #include <vector> -#include "mongo/db/concurrency/flow_control_ticketholder.h" #include "mongo/db/namespace_string.h" #include "mongo/db/service_context.h" #include "mongo/logv2/log.h" @@ -178,6 +176,27 @@ Lock::GlobalLock::GlobalLock(GlobalLock&& otherLock) otherLock._result = LOCK_INVALID; } +Lock::GlobalLock::~GlobalLock() { + // Preserve the original lock result which will be overridden by unlock(). + auto lockResult = _result; + auto* locker = _opCtx->lockState(); + + 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 && !locker->inAWriteUnitOfWork(); + if (willReleaseLock) { + _opCtx->recoveryUnit()->abandonSnapshot(); + } + _unlock(); + } + + if (!_skipRSTLLock && (lockResult == LOCK_OK || lockResult == LOCK_WAITING)) { + locker->unlock(resourceIdReplicationStateTransitionLock); + } +} + void Lock::GlobalLock::_unlock() { _opCtx->lockState()->unlockGlobal(); _result = LOCK_INVALID; |