diff options
author | Tess Avitabile <tess.avitabile@mongodb.com> | 2018-02-05 17:21:06 -0500 |
---|---|---|
committer | Tess Avitabile <tess.avitabile@mongodb.com> | 2018-02-08 10:31:50 -0500 |
commit | b730e13c75d21ee86fea0622a55410d790a23224 (patch) | |
tree | 5a2aeec9dce06a77fbd0070261b1b6eea17ed248 /src/mongo/db/query/plan_yield_policy.cpp | |
parent | c556e377094792e7253a95cb5fedcd703a99bf2c (diff) | |
download | mongo-b730e13c75d21ee86fea0622a55410d790a23224.tar.gz |
SERVER-32685 Disable lock and WT transaction yielding under readConcern snapshot for find and getMore
Diffstat (limited to 'src/mongo/db/query/plan_yield_policy.cpp')
-rw-r--r-- | src/mongo/db/query/plan_yield_policy.cpp | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/src/mongo/db/query/plan_yield_policy.cpp b/src/mongo/db/query/plan_yield_policy.cpp index 13bded7f1b4..4c3a96282d4 100644 --- a/src/mongo/db/query/plan_yield_policy.cpp +++ b/src/mongo/db/query/plan_yield_policy.cpp @@ -36,11 +36,16 @@ #include "mongo/db/query/query_knobs.h" #include "mongo/db/query/query_yield.h" #include "mongo/db/service_context.h" +#include "mongo/util/fail_point_service.h" #include "mongo/util/scopeguard.h" #include "mongo/util/time_support.h" namespace mongo { +namespace { +MONGO_FP_DECLARE(setCheckForInterruptHang); +} // namespace + PlanYieldPolicy::PlanYieldPolicy(PlanExecutor* exec, PlanExecutor::YieldPolicy policy) : _policy(exec->getOpCtx()->lockState()->isGlobalLockedRecursively() ? PlanExecutor::NO_YIELD : policy), @@ -59,6 +64,13 @@ PlanYieldPolicy::PlanYieldPolicy(PlanExecutor::YieldPolicy policy, ClockSource* Milliseconds(internalQueryExecYieldPeriodMS.load())), _planYielding(nullptr) {} +bool PlanYieldPolicy::shouldYieldOrInterrupt() { + if (_policy == PlanExecutor::INTERRUPT_ONLY) { + return _elapsedTracker.intervalHasElapsed(); + } + return shouldYield(); +} + bool PlanYieldPolicy::shouldYield() { if (!canAutoYield()) return false; @@ -72,15 +84,28 @@ void PlanYieldPolicy::resetTimer() { _elapsedTracker.resetLastTime(); } -Status PlanYieldPolicy::yield(RecordFetcher* recordFetcher) { +Status PlanYieldPolicy::yieldOrInterrupt(RecordFetcher* recordFetcher) { invariant(_planYielding); if (recordFetcher) { OperationContext* opCtx = _planYielding->getOpCtx(); - return yield([recordFetcher, opCtx] { recordFetcher->setup(opCtx); }, - [recordFetcher] { recordFetcher->fetch(); }); + return yieldOrInterrupt([recordFetcher, opCtx] { recordFetcher->setup(opCtx); }, + [recordFetcher] { recordFetcher->fetch(); }); } else { - return yield(nullptr, nullptr); + return yieldOrInterrupt(nullptr, nullptr); + } +} + +Status PlanYieldPolicy::yieldOrInterrupt(stdx::function<void()> beforeYieldingFn, + stdx::function<void()> whileYieldingFn) { + if (_policy == PlanExecutor::INTERRUPT_ONLY) { + ON_BLOCK_EXIT([this]() { resetTimer(); }); + OperationContext* opCtx = _planYielding->getOpCtx(); + invariant(opCtx); + MONGO_FAIL_POINT_PAUSE_WHILE_SET(setCheckForInterruptHang); + return opCtx->checkForInterruptNoAssert(); } + + return yield(beforeYieldingFn, whileYieldingFn); } Status PlanYieldPolicy::yield(stdx::function<void()> beforeYieldingFn, @@ -106,6 +131,8 @@ Status PlanYieldPolicy::yield(stdx::function<void()> beforeYieldingFn, // that it's time to yield. Whether or not we will actually yield, we need to check // if this operation has been interrupted. if (_policy == PlanExecutor::YIELD_AUTO) { + MONGO_FAIL_POINT_PAUSE_WHILE_SET(setCheckForInterruptHang); + auto interruptStatus = opCtx->checkForInterruptNoAssert(); if (!interruptStatus.isOK()) { return interruptStatus; |