Index: base/waitable_event_posix.cc |
diff --git a/base/waitable_event_posix.cc b/base/waitable_event_posix.cc |
index 09e28684c5da7ac156b229f11f8aa88eae8ad07d..690c7557c351800eb86b0911d8f689a7335295bb 100644 |
--- a/base/waitable_event_posix.cc |
+++ b/base/waitable_event_posix.cc |
@@ -35,46 +35,40 @@ 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_(initially_signaled), |
- manual_reset_(manual_reset) { |
+ : kernel_(new WaitableEventKernel(manual_reset, initially_signaled)) { |
} |
WaitableEvent::~WaitableEvent() { |
- if (!waiters_.empty()) { |
- LOG(ERROR) << "Destroying a WaitableEvent (" << this << ") with " |
- << waiters_.size() << " waiters"; |
- NOTREACHED() << "Aborting."; |
- } |
} |
void WaitableEvent::Reset() { |
- AutoLock locked(lock_); |
- signaled_ = false; |
+ AutoLock locked(kernel_->lock_); |
+ kernel_->signaled_ = false; |
} |
void WaitableEvent::Signal() { |
- AutoLock locked(lock_); |
+ AutoLock locked(kernel_->lock_); |
- if (signaled_) |
+ if (kernel_->signaled_) |
return; |
- if (manual_reset_) { |
+ if (kernel_->manual_reset_) { |
SignalAll(); |
- signaled_ = true; |
+ kernel_->signaled_ = true; |
} else { |
// In the case of auto reset, if no waiters were woken, we remain |
// signaled. |
if (!SignalOne()) |
- signaled_ = true; |
+ kernel_->signaled_ = true; |
} |
} |
bool WaitableEvent::IsSignaled() { |
- AutoLock locked(lock_); |
+ AutoLock locked(kernel_->lock_); |
- const bool result = signaled_; |
- if (result && !manual_reset_) |
- signaled_ = false; |
+ const bool result = kernel_->signaled_; |
+ if (result && !kernel_->manual_reset_) |
+ kernel_->signaled_ = false; |
return result; |
} |
@@ -150,15 +144,15 @@ 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_) { |
- if (!manual_reset_) { |
+ kernel_->lock_.Acquire(); |
+ if (kernel_->signaled_) { |
+ if (!kernel_->manual_reset_) { |
// In this case we were signaled when we had no waiters. Now that |
// someone has waited upon us, we can automatically reset. |
- signaled_ = false; |
+ kernel_->signaled_ = false; |
} |
- lock_.Release(); |
+ kernel_->lock_.Release(); |
return true; |
} |
@@ -168,7 +162,7 @@ bool WaitableEvent::TimedWait(const TimeDelta& max_time) { |
SyncWaiter sw(&cv, &lock); |
Enqueue(&sw); |
- lock_.Release(); |
+ kernel_->lock_.Release(); |
// We are violating locking order here by holding the SyncWaiter lock but not |
// the WaitableEvent lock. However, this is safe because we don't lock @lock_ |
// again before unlocking it. |
@@ -187,9 +181,9 @@ bool WaitableEvent::TimedWait(const TimeDelta& max_time) { |
sw.Disable(); |
lock.Release(); |
- lock_.Acquire(); |
- Dequeue(&sw, &sw); |
- lock_.Release(); |
+ kernel_->lock_.Acquire(); |
+ kernel_->Dequeue(&sw, &sw); |
+ kernel_->lock_.Release(); |
return return_value; |
} |
@@ -261,7 +255,7 @@ size_t WaitableEvent::WaitMany(WaitableEvent** raw_waitables, |
lock.Acquire(); |
// Release the WaitableEvent locks in the reverse order |
for (size_t i = 0; i < count; ++i) { |
- waitables[count - (1 + i)].first->lock_.Release(); |
+ waitables[count - (1 + i)].first->kernel_->lock_.Release(); |
} |
for (;;) { |
@@ -281,12 +275,12 @@ size_t WaitableEvent::WaitMany(WaitableEvent** raw_waitables, |
// remove our SyncWaiter from the wait-list |
for (size_t i = 0; i < count; ++i) { |
if (raw_waitables[i] != signaled_event) { |
- raw_waitables[i]->lock_.Acquire(); |
+ raw_waitables[i]->kernel_->lock_.Acquire(); |
// There's no possible ABA issue with the address of the SyncWaiter here |
// because it lives on the stack. Thus the tag value is just the pointer |
// value again. |
- raw_waitables[i]->Dequeue(&sw, &sw); |
- raw_waitables[i]->lock_.Release(); |
+ raw_waitables[i]->kernel_->Dequeue(&sw, &sw); |
+ raw_waitables[i]->kernel_->lock_.Release(); |
} else { |
signaled_index = i; |
} |
@@ -312,17 +306,17 @@ size_t WaitableEvent::EnqueueMany |
if (!count) |
return 0; |
- waitables[0].first->lock_.Acquire(); |
- if (waitables[0].first->signaled_) { |
- if (!waitables[0].first->manual_reset_) |
- waitables[0].first->signaled_ = false; |
- waitables[0].first->lock_.Release(); |
+ 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->lock_.Release(); |
+ waitables[0].first->kernel_->lock_.Release(); |
} else { |
waitables[0].first->Enqueue(waiter); |
} |
@@ -343,12 +337,12 @@ bool WaitableEvent::SignalAll() { |
bool signaled_at_least_one = false; |
for (std::list<Waiter*>::iterator |
- i = waiters_.begin(); i != waiters_.end(); ++i) { |
+ i = kernel_->waiters_.begin(); i != kernel_->waiters_.end(); ++i) { |
if ((*i)->Fire(this)) |
signaled_at_least_one = true; |
} |
- waiters_.clear(); |
+ kernel_->waiters_.clear(); |
return signaled_at_least_one; |
} |
@@ -358,11 +352,11 @@ bool WaitableEvent::SignalAll() { |
// --------------------------------------------------------------------------- |
bool WaitableEvent::SignalOne() { |
for (;;) { |
- if (waiters_.empty()) |
+ if (kernel_->waiters_.empty()) |
return false; |
- const bool r = (*waiters_.begin())->Fire(this); |
- waiters_.pop_front(); |
+ const bool r = (*kernel_->waiters_.begin())->Fire(this); |
+ kernel_->waiters_.pop_front(); |
if (r) |
return true; |
} |
@@ -372,14 +366,14 @@ bool WaitableEvent::SignalOne() { |
// Add a waiter to the list of those waiting. Called with lock held. |
// ----------------------------------------------------------------------------- |
void WaitableEvent::Enqueue(Waiter* waiter) { |
- waiters_.push_back(waiter); |
+ kernel_->waiters_.push_back(waiter); |
} |
// ----------------------------------------------------------------------------- |
// Remove a waiter from the list of those waiting. Return true if the waiter was |
// actually removed. Called with lock held. |
// ----------------------------------------------------------------------------- |
-bool WaitableEvent::Dequeue(Waiter* waiter, void* tag) { |
+bool WaitableEvent::WaitableEventKernel::Dequeue(Waiter* waiter, void* tag) { |
for (std::list<Waiter*>::iterator |
i = waiters_.begin(); i != waiters_.end(); ++i) { |
if (*i == waiter && (*i)->Compare(tag)) { |