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-07-11 09:56:40 -0400
commit57069e87a5237c9026e985b01f8fef504de3f62f (patch)
tree3f9d7d8e771c0a335a5ec0d9fda3640e52276ca1
parent0bcd33cb6ced016aed81a4734ab62167fbf845d8 (diff)
downloadmongo-57069e87a5237c9026e985b01f8fef504de3f62f.tar.gz
SERVER-29327: Prevent DBDirectClient from storing MaxTimeMS on cursors
(cherry picked from commit 7d5b5cd998df4a8532748c2a59fce06c305122d8)
-rw-r--r--src/mongo/db/commands/find_cmd.cpp6
-rw-r--r--src/mongo/db/commands/getmore_cmd.cpp10
-rw-r--r--src/mongo/db/query/find.cpp20
3 files changed, 22 insertions, 14 deletions
diff --git a/src/mongo/db/commands/find_cmd.cpp b/src/mongo/db/commands/find_cmd.cpp
index 5257cec25db..3a48725631f 100644
--- a/src/mongo/db/commands/find_cmd.cpp
+++ b/src/mongo/db/commands/find_cmd.cpp
@@ -408,7 +408,11 @@ public:
cursorExec->saveState();
cursorExec->detachFromOperationContext();
- cursor->setLeftoverMaxTimeMicros(txn->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 (!txn->getClient()->isInDirectClient()) {
+ cursor->setLeftoverMaxTimeMicros(txn->getRemainingMaxTimeMicros());
+ }
cursor->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 709b6b9c76a..9c327ec57af 100644
--- a/src/mongo/db/commands/getmore_cmd.cpp
+++ b/src/mongo/db/commands/getmore_cmd.cpp
@@ -301,20 +301,16 @@ public:
const bool hasOwnMaxTime = txn->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 && !txn->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",
- !txn->getClient()->isInDirectClient());
txn->setDeadlineAfterNowBy(Seconds{1});
} else if (cursor->getLeftoverMaxTimeMicros() < Microseconds::max()) {
- uassert(40118,
- "Illegal attempt to set operation deadline within DBDirectClient",
- !txn->getClient()->isInDirectClient());
txn->setDeadlineAfterNowBy(cursor->getLeftoverMaxTimeMicros());
}
}
diff --git a/src/mongo/db/query/find.cpp b/src/mongo/db/query/find.cpp
index 2fec699721d..9e9ebb32fb6 100644
--- a/src/mongo/db/query/find.cpp
+++ b/src/mongo/db/query/find.cpp
@@ -478,9 +478,13 @@ Message getMore(OperationContext* txn,
*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(txn->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 (!txn->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(txn->getRemainingMaxTimeMicros());
+ }
}
}
@@ -689,9 +693,13 @@ std::string runQuery(OperationContext* txn,
cc->setPos(numResults);
- // If the query had a time limit, remaining time is "rolled over" to the cursor (for
- // use by future getmore ops).
- cc->setLeftoverMaxTimeMicros(txn->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 (!txn->getClient()->isInDirectClient()) {
+ // If the query had a time limit, remaining time is "rolled over" to the cursor (for
+ // use by future getmore ops).
+ cc->setLeftoverMaxTimeMicros(txn->getRemainingMaxTimeMicros());
+ }
endQueryOp(txn, collection, *cc->getExecutor(), numResults, ccId);
} else {