diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-16 00:25:11 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-16 00:25:11 +0000 |
commit | cc2aa4193b5dbf3d4edeb4d3c33c94733c0b81d9 (patch) | |
tree | 24da027ee50590b54bae705e9566f92961a31b8a /base/waitable_event_posix.cc | |
parent | 075b9d39315fee5a08e7397d62db1441ee18e157 (diff) | |
download | chromium_src-cc2aa4193b5dbf3d4edeb4d3c33c94733c0b81d9.zip chromium_src-cc2aa4193b5dbf3d4edeb4d3c33c94733c0b81d9.tar.gz chromium_src-cc2aa4193b5dbf3d4edeb4d3c33c94733c0b81d9.tar.bz2 |
Mac/Linux test fixes: hopefully this will fix some flakey tests
Review URL: http://codereview.chromium.org/18298
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8143 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/waitable_event_posix.cc')
-rw-r--r-- | base/waitable_event_posix.cc | 54 |
1 files changed, 29 insertions, 25 deletions
diff --git a/base/waitable_event_posix.cc b/base/waitable_event_posix.cc index 335f13e..09e2868 100644 --- a/base/waitable_event_posix.cc +++ b/base/waitable_event_posix.cc @@ -35,13 +35,16 @@ namespace base { // This is just an abstract base class for waking the two types of waiters // ----------------------------------------------------------------------------- WaitableEvent::WaitableEvent(bool manual_reset, bool initially_signaled) - : signaled_(false), + : signaled_(initially_signaled), manual_reset_(manual_reset) { - DCHECK(!initially_signaled) << "Not implemented"; } WaitableEvent::~WaitableEvent() { - DCHECK(waiters_.empty()) << "Deleting WaitableEvent with listeners!"; + if (!waiters_.empty()) { + LOG(ERROR) << "Destroying a WaitableEvent (" << this << ") with " + << waiters_.size() << " waiters"; + NOTREACHED() << "Aborting."; + } } void WaitableEvent::Reset() { @@ -88,7 +91,8 @@ class SyncWaiter : public WaitableEvent::Waiter { : fired_(false), cv_(cv), lock_(lock), - signaling_event_(NULL) { } + signaling_event_(NULL) { + } bool Fire(WaitableEvent *signaling_event) { lock_->Acquire(); @@ -144,6 +148,7 @@ class SyncWaiter : public WaitableEvent::Waiter { bool WaitableEvent::TimedWait(const TimeDelta& max_time) { const Time end_time(Time::Now() + max_time); + const bool finite_time = max_time.ToInternalValue() >= 0; lock_.Acquire(); if (signaled_) { @@ -169,32 +174,31 @@ bool WaitableEvent::TimedWait(const TimeDelta& max_time) { // again before unlocking it. for (;;) { - if (sw.fired()) { + const Time current_time(Time::Now()); + + if (sw.fired() || (finite_time && current_time >= end_time)) { + const bool return_value = sw.fired(); + + // We can't acquire @lock_ before releasing @lock (because of locking + // order), however, inbetween the two a signal could be fired and @sw + // would accept it, however we will still return false, so the signal + // would be lost on an auto-reset WaitableEvent. Thus we call Disable + // which makes sw::Fire return false. + sw.Disable(); lock.Release(); - return true; + + lock_.Acquire(); + Dequeue(&sw, &sw); + lock_.Release(); + + return return_value; } - if (max_time.ToInternalValue() < 0) { - cv.Wait(); - } else { - const Time current_time(Time::Now()); - if (current_time >= end_time) { - // We can't acquire @lock_ before releasing @lock (because of locking - // order), however, inbetween the two a signal could be fired and @sw - // would accept it, however we will still return false, so the signal - // would be lost on an auto-reset WaitableEvent. Thus we call Disable - // which makes sw::Fire return false. - sw.Disable(); - lock.Release(); - - lock_.Acquire(); - Dequeue(&sw, &sw); - lock_.Release(); - return false; - } + if (finite_time) { const TimeDelta max_wait(end_time - current_time); - cv.TimedWait(max_wait); + } else { + cv.Wait(); } } } |