summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSpencer Jackson <spencer.jackson@mongodb.com>2017-05-23 11:18:19 -0400
committerSpencer Jackson <spencer.jackson@mongodb.com>2017-06-05 12:48:47 -0400
commit7d5b5cd998df4a8532748c2a59fce06c305122d8 (patch)
tree9fdb47dd1938af6d3d9ea0284ccbd231d806919e
parent9785b9c4cda63c813abb2468e644eb84cc903f69 (diff)
downloadmongo-7d5b5cd998df4a8532748c2a59fce06c305122d8.tar.gz
SERVER-29327: Prevent DBDirectClient from storing MaxTimeMS on cursors
-rw-r--r--src/mongo/db/commands/find_cmd.cpp7
-rw-r--r--src/mongo/db/commands/getmore_cmd.cpp10
-rw-r--r--src/mongo/db/query/find.cpp20
3 files changed, 23 insertions, 14 deletions
diff --git a/src/mongo/db/commands/find_cmd.cpp b/src/mongo/db/commands/find_cmd.cpp
index 4a1fbd18510..4b18a6fb8cb 100644
--- a/src/mongo/db/commands/find_cmd.cpp
+++ b/src/mongo/db/commands/find_cmd.cpp
@@ -401,7 +401,12 @@ public:
cursorExec->saveState();
cursorExec->detachFromOperationContext();
- pinnedCursor.getCursor()->setLeftoverMaxTimeMicros(opCtx->getRemainingMaxTimeMicros());
+ // We assume that cursors created through a DBDirectClient are always used from their
+ // original OperationContext, so we do not need to move time to and from the cursor.
+ if (!opCtx->getClient()->isInDirectClient()) {
+ pinnedCursor.getCursor()->setLeftoverMaxTimeMicros(
+ opCtx->getRemainingMaxTimeMicros());
+ }
pinnedCursor.getCursor()->setPos(numResults);
// Fill out curop based on the results.
diff --git a/src/mongo/db/commands/getmore_cmd.cpp b/src/mongo/db/commands/getmore_cmd.cpp
index e9c46da135a..6cc3799d6a4 100644
--- a/src/mongo/db/commands/getmore_cmd.cpp
+++ b/src/mongo/db/commands/getmore_cmd.cpp
@@ -284,20 +284,16 @@ public:
const bool hasOwnMaxTime = opCtx->hasDeadline();
- if (!hasOwnMaxTime) {
+ // We assume that cursors created through a DBDirectClient are always used from their
+ // original OperationContext, so we do not need to move time to and from the cursor.
+ if (!hasOwnMaxTime && !opCtx->getClient()->isInDirectClient()) {
// There is no time limit set directly on this getMore command. If the cursor is
// awaitData, then we supply a default time of one second. Otherwise we roll over
// any leftover time from the maxTimeMS of the operation that spawned this cursor,
// applying it to this getMore.
if (isCursorAwaitData(cursor)) {
- uassert(40117,
- "Illegal attempt to set operation deadline within DBDirectClient",
- !opCtx->getClient()->isInDirectClient());
opCtx->setDeadlineAfterNowBy(Seconds{1});
} else if (cursor->getLeftoverMaxTimeMicros() < Microseconds::max()) {
- uassert(40118,
- "Illegal attempt to set operation deadline within DBDirectClient",
- !opCtx->getClient()->isInDirectClient());
opCtx->setDeadlineAfterNowBy(cursor->getLeftoverMaxTimeMicros());
}
}
diff --git a/src/mongo/db/query/find.cpp b/src/mongo/db/query/find.cpp
index d6fb483b627..e03b3318b1a 100644
--- a/src/mongo/db/query/find.cpp
+++ b/src/mongo/db/query/find.cpp
@@ -481,9 +481,13 @@ Message getMore(OperationContext* opCtx,
*exhaust = cc->queryOptions() & QueryOption_Exhaust;
- // If the getmore had a time limit, remaining time is "rolled over" back to the
- // cursor (for use by future getmore ops).
- cc->setLeftoverMaxTimeMicros(opCtx->getRemainingMaxTimeMicros());
+ // We assume that cursors created through a DBDirectClient are always used from their
+ // original OperationContext, so we do not need to move time to and from the cursor.
+ if (!opCtx->getClient()->isInDirectClient()) {
+ // If the getmore had a time limit, remaining time is "rolled over" back to the
+ // cursor (for use by future getmore ops).
+ cc->setLeftoverMaxTimeMicros(opCtx->getRemainingMaxTimeMicros());
+ }
}
}
@@ -684,9 +688,13 @@ std::string runQuery(OperationContext* opCtx,
pinnedCursor.getCursor()->setPos(numResults);
- // If the query had a time limit, remaining time is "rolled over" to the cursor (for
- // use by future getmore ops).
- pinnedCursor.getCursor()->setLeftoverMaxTimeMicros(opCtx->getRemainingMaxTimeMicros());
+ // We assume that cursors created through a DBDirectClient are always used from their
+ // original OperationContext, so we do not need to move time to and from the cursor.
+ if (!opCtx->getClient()->isInDirectClient()) {
+ // If the query had a time limit, remaining time is "rolled over" to the cursor (for
+ // use by future getmore ops).
+ pinnedCursor.getCursor()->setLeftoverMaxTimeMicros(opCtx->getRemainingMaxTimeMicros());
+ }
endQueryOp(opCtx, collection, *pinnedCursor.getCursor()->getExecutor(), numResults, ccId);
} else {