summaryrefslogtreecommitdiff
path: root/src/mongo/db/concurrency/d_concurrency.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/concurrency/d_concurrency.cpp')
-rw-r--r--src/mongo/db/concurrency/d_concurrency.cpp23
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;