| Index: base/synchronization/waitable_event_posix.cc
|
| diff --git a/base/synchronization/waitable_event_posix.cc b/base/synchronization/waitable_event_posix.cc
|
| index fccba9d31c67c767b0b8172e10ad127ab2a5cb24..15d101a4f92a7c90a89a5682d027f68727b49c97 100644
|
| --- a/base/synchronization/waitable_event_posix.cc
|
| +++ b/base/synchronization/waitable_event_posix.cc
|
| @@ -197,6 +197,11 @@ bool WaitableEvent::TimedWait(const TimeDelta& max_time) {
|
| sw.Disable();
|
| sw.lock()->Release();
|
|
|
| + // This is a bug that has been enshrined in the interface of
|
| + // WaitableEvent now: |Dequeue| is called even when |sw.fired()| is true,
|
| + // even though it'll always return false in that case. However, taking
|
| + // the lock ensures that |Signal| has completed before we return and
|
| + // means that a WaitableEvent can synchronise its own destruction.
|
| kernel_->lock_.Acquire();
|
| kernel_->Dequeue(&sw, &sw);
|
| kernel_->lock_.Release();
|
| @@ -290,6 +295,10 @@ size_t WaitableEvent::WaitMany(WaitableEvent** raw_waitables,
|
| raw_waitables[i]->kernel_->Dequeue(&sw, &sw);
|
| raw_waitables[i]->kernel_->lock_.Release();
|
| } else {
|
| + // By taking this lock here we ensure that |Signal| has completed by the
|
| + // time we return. This matches the behaviour of |Wait| and |TimedWait|.
|
| + raw_waitables[i]->kernel_->lock_.Acquire();
|
| + raw_waitables[i]->kernel_->lock_.Release();
|
| signaled_index = i;
|
| }
|
| }
|
|
|