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.h21
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;