Index: mojo/edk/system/wait_set_dispatcher.cc |
diff --git a/mojo/edk/system/wait_set_dispatcher.cc b/mojo/edk/system/wait_set_dispatcher.cc |
index 3a5d4972a388f7a0fb80946ae465f14e0248772a..f6fc5599286c560382499aeee47f56219105883f 100644 |
--- a/mojo/edk/system/wait_set_dispatcher.cc |
+++ b/mojo/edk/system/wait_set_dispatcher.cc |
@@ -39,35 +39,49 @@ WaitSetDispatcher::WaitState::~WaitState() {} |
WaitSetDispatcher::WaitSetDispatcher() |
: waiter_(new WaitSetDispatcher::Waiter(this)) {} |
-WaitSetDispatcher::~WaitSetDispatcher() { |
- DCHECK(waiting_dispatchers_.empty()); |
- DCHECK(awoken_queue_.empty()); |
- DCHECK(processed_dispatchers_.empty()); |
-} |
- |
Dispatcher::Type WaitSetDispatcher::GetType() const { |
return Type::WAIT_SET; |
} |
-void WaitSetDispatcher::CloseImplNoLock() { |
- lock().AssertAcquired(); |
- for (const auto& entry : waiting_dispatchers_) |
- entry.second.dispatcher->RemoveAwakable(waiter_.get(), nullptr); |
- waiting_dispatchers_.clear(); |
+MojoResult WaitSetDispatcher::Close() { |
+ { |
+ base::AutoLock lock(lock_); |
Anand Mistry (off Chromium)
2016/01/28 02:26:25
Why not just hold lock_ for the entire function. I
|
+ if (is_closed_) |
+ return MOJO_RESULT_INVALID_ARGUMENT; |
+ is_closed_ = true; |
+ } |
+ |
+ { |
+ base::AutoLock locker(awakable_lock_); |
+ awakable_list_.CancelAll(); |
+ } |
+ |
+ { |
+ base::AutoLock lock(lock_); |
+ for (const auto& entry : waiting_dispatchers_) |
+ entry.second.dispatcher->RemoveAwakable(waiter_.get(), nullptr); |
+ waiting_dispatchers_.clear(); |
+ } |
base::AutoLock locker(awoken_lock_); |
awoken_queue_.clear(); |
processed_dispatchers_.clear(); |
+ |
+ return MOJO_RESULT_OK; |
} |
-MojoResult WaitSetDispatcher::AddWaitingDispatcherImplNoLock( |
+MojoResult WaitSetDispatcher::AddWaitingDispatcher( |
const scoped_refptr<Dispatcher>& dispatcher, |
MojoHandleSignals signals, |
uintptr_t context) { |
- lock().AssertAcquired(); |
if (dispatcher == this) |
return MOJO_RESULT_INVALID_ARGUMENT; |
+ base::AutoLock lock(lock_); |
+ |
+ if (is_closed_) |
+ return MOJO_RESULT_INVALID_ARGUMENT; |
+ |
uintptr_t dispatcher_handle = reinterpret_cast<uintptr_t>(dispatcher.get()); |
auto it = waiting_dispatchers_.find(dispatcher_handle); |
if (it != waiting_dispatchers_.end()) { |
@@ -94,18 +108,20 @@ MojoResult WaitSetDispatcher::AddWaitingDispatcherImplNoLock( |
return MOJO_RESULT_OK; |
} |
-MojoResult WaitSetDispatcher::RemoveWaitingDispatcherImplNoLock( |
+MojoResult WaitSetDispatcher::RemoveWaitingDispatcher( |
const scoped_refptr<Dispatcher>& dispatcher) { |
- lock().AssertAcquired(); |
uintptr_t dispatcher_handle = reinterpret_cast<uintptr_t>(dispatcher.get()); |
- auto it = waiting_dispatchers_.find(dispatcher_handle); |
- if (it == waiting_dispatchers_.end()) |
- return MOJO_RESULT_NOT_FOUND; |
- |
- dispatcher->RemoveAwakable(waiter_.get(), nullptr); |
- // At this point, it should not be possible for |waiter_| to be woken with |
- // |dispatcher|. |
- waiting_dispatchers_.erase(it); |
+ { |
+ base::AutoLock lock(lock_); |
Anand Mistry (off Chromium)
2016/01/28 02:26:25
Need to handle the closed state. This can return "
|
+ auto it = waiting_dispatchers_.find(dispatcher_handle); |
+ if (it == waiting_dispatchers_.end()) |
+ return MOJO_RESULT_NOT_FOUND; |
+ |
+ dispatcher->RemoveAwakable(waiter_.get(), nullptr); |
+ // At this point, it should not be possible for |waiter_| to be woken with |
+ // |dispatcher|. |
+ waiting_dispatchers_.erase(it); |
+ } |
base::AutoLock locker(awoken_lock_); |
int num_erased = 0; |
@@ -127,12 +143,13 @@ MojoResult WaitSetDispatcher::RemoveWaitingDispatcherImplNoLock( |
return MOJO_RESULT_OK; |
} |
-MojoResult WaitSetDispatcher::GetReadyDispatchersImplNoLock( |
+MojoResult WaitSetDispatcher::GetReadyDispatchers( |
uint32_t* count, |
DispatcherVector* dispatchers, |
MojoResult* results, |
uintptr_t* contexts) { |
- lock().AssertAcquired(); |
+ base::AutoLock lock(lock_); |
+ |
dispatchers->clear(); |
// Re-queue any already retrieved dispatchers. These should be the dispatchers |
@@ -205,20 +222,20 @@ MojoResult WaitSetDispatcher::GetReadyDispatchersImplNoLock( |
return MOJO_RESULT_OK; |
} |
-void WaitSetDispatcher::CancelAllAwakablesNoLock() { |
- lock().AssertAcquired(); |
- base::AutoLock locker(awakable_lock_); |
- awakable_list_.CancelAll(); |
+HandleSignalsState WaitSetDispatcher::GetHandleSignalsState() const { |
Anand Mistry (off Chromium)
2016/01/28 02:26:25
Need to handle the closed state. Without it, it's
|
+ HandleSignalsState rv; |
+ rv.satisfiable_signals = MOJO_HANDLE_SIGNAL_READABLE; |
+ base::AutoLock locker(awoken_lock_); |
+ if (!awoken_queue_.empty() || !processed_dispatchers_.empty()) |
+ rv.satisfied_signals = MOJO_HANDLE_SIGNAL_READABLE; |
+ return rv; |
} |
-MojoResult WaitSetDispatcher::AddAwakableImplNoLock( |
- Awakable* awakable, |
- MojoHandleSignals signals, |
- uintptr_t context, |
- HandleSignalsState* signals_state) { |
- lock().AssertAcquired(); |
- |
- HandleSignalsState state(GetHandleSignalsStateImplNoLock()); |
+MojoResult WaitSetDispatcher::AddAwakable(Awakable* awakable, |
+ MojoHandleSignals signals, |
+ uintptr_t context, |
+ HandleSignalsState* signals_state) { |
+ HandleSignalsState state(GetHandleSignalsState()); |
if (state.satisfies(signals)) { |
if (signals_state) |
*signals_state = state; |
@@ -235,32 +252,23 @@ MojoResult WaitSetDispatcher::AddAwakableImplNoLock( |
return MOJO_RESULT_OK; |
} |
-void WaitSetDispatcher::RemoveAwakableImplNoLock( |
- Awakable* awakable, |
- HandleSignalsState* signals_state) { |
- lock().AssertAcquired(); |
+void WaitSetDispatcher::RemoveAwakable(Awakable* awakable, |
+ HandleSignalsState* signals_state) { |
base::AutoLock locker(awakable_lock_); |
awakable_list_.Remove(awakable); |
if (signals_state) |
- *signals_state = GetHandleSignalsStateImplNoLock(); |
+ *signals_state = GetHandleSignalsState(); |
} |
-HandleSignalsState WaitSetDispatcher::GetHandleSignalsStateImplNoLock() const { |
- lock().AssertAcquired(); |
- HandleSignalsState rv; |
- rv.satisfiable_signals = MOJO_HANDLE_SIGNAL_READABLE; |
- base::AutoLock locker(awoken_lock_); |
- if (!awoken_queue_.empty() || !processed_dispatchers_.empty()) |
- rv.satisfied_signals = MOJO_HANDLE_SIGNAL_READABLE; |
- return rv; |
+bool WaitSetDispatcher::BeginTransit() { |
+ // You can't transfer wait sets! |
+ return false; |
} |
-scoped_refptr<Dispatcher> |
-WaitSetDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() { |
- lock().AssertAcquired(); |
- LOG(ERROR) << "Attempting to serialize WaitSet"; |
- CloseImplNoLock(); |
- return new WaitSetDispatcher(); |
+WaitSetDispatcher::~WaitSetDispatcher() { |
+ DCHECK(waiting_dispatchers_.empty()); |
+ DCHECK(awoken_queue_.empty()); |
+ DCHECK(processed_dispatchers_.empty()); |
} |
void WaitSetDispatcher::WakeDispatcher(MojoResult result, uintptr_t context) { |