From cb47b58ae27a4f21af65af4836d2bd806ebbd13d Mon Sep 17 00:00:00 2001 From: Jason Lokerson Date: Wed, 1 Apr 2015 22:46:02 -0700 Subject: [PATCH] Add timeout-free Barrier variant This `Barrier` variant is identical to the timed version, except that it does not time out. --- autowiring/DispatchQueue.h | 5 +++++ src/autowiring/DispatchQueue.cpp | 15 +++++++++++++++ src/autowiring/test/DispatchQueueTest.cpp | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/autowiring/DispatchQueue.h b/autowiring/DispatchQueue.h index f4c43ce42..c024699e7 100644 --- a/autowiring/DispatchQueue.h +++ b/autowiring/DispatchQueue.h @@ -200,6 +200,11 @@ class DispatchQueue { /// bool Barrier(std::chrono::nanoseconds timeout); + /// + /// Identical to the timed version of Barrier, but does not time out + /// + void Barrier(void); + /// /// Recommends a point in time to wake up to check for events /// diff --git a/src/autowiring/DispatchQueue.cpp b/src/autowiring/DispatchQueue.cpp index 5cfe6625d..6ac978a95 100644 --- a/src/autowiring/DispatchQueue.cpp +++ b/src/autowiring/DispatchQueue.cpp @@ -193,6 +193,21 @@ bool DispatchQueue::Barrier(std::chrono::nanoseconds timeout) { return rv; } +void DispatchQueue::Barrier(void) { + // Set up the lambda: + bool complete = false; + *this += [&] { complete = true; }; + + // Obtain the lock, wait until our variable is satisfied, which might be right away: + std::unique_lock lk(m_dispatchLock); + m_queueUpdated.wait(lk, [&] { return m_aborted || complete; }); + if (m_aborted) + // At this point, the dispatch queue MUST be completely run down. We have no outstanding references + // to our stack-allocated "complete" variable. Furthermore, after m_aborted is true, no further + // dispatchers are permitted to be run. + throw autowiring_error("Dispatch queue was aborted while a barrier was invoked"); +} + std::chrono::steady_clock::time_point DispatchQueue::SuggestSoonestWakeupTimeUnsafe(std::chrono::steady_clock::time_point latestTime) const { return diff --git a/src/autowiring/test/DispatchQueueTest.cpp b/src/autowiring/test/DispatchQueueTest.cpp index b07211835..19faea4c3 100644 --- a/src/autowiring/test/DispatchQueueTest.cpp +++ b/src/autowiring/test/DispatchQueueTest.cpp @@ -129,4 +129,4 @@ TEST_F(DispatchQueueTest, BarrierWithAbort) { ct->Abort(); ASSERT_EQ(std::future_status::ready, f.wait_for(std::chrono::seconds(5))) << "Barrier did not abort fast enough"; ASSERT_TRUE(*exception) << "Exception should have been thrown inside the Barrier call"; -} \ No newline at end of file +}