Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2835)

Unified Diff: base/synchronization/waitable_event_posix.cc

Issue 2761993004: Revert of Ensure consistent return ordering in base::WaitableEvent::WaitMany (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/synchronization/waitable_event.h ('k') | base/synchronization/waitable_event_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/synchronization/waitable_event_posix.cc
diff --git a/base/synchronization/waitable_event_posix.cc b/base/synchronization/waitable_event_posix.cc
index 846fa06700e1dcb1c1c5976eb2397643c0698759..5dfff468ad6acb0f2c81df98bcc31564f7029506 100644
--- a/base/synchronization/waitable_event_posix.cc
+++ b/base/synchronization/waitable_event_posix.cc
@@ -5,7 +5,6 @@
#include <stddef.h>
#include <algorithm>
-#include <limits>
#include <vector>
#include "base/debug/activity_tracker.h"
@@ -267,10 +266,12 @@
SyncWaiter sw;
const size_t r = EnqueueMany(&waitables[0], count, &sw);
- if (r < count) {
+ if (r) {
// One of the events is already signaled. The SyncWaiter has not been
- // enqueued anywhere.
- return waitables[r].second;
+ // enqueued anywhere. EnqueueMany returns the count of remaining waitables
+ // when the signaled one was seen, so the index of the signaled event is
+ // @count - @r.
+ return waitables[count - r].second;
}
// At this point, we hold the locks on all the WaitableEvents and we have
@@ -318,50 +319,38 @@
}
// -----------------------------------------------------------------------------
-// If return value == count:
+// If return value == 0:
// The locks of the WaitableEvents have been taken in order and the Waiter has
// been enqueued in the wait-list of each. None of the WaitableEvents are
// currently signaled
// else:
// None of the WaitableEvent locks are held. The Waiter has not been enqueued
-// in any of them and the return value is the index of the WaitableEvent which
-// was signaled with the lowest input index from the original WaitMany call.
+// in any of them and the return value is the index of the first WaitableEvent
+// which was signaled, from the end of the array.
// -----------------------------------------------------------------------------
// static
-size_t WaitableEvent::EnqueueMany(std::pair<WaitableEvent*, size_t>* waitables,
- size_t count,
- Waiter* waiter) {
- size_t winner = count;
- size_t winner_index = count;
- for (size_t i = 0; i < count; ++i) {
- auto& kernel = waitables[i].first->kernel_;
- kernel->lock_.Acquire();
- if (kernel->signaled_ && waitables[i].second < winner) {
- winner = waitables[i].second;
- winner_index = i;
- }
- }
-
- // No events signaled. All locks acquired. Enqueue the Waiter on all of them
- // and return.
- if (winner == count) {
- for (size_t i = 0; i < count; ++i)
- waitables[i].first->Enqueue(waiter);
- return count;
- }
-
- // Unlock in reverse order and possibly clear the chosen winner's signal
- // before returning its index.
- for (auto* w = waitables + count - 1; w >= waitables; --w) {
- auto& kernel = w->first->kernel_;
- if (w->second == winner) {
- if (!kernel->manual_reset_)
- kernel->signaled_ = false;
- }
- kernel->lock_.Release();
- }
-
- return winner_index;
+size_t WaitableEvent::EnqueueMany
+ (std::pair<WaitableEvent*, size_t>* waitables,
+ size_t count, Waiter* waiter) {
+ if (!count)
+ return 0;
+
+ waitables[0].first->kernel_->lock_.Acquire();
+ if (waitables[0].first->kernel_->signaled_) {
+ if (!waitables[0].first->kernel_->manual_reset_)
+ waitables[0].first->kernel_->signaled_ = false;
+ waitables[0].first->kernel_->lock_.Release();
+ return count;
+ }
+
+ const size_t r = EnqueueMany(waitables + 1, count - 1, waiter);
+ if (r) {
+ waitables[0].first->kernel_->lock_.Release();
+ } else {
+ waitables[0].first->Enqueue(waiter);
+ }
+
+ return r;
}
// -----------------------------------------------------------------------------
« no previous file with comments | « base/synchronization/waitable_event.h ('k') | base/synchronization/waitable_event_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698