diff options
author | Andy Schwerin <Andy Schwerin schwerin@mongodb.com> | 2017-02-09 23:43:15 -0500 |
---|---|---|
committer | Andy Schwerin <Andy Schwerin schwerin@mongodb.com> | 2017-03-15 13:37:27 -0400 |
commit | 1515d4e4e2613e79b2c1761b7505cfaa9c31f0a9 (patch) | |
tree | cc067362d65a4082d62482f90dc65f94f3115bad /src | |
parent | 10c9d67de63a38249fca0234208660af8b45f12b (diff) | |
download | mongo-1515d4e4e2613e79b2c1761b7505cfaa9c31f0a9.tar.gz |
SERVER-25062 Fix return types of predicated waits and notification waitFor.
This patch makes the return types of predicated waits on condition variables
and Notification::waitFor look more like the corresponding functions in C++
standard types.
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/operation_context.cpp | 6 | ||||
-rw-r--r-- | src/mongo/db/operation_context.h | 20 | ||||
-rw-r--r-- | src/mongo/db/operation_context_test.cpp | 77 | ||||
-rw-r--r-- | src/mongo/db/s/operation_sharding_state.cpp | 4 | ||||
-rw-r--r-- | src/mongo/util/concurrency/notification.h | 10 |
5 files changed, 56 insertions, 61 deletions
diff --git a/src/mongo/db/operation_context.cpp b/src/mongo/db/operation_context.cpp index d0cb8e244ad..0950c620280 100644 --- a/src/mongo/db/operation_context.cpp +++ b/src/mongo/db/operation_context.cpp @@ -214,16 +214,14 @@ void OperationContext::sleepUntil(Date_t deadline) { stdx::mutex m; stdx::condition_variable cv; stdx::unique_lock<stdx::mutex> lk(m); - invariant(stdx::cv_status::timeout == - waitForConditionOrInterruptUntil(cv, lk, deadline, [] { return false; })); + invariant(!waitForConditionOrInterruptUntil(cv, lk, deadline, [] { return false; })); } void OperationContext::sleepFor(Milliseconds duration) { stdx::mutex m; stdx::condition_variable cv; stdx::unique_lock<stdx::mutex> lk(m); - invariant(stdx::cv_status::timeout == - waitForConditionOrInterruptFor(cv, lk, duration, [] { return false; })); + invariant(!waitForConditionOrInterruptFor(cv, lk, duration, [] { return false; })); } void OperationContext::waitForConditionOrInterrupt(stdx::condition_variable& cv, diff --git a/src/mongo/db/operation_context.h b/src/mongo/db/operation_context.h index 87c0f159a7f..54be41d5e29 100644 --- a/src/mongo/db/operation_context.h +++ b/src/mongo/db/operation_context.h @@ -203,16 +203,16 @@ public: * cv_status::no_timeout indicating that "pred" finally returned true. */ template <typename Pred> - stdx::cv_status waitForConditionOrInterruptUntil(stdx::condition_variable& cv, - stdx::unique_lock<stdx::mutex>& m, - Date_t deadline, - Pred pred) { + bool waitForConditionOrInterruptUntil(stdx::condition_variable& cv, + stdx::unique_lock<stdx::mutex>& m, + Date_t deadline, + Pred pred) { while (!pred()) { if (stdx::cv_status::timeout == waitForConditionOrInterruptUntil(cv, m, deadline)) { - return stdx::cv_status::timeout; + return pred(); } } - return stdx::cv_status::no_timeout; + return true; } /** @@ -220,10 +220,10 @@ public: * amount of time to wait instead of an absolute time point. */ template <typename Pred> - stdx::cv_status waitForConditionOrInterruptFor(stdx::condition_variable& cv, - stdx::unique_lock<stdx::mutex>& m, - Milliseconds duration, - Pred pred) { + bool waitForConditionOrInterruptFor(stdx::condition_variable& cv, + stdx::unique_lock<stdx::mutex>& m, + Milliseconds duration, + Pred pred) { return waitForConditionOrInterruptUntil( cv, m, getExpirationDateForWaitForValue(duration), pred); } diff --git a/src/mongo/db/operation_context_test.cpp b/src/mongo/db/operation_context_test.cpp index 46f7bc04772..3592e4dd3c1 100644 --- a/src/mongo/db/operation_context_test.cpp +++ b/src/mongo/db/operation_context_test.cpp @@ -206,9 +206,8 @@ TEST_F(OperationDeadlineTests, WaitForDurationExpired) { stdx::mutex m; stdx::condition_variable cv; stdx::unique_lock<stdx::mutex> lk(m); - ASSERT(stdx::cv_status::timeout == - opCtx->waitForConditionOrInterruptFor( - cv, lk, Milliseconds(-1000), []() -> bool { return false; })); + ASSERT_FALSE(opCtx->waitForConditionOrInterruptFor( + cv, lk, Milliseconds(-1000), []() -> bool { return false; })); } TEST_F(OperationDeadlineTests, DuringWaitMaxTimeExpirationDominatesUntilExpiration) { @@ -224,7 +223,7 @@ TEST_F(OperationDeadlineTests, DuringWaitMaxTimeExpirationDominatesUntilExpirati class ThreadedOperationDeadlineTests : public OperationDeadlineTests { public: using CvPred = stdx::function<bool()>; - using WaitFn = stdx::function<stdx::cv_status( + using WaitFn = stdx::function<bool( OperationContext*, stdx::condition_variable&, stdx::unique_lock<stdx::mutex>&, CvPred)>; struct WaitTestState { @@ -240,13 +239,13 @@ public: bool isSignaled = false; }; - stdx::future<stdx::cv_status> startWaiterWithMaxTime(OperationContext* opCtx, - WaitTestState* state, - WaitFn waitFn, - Date_t maxTime) { + stdx::future<bool> startWaiterWithMaxTime(OperationContext* opCtx, + WaitTestState* state, + WaitFn waitFn, + Date_t maxTime) { auto barrier = std::make_shared<unittest::Barrier>(2); - auto task = stdx::packaged_task<stdx::cv_status()>([=] { + auto task = stdx::packaged_task<bool()>([=] { if (maxTime < Date_t::max()) { opCtx->setDeadlineByDate(maxTime); } @@ -270,10 +269,10 @@ public: return result; } - stdx::future<stdx::cv_status> startWaiterWithUntilAndMaxTime(OperationContext* opCtx, - WaitTestState* state, - Date_t until, - Date_t maxTime) { + stdx::future<bool> startWaiterWithUntilAndMaxTime(OperationContext* opCtx, + WaitTestState* state, + Date_t until, + Date_t maxTime) { const auto waitFn = [until](OperationContext* opCtx, stdx::condition_variable& cv, stdx::unique_lock<stdx::mutex>& lk, @@ -282,17 +281,17 @@ public: return opCtx->waitForConditionOrInterruptUntil(cv, lk, until, predicate); } else { opCtx->waitForConditionOrInterrupt(cv, lk, predicate); - return stdx::cv_status::no_timeout; + return true; } }; return startWaiterWithMaxTime(opCtx, state, waitFn, maxTime); } template <typename Period> - stdx::future<stdx::cv_status> startWaiterWithDurationAndMaxTime(OperationContext* opCtx, - WaitTestState* state, - Duration<Period> duration, - Date_t maxTime) { + stdx::future<bool> startWaiterWithDurationAndMaxTime(OperationContext* opCtx, + WaitTestState* state, + Duration<Period> duration, + Date_t maxTime) { const auto waitFn = [duration](OperationContext* opCtx, stdx::condition_variable& cv, stdx::unique_lock<stdx::mutex>& lk, @@ -302,14 +301,14 @@ public: return startWaiterWithMaxTime(opCtx, state, waitFn, maxTime); } - stdx::future<stdx::cv_status> startWaiter(OperationContext* opCtx, WaitTestState* state) { + stdx::future<bool> startWaiter(OperationContext* opCtx, WaitTestState* state) { return startWaiterWithUntilAndMaxTime(opCtx, state, Date_t::max(), Date_t::max()); } - stdx::future<stdx::cv_status> startWaiterWithSleepUntilAndMaxTime(OperationContext* opCtx, - WaitTestState* state, - Date_t sleepUntil, - Date_t maxTime) { + stdx::future<bool> startWaiterWithSleepUntilAndMaxTime(OperationContext* opCtx, + WaitTestState* state, + Date_t sleepUntil, + Date_t maxTime) { auto waitFn = [sleepUntil](OperationContext* opCtx, stdx::condition_variable& cv, stdx::unique_lock<stdx::mutex>& lk, @@ -317,16 +316,16 @@ public: lk.unlock(); opCtx->sleepUntil(sleepUntil); lk.lock(); - return stdx::cv_status::timeout; + return false; }; return startWaiterWithMaxTime(opCtx, state, waitFn, maxTime); } template <typename Period> - stdx::future<stdx::cv_status> startWaiterWithSleepForAndMaxTime(OperationContext* opCtx, - WaitTestState* state, - Duration<Period> sleepFor, - Date_t maxTime) { + stdx::future<bool> startWaiterWithSleepForAndMaxTime(OperationContext* opCtx, + WaitTestState* state, + Duration<Period> sleepFor, + Date_t maxTime) { auto waitFn = [sleepFor](OperationContext* opCtx, stdx::condition_variable& cv, stdx::unique_lock<stdx::mutex>& lk, @@ -334,7 +333,7 @@ public: lk.unlock(); opCtx->sleepFor(sleepFor); lk.lock(); - return stdx::cv_status::timeout; + return false; }; return startWaiterWithMaxTime(opCtx, state, waitFn, maxTime); } @@ -386,7 +385,7 @@ TEST_F(ThreadedOperationDeadlineTests, UntilExpiresWhileWaiting) { ASSERT(stdx::future_status::ready != waiterResult.wait_for(Milliseconds::zero().toSystemDuration())); mockClock->advance(Seconds{2}); - ASSERT(stdx::cv_status::timeout == waiterResult.get()); + ASSERT_FALSE(waiterResult.get()); } TEST_F(ThreadedOperationDeadlineTests, ForExpiresWhileWaiting) { @@ -402,7 +401,7 @@ TEST_F(ThreadedOperationDeadlineTests, ForExpiresWhileWaiting) { ASSERT(stdx::future_status::ready != waiterResult.wait_for(Milliseconds::zero().toSystemDuration())); mockClock->advance(Seconds{2}); - ASSERT(stdx::cv_status::timeout == waiterResult.get()); + ASSERT_FALSE(waiterResult.get()); } TEST_F(ThreadedOperationDeadlineTests, SignalOne) { @@ -414,7 +413,7 @@ TEST_F(ThreadedOperationDeadlineTests, SignalOne) { waiterResult.wait_for(Milliseconds::zero().toSystemDuration())) << waiterResult.get(); state.signal(); - ASSERT(stdx::cv_status::no_timeout == waiterResult.get()); + ASSERT_TRUE(waiterResult.get()); } TEST_F(ThreadedOperationDeadlineTests, KillOneSignalAnother) { @@ -438,7 +437,7 @@ TEST_F(ThreadedOperationDeadlineTests, KillOneSignalAnother) { ASSERT(stdx::future_status::ready != waiterResult2.wait_for(Milliseconds::zero().toSystemDuration())); state2.signal(); - ASSERT(stdx::cv_status::no_timeout == waiterResult2.get()); + ASSERT_TRUE(waiterResult2.get()); } TEST_F(ThreadedOperationDeadlineTests, SignalBeforeUntilExpires) { @@ -456,7 +455,7 @@ TEST_F(ThreadedOperationDeadlineTests, SignalBeforeUntilExpires) { ASSERT(stdx::future_status::ready != waiterResult.wait_for(Milliseconds::zero().toSystemDuration())); state.signal(); - ASSERT(stdx::cv_status::no_timeout == waiterResult.get()); + ASSERT_TRUE(waiterResult.get()); } TEST_F(ThreadedOperationDeadlineTests, SignalBeforeMaxTimeExpires) { @@ -474,7 +473,7 @@ TEST_F(ThreadedOperationDeadlineTests, SignalBeforeMaxTimeExpires) { ASSERT(stdx::future_status::ready != waiterResult.wait_for(Milliseconds::zero().toSystemDuration())); state.signal(); - ASSERT(stdx::cv_status::no_timeout == waiterResult.get()); + ASSERT_TRUE(waiterResult.get()); } TEST_F(ThreadedOperationDeadlineTests, SleepUntilWithExpiredUntilDoesNotBlock) { @@ -485,7 +484,7 @@ TEST_F(ThreadedOperationDeadlineTests, SleepUntilWithExpiredUntilDoesNotBlock) { &state, startDate - Seconds{10}, // until startDate + Seconds{60}); // maxTime - ASSERT(stdx::cv_status::timeout == waiterResult.get()); + ASSERT_FALSE(waiterResult.get()); } TEST_F(ThreadedOperationDeadlineTests, SleepUntilExpires) { @@ -502,7 +501,7 @@ TEST_F(ThreadedOperationDeadlineTests, SleepUntilExpires) { ASSERT(stdx::future_status::ready != waiterResult.wait_for(Milliseconds::zero().toSystemDuration())); mockClock->advance(Seconds{2}); - ASSERT(stdx::cv_status::timeout == waiterResult.get()); + ASSERT_FALSE(waiterResult.get()); } TEST_F(ThreadedOperationDeadlineTests, SleepForWithExpiredForDoesNotBlock) { @@ -511,7 +510,7 @@ TEST_F(ThreadedOperationDeadlineTests, SleepForWithExpiredForDoesNotBlock) { const auto startDate = mockClock->now(); auto waiterResult = startWaiterWithSleepForAndMaxTime( opCtx.get(), &state, Seconds{-10}, startDate + Seconds{60}); // maxTime - ASSERT(stdx::cv_status::timeout == waiterResult.get()); + ASSERT_FALSE(waiterResult.get()); } TEST_F(ThreadedOperationDeadlineTests, SleepForExpires) { @@ -526,7 +525,7 @@ TEST_F(ThreadedOperationDeadlineTests, SleepForExpires) { ASSERT(stdx::future_status::ready != waiterResult.wait_for(Milliseconds::zero().toSystemDuration())); mockClock->advance(Seconds{2}); - ASSERT(stdx::cv_status::timeout == waiterResult.get()); + ASSERT_FALSE(waiterResult.get()); } } // namespace diff --git a/src/mongo/db/s/operation_sharding_state.cpp b/src/mongo/db/s/operation_sharding_state.cpp index fc13bf41287..4b8e6304111 100644 --- a/src/mongo/db/s/operation_sharding_state.cpp +++ b/src/mongo/db/s/operation_sharding_state.cpp @@ -40,7 +40,7 @@ const OperationContext::Decoration<OperationShardingState> shardingMetadataDecor OperationContext::declareDecoration<OperationShardingState>(); // Max time to wait for the migration critical section to complete -const Microseconds kMaxWaitForMigrationCriticalSection = Minutes(5); +const Milliseconds kMaxWaitForMigrationCriticalSection = Minutes(5); } // namespace @@ -109,7 +109,7 @@ bool OperationShardingState::waitForMigrationCriticalSectionSignal(OperationCont _migrationCriticalSectionSignal->waitFor( opCtx, opCtx->hasDeadline() - ? std::min(opCtx->getRemainingMaxTimeMicros(), kMaxWaitForMigrationCriticalSection) + ? std::min(opCtx->getRemainingMaxTimeMillis(), kMaxWaitForMigrationCriticalSection) : kMaxWaitForMigrationCriticalSection); _migrationCriticalSectionSignal = nullptr; return true; diff --git a/src/mongo/util/concurrency/notification.h b/src/mongo/util/concurrency/notification.h index 091dca02a60..aa8df252110 100644 --- a/src/mongo/util/concurrency/notification.h +++ b/src/mongo/util/concurrency/notification.h @@ -100,12 +100,10 @@ public: * If the notification is not set, blocks either until it becomes set or until the waitTimeout * expires. If the wait is interrupted, throws an exception. Otherwise, returns immediately. */ - bool waitFor(OperationContext* opCtx, Microseconds waitTimeout) { - const auto waitDeadline = Date_t::now() + waitTimeout; - + bool waitFor(OperationContext* opCtx, Milliseconds waitTimeout) { stdx::unique_lock<stdx::mutex> lock(_mutex); - return _condVar.wait_until( - lock, waitDeadline.toSystemTimePoint(), [&]() { return !!_value; }); + return opCtx->waitForConditionOrInterruptFor( + _condVar, lock, waitTimeout, [&]() { return !!_value; }); } private: @@ -135,7 +133,7 @@ public: _notification.set(true); } - bool waitFor(OperationContext* opCtx, Microseconds waitTimeout) { + bool waitFor(OperationContext* opCtx, Milliseconds waitTimeout) { return _notification.waitFor(opCtx, waitTimeout); } |