Index: base/waitable_event_posix.cc |
=================================================================== |
--- base/waitable_event_posix.cc (revision 23711) |
+++ base/waitable_event_posix.cc (working copy) |
@@ -76,36 +76,37 @@ |
// Synchronous waits |
// ----------------------------------------------------------------------------- |
-// This is an synchronous waiter. The thread is waiting on the given condition |
+// This is a synchronous waiter. The thread is waiting on the given condition |
// variable and the fired flag in this object. |
// ----------------------------------------------------------------------------- |
class SyncWaiter : public WaitableEvent::Waiter { |
public: |
- SyncWaiter(ConditionVariable* cv, Lock* lock) |
+ SyncWaiter() |
: fired_(false), |
- cv_(cv), |
- lock_(lock), |
- signaling_event_(NULL) { |
+ signaling_event_(NULL), |
+ lock_(), |
agl
2009/08/19 17:35:35
Isn't this line a no-op?
|
+ cv_(&lock_) { |
} |
- bool Fire(WaitableEvent *signaling_event) { |
- lock_->Acquire(); |
- const bool previous_value = fired_; |
- fired_ = true; |
- if (!previous_value) |
- signaling_event_ = signaling_event; |
- lock_->Release(); |
+ bool Fire(WaitableEvent* signaling_event) { |
+ AutoLock locked(lock_); |
- if (previous_value) |
+ if (fired_) |
return false; |
- cv_->Broadcast(); |
+ fired_ = true; |
+ signaling_event_ = signaling_event; |
- // SyncWaiters are stack allocated on the stack of the blocking thread. |
+ cv_.Broadcast(); |
+ |
+ // Unlike AsyncWaiter objects, SyncWaiter objects are stack-allocated on |
+ // the blocking thread's stack. There is no |delete this;| in Fire. The |
+ // SyncWaiter object is destroyed when it goes out of scope. |
+ |
return true; |
} |
- WaitableEvent* signaled_event() const { |
+ WaitableEvent* signaling_event() const { |
return signaling_event_; |
} |
@@ -133,11 +134,19 @@ |
fired_ = true; |
} |
+ Lock* lock() { |
+ return &lock_; |
+ } |
+ |
+ ConditionVariable* cv() { |
+ return &cv_; |
+ } |
+ |
private: |
bool fired_; |
- ConditionVariable *const cv_; |
- Lock *const lock_; |
WaitableEvent* signaling_event_; // The WaitableEvent which woke us |
+ Lock lock_; |
+ ConditionVariable cv_; |
}; |
bool WaitableEvent::TimedWait(const TimeDelta& max_time) { |
@@ -156,10 +165,8 @@ |
return true; |
} |
- Lock lock; |
- lock.Acquire(); |
- ConditionVariable cv(&lock); |
- SyncWaiter sw(&cv, &lock); |
+ SyncWaiter sw; |
+ sw.lock()->Acquire(); |
Enqueue(&sw); |
kernel_->lock_.Release(); |
@@ -173,13 +180,13 @@ |
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. |
+ // We can't acquire @lock_ before releasing the SyncWaiter lock (because |
+ // of locking order), however, in between 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(); |
+ sw.lock()->Release(); |
kernel_->lock_.Acquire(); |
kernel_->Dequeue(&sw, &sw); |
@@ -190,9 +197,9 @@ |
if (finite_time) { |
const TimeDelta max_wait(end_time - current_time); |
- cv.TimedWait(max_wait); |
+ sw.cv()->TimedWait(max_wait); |
} else { |
- cv.Wait(); |
+ sw.cv()->Wait(); |
} |
} |
} |
@@ -237,9 +244,7 @@ |
DCHECK(waitables[i].first != waitables[i+1].first); |
} |
- Lock lock; |
- ConditionVariable cv(&lock); |
- SyncWaiter sw(&cv, &lock); |
+ SyncWaiter sw; |
const size_t r = EnqueueMany(&waitables[0], count, &sw); |
if (r) { |
@@ -252,7 +257,7 @@ |
// At this point, we hold the locks on all the WaitableEvents and we have |
// enqueued our waiter in them all. |
- lock.Acquire(); |
+ sw.lock()->Acquire(); |
// Release the WaitableEvent locks in the reverse order |
for (size_t i = 0; i < count; ++i) { |
waitables[count - (1 + i)].first->kernel_->lock_.Release(); |
@@ -262,12 +267,12 @@ |
if (sw.fired()) |
break; |
- cv.Wait(); |
+ sw.cv()->Wait(); |
} |
- lock.Release(); |
+ sw.lock()->Release(); |
// The address of the WaitableEvent which fired is stored in the SyncWaiter. |
- WaitableEvent *const signaled_event = sw.signaled_event(); |
+ WaitableEvent *const signaled_event = sw.signaling_event(); |
// This will store the index of the raw_waitables which fired. |
size_t signaled_index = 0; |