summaryrefslogtreecommitdiff
path: root/src/mongo/db/operation_context.cpp
diff options
context:
space:
mode:
authorMathias Stearn <mathias@10gen.com>2017-03-21 18:16:08 -0400
committerMathias Stearn <mathias@10gen.com>2017-03-22 19:15:21 -0400
commit86bc5bdac397909e246f0ea19f5414387bb6b0a9 (patch)
treec99a95052141d4749fd24d22007ee60768feb087 /src/mongo/db/operation_context.cpp
parent51d8b9c2f5eafc457f889d9786ebd68e4398ba64 (diff)
downloadmongo-86bc5bdac397909e246f0ea19f5414387bb6b0a9.tar.gz
SERVER-28421 Implement ClockSource::waitForConditionUntil()
Diffstat (limited to 'src/mongo/db/operation_context.cpp')
-rw-r--r--src/mongo/db/operation_context.cpp56
1 files changed, 1 insertions, 55 deletions
diff --git a/src/mongo/db/operation_context.cpp b/src/mongo/db/operation_context.cpp
index 0950c620280..4170797da1e 100644
--- a/src/mongo/db/operation_context.cpp
+++ b/src/mongo/db/operation_context.cpp
@@ -245,53 +245,6 @@ stdx::cv_status OperationContext::waitForConditionOrInterruptUntil(
return uassertStatusOK(waitForConditionOrInterruptNoAssertUntil(cv, m, deadline));
}
-static NOINLINE_DECL stdx::cv_status cvWaitUntilWithClockSource(ClockSource* clockSource,
- stdx::condition_variable& cv,
- stdx::unique_lock<stdx::mutex>& m,
- Date_t deadline) {
- if (deadline <= clockSource->now()) {
- return stdx::cv_status::timeout;
- }
-
- struct AlarmInfo {
- stdx::mutex controlMutex;
- stdx::mutex* waitMutex;
- stdx::condition_variable* waitCV;
- stdx::cv_status cvWaitResult = stdx::cv_status::no_timeout;
- };
- auto alarmInfo = std::make_shared<AlarmInfo>();
- alarmInfo->waitCV = &cv;
- alarmInfo->waitMutex = m.mutex();
- const auto waiterThreadId = stdx::this_thread::get_id();
- bool invokedAlarmInline = false;
- invariantOK(clockSource->setAlarm(deadline, [alarmInfo, waiterThreadId, &invokedAlarmInline] {
- stdx::lock_guard<stdx::mutex> controlLk(alarmInfo->controlMutex);
- alarmInfo->cvWaitResult = stdx::cv_status::timeout;
- if (!alarmInfo->waitMutex) {
- return;
- }
- if (stdx::this_thread::get_id() == waiterThreadId) {
- // In NetworkInterfaceMock, setAlarm may invoke its callback immediately if the deadline
- // has expired, so we detect that case and avoid self-deadlock by returning early, here.
- // It is safe to set invokedAlarmInline without synchronization in this case, because it
- // is exactly the case where the same thread is writing and consulting the value.
- invokedAlarmInline = true;
- return;
- }
- stdx::lock_guard<stdx::mutex> waitLk(*alarmInfo->waitMutex);
- alarmInfo->waitCV->notify_all();
- }));
- if (!invokedAlarmInline) {
- cv.wait(m);
- }
- m.unlock();
- stdx::lock_guard<stdx::mutex> controlLk(alarmInfo->controlMutex);
- m.lock();
- alarmInfo->waitMutex = nullptr;
- alarmInfo->waitCV = nullptr;
- return alarmInfo->cvWaitResult;
-}
-
// Theory of operation for waitForConditionOrInterruptNoAssertUntil and markKilled:
//
// An operation indicates to potential killers that it is waiting on a condition variable by setting
@@ -344,14 +297,7 @@ StatusWith<stdx::cv_status> OperationContext::waitForConditionOrInterruptNoAsser
cv.wait(m);
return stdx::cv_status::no_timeout;
}
- const auto clockSource = getServiceContext()->getPreciseClockSource();
- if (clockSource->tracksSystemClock()) {
- return cv.wait_until(m, deadline.toSystemTimePoint());
- }
-
- // The following cases only occur during testing, when the precise clock source is
- // virtualized and does not track the system clock.
- return cvWaitUntilWithClockSource(clockSource, cv, m, deadline);
+ return getServiceContext()->getPreciseClockSource()->waitForConditionUntil(cv, m, deadline);
}();
// Continue waiting on cv until no other thread is attempting to kill this one.