Skip to content

Commit

Permalink
Merge pull request #952 from leapmotion/feature-optimistic
Browse files Browse the repository at this point in the history
Use optimistic behavior in Barrier
  • Loading branch information
jhe- committed May 23, 2016
2 parents 6eb4f66 + c9988a0 commit 3a64e9f
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 11 deletions.
14 changes: 5 additions & 9 deletions src/autowiring/DispatchQueue.cpp
Expand Up @@ -281,21 +281,17 @@ void DispatchQueue::PendExisting(std::unique_lock<std::mutex>&& lk, DispatchThun
}

bool DispatchQueue::Barrier(std::chrono::nanoseconds timeout) {
// Optimistic check first:
// Do not block or lock in the event of a no-wait check
if (timeout.count() == 0)
return m_count == 0;

// Now lock and double-check:
std::unique_lock<std::mutex> lk(m_dispatchLock);

// Short-circuit if dispatching has been aborted
if (onAborted)
throw dispatch_aborted_exception("Dispatch queue was aborted before a timed wait was attempted");

// Short-circuit if the queue is already empty
if (!m_count)
return true;

// Also short-circuit if zero is specified as the timeout value
if (timeout.count() == 0)
return false;

// Set up the lambda. Note that the queue size CANNOT be 1, because we just checked to verify
// that it is non-empty. Thus, we do not need to signal the m_queueUpdated condition variable.
auto complete = std::make_shared<bool>(false);
Expand Down
11 changes: 9 additions & 2 deletions src/autowiring/DispatchQueue.h
Expand Up @@ -247,17 +247,24 @@ class DispatchQueue {
/// <summary>
/// Blocks until all dispatchers on the DispatchQueue at the time of the call have been dispatched
/// </summary>
/// <param name="timeout">The maximum amount of time to wait</param>
/// <param name="timeout">
/// The maximum amount of time to wait. If this value is zero, this method will not wait.
/// </param>
/// <remarks>
/// This method does not cause any dispatchers to run. If the underlying dispatch queue does not have an event loop
/// operating on it, this method will deadlock. It is an error for the party responsible for driving the dispatch queue
/// via WaitForEvent or DispatchAllEvents unless that party first delegates the responsibility elsewhere.
/// via WaitForEvent or DispatchAllEvents to call this method unless that party first delegates the responsibility
/// elsewhere.
///
/// If DispatchQueue::Abort() is called before the dispatcher has been completed, this method will throw an exception.
/// If a dispatcher on the underlying DispatchQueue throws an exception, this method will also throw an exception.
///
/// If zero is passed as the timeout value, this method will return true if and only if the queue was empty at the time
/// of the call, ignoring any delayed dispatchers.
///
/// If timeout is nonzero, this method will pend a dispatcher to the queue and only return true if this dispatcher
/// is actually dispatched. If the timeout is zero, this method will return true immediately if the queue length
/// is exactly zero.
/// </remarks>
bool Barrier(std::chrono::nanoseconds timeout);

Expand Down

0 comments on commit 3a64e9f

Please sign in to comment.