diff options
Diffstat (limited to 'src/mongo/db/operation_context.cpp')
| -rw-r--r-- | src/mongo/db/operation_context.cpp | 52 |
1 files changed, 20 insertions, 32 deletions
diff --git a/src/mongo/db/operation_context.cpp b/src/mongo/db/operation_context.cpp index f4272010fa5..649ad363b0c 100644 --- a/src/mongo/db/operation_context.cpp +++ b/src/mongo/db/operation_context.cpp @@ -318,36 +318,27 @@ StatusWith<stdx::cv_status> OperationContext::waitForConditionOrInterruptNoAsser deadline = std::min(deadline, getDeadline()); } - try { - const auto waitStatus = [&] { - if (Date_t::max() == deadline) { - Waitable::wait(_baton.get(), getServiceContext()->getPreciseClockSource(), cv, m); - return stdx::cv_status::no_timeout; - } - return getServiceContext()->getPreciseClockSource()->waitForConditionUntil( - cv, m, deadline, _baton.get()); - }(); - - if (opHasDeadline && waitStatus == stdx::cv_status::timeout && deadline == getDeadline()) { - // It's possible that the system clock used in stdx::condition_variable::wait_until - // is slightly ahead of the FastClock used in checkForInterrupt. In this case, - // we treat the operation as though it has exceeded its time limit, just as if the - // FastClock and system clock had agreed. - if (!_hasArtificialDeadline) { - interruptible_detail::doWithoutLock(m, [&] { markKilled(_timeoutError); }); - } - return Status(_timeoutError, "operation exceeded time limit"); + const auto waitStatus = [&] { + if (Date_t::max() == deadline) { + Waitable::wait(_baton.get(), getServiceContext()->getPreciseClockSource(), cv, m); + return stdx::cv_status::no_timeout; } - - return waitStatus; - } catch (const ExceptionFor<ErrorCodes::DurationOverflow>& ex) { - // Inside waitForConditionUntil() is a conversion from deadline's Date_t type to the system - // clock's time_point type. If the time_point's compiler-dependent resolution is higher - // than Date_t's milliseconds, it's possible for the conversion from Date_t to time_point - // to overflow and trigger an exception. We catch that here to maintain the noexcept - // contract. - return ex.toStatus(); + return getServiceContext()->getPreciseClockSource()->waitForConditionUntil( + cv, m, deadline, _baton.get()); + }(); + + if (opHasDeadline && waitStatus == stdx::cv_status::timeout && deadline == getDeadline()) { + // It's possible that the system clock used in stdx::condition_variable::wait_until + // is slightly ahead of the FastClock used in checkForInterrupt. In this case, + // we treat the operation as though it has exceeded its time limit, just as if the + // FastClock and system clock had agreed. + if (!_hasArtificialDeadline) { + interruptible_detail::doWithoutLock(m, [&] { markKilled(_timeoutError); }); + } + return Status(_timeoutError, "operation exceeded time limit"); } + + return waitStatus; } void OperationContext::markKilled(ErrorCodes::Error killCode) { @@ -400,10 +391,7 @@ void OperationContext::setIsExecutingShutdown() { _isExecutingShutdown = true; - // The OperationContext executing shutdown is immune from interruption. - _hasArtificialDeadline = true; - setDeadlineByDate(Date_t::max(), ErrorCodes::ExceededTimeLimit); - _ignoreInterrupts = true; + pushIgnoreInterrupts(); } void OperationContext::setLogicalSessionId(LogicalSessionId lsid) { |
