summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndy Schwerin <Andy Schwerin schwerin@mongodb.com>2017-02-09 23:43:15 -0500
committerAndy Schwerin <Andy Schwerin schwerin@mongodb.com>2017-03-15 13:37:27 -0400
commit1515d4e4e2613e79b2c1761b7505cfaa9c31f0a9 (patch)
treecc067362d65a4082d62482f90dc65f94f3115bad /src
parent10c9d67de63a38249fca0234208660af8b45f12b (diff)
downloadmongo-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.cpp6
-rw-r--r--src/mongo/db/operation_context.h20
-rw-r--r--src/mongo/db/operation_context_test.cpp77
-rw-r--r--src/mongo/db/s/operation_sharding_state.cpp4
-rw-r--r--src/mongo/util/concurrency/notification.h10
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);
}