summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Storch <david.storch@mongodb.com>2021-01-29 09:49:44 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-02-02 17:06:33 +0000
commite0602a389d6a9d842b73fd9b22c9046b046131d7 (patch)
tree816c9cba7e6e16d6e56a6b2f962c7701c01a2bc3 /src
parentdbd98eb603720f38f9c782ff167284dd878c9dc2 (diff)
downloadmongo-e0602a389d6a9d842b73fd9b22c9046b046131d7.tar.gz
SERVER-53723 Prevent failpoint from mistakenly acquiring db_raii helper during getMore on agg cursor
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/commands/getmore_cmd.cpp13
1 files changed, 9 insertions, 4 deletions
diff --git a/src/mongo/db/commands/getmore_cmd.cpp b/src/mongo/db/commands/getmore_cmd.cpp
index 3e64cc79090..53ead6d1e12 100644
--- a/src/mongo/db/commands/getmore_cmd.cpp
+++ b/src/mongo/db/commands/getmore_cmd.cpp
@@ -487,7 +487,12 @@ public:
// repeatedly release and re-acquire the collection readLock at regular intervals until
// the failpoint is released. This is done in order to avoid deadlocks caused by the
// pinned-cursor failpoints in this file (see SERVER-21997).
- std::function<void()> dropAndReacquireReadLock = [&readLock, opCtx, this]() {
+ std::function<void()> dropAndReacquireReadLockIfLocked = [&readLock, opCtx, this]() {
+ if (!readLock) {
+ // This function is a no-op if 'readLock' is not held in the first place.
+ return;
+ }
+
// Make sure an interrupted operation does not prevent us from reacquiring the lock.
UninterruptibleLockGuard noInterrupt(opCtx->lockState());
readLock.reset();
@@ -498,7 +503,7 @@ public:
&waitAfterPinningCursorBeforeGetMoreBatch,
opCtx,
"waitAfterPinningCursorBeforeGetMoreBatch",
- dropAndReacquireReadLock,
+ dropAndReacquireReadLockIfLocked,
_request.nss);
}
@@ -590,9 +595,9 @@ public:
// of this operation's CurOp to signal that we've hit this point and then spin until the
// failpoint is released.
std::function<void()> saveAndRestoreStateWithReadLockReacquisition =
- [exec, dropAndReacquireReadLock, &readLock]() {
+ [exec, dropAndReacquireReadLockIfLocked, &readLock]() {
exec->saveState();
- dropAndReacquireReadLock();
+ dropAndReacquireReadLockIfLocked();
exec->restoreState(&readLock->getCollection());
};