Index: third_party/mojo/src/mojo/edk/system/wait_set_dispatcher.cc |
diff --git a/third_party/mojo/src/mojo/edk/system/wait_set_dispatcher.cc b/third_party/mojo/src/mojo/edk/system/wait_set_dispatcher.cc |
deleted file mode 100644 |
index 45518e7eefd14044f2696bca00dd8fce301cfc31..0000000000000000000000000000000000000000 |
--- a/third_party/mojo/src/mojo/edk/system/wait_set_dispatcher.cc |
+++ /dev/null |
@@ -1,277 +0,0 @@ |
-// Copyright 2015 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "third_party/mojo/src/mojo/edk/system/wait_set_dispatcher.h" |
- |
-#include <algorithm> |
-#include <utility> |
- |
-#include "base/logging.h" |
-#include "third_party/mojo/src/mojo/edk/system/awakable.h" |
- |
-namespace mojo { |
-namespace system { |
- |
-class WaitSetDispatcher::Waiter final : public Awakable { |
- public: |
- explicit Waiter(WaitSetDispatcher* dispatcher) : dispatcher_(dispatcher) {} |
- ~Waiter() {} |
- |
- // |Awakable| implementation. |
- bool Awake(MojoResult result, uintptr_t context) override { |
- // Note: This is called with various Mojo locks held. |
- dispatcher_->WakeDispatcher(result, context); |
- // Removes |this| from the dispatcher's list of waiters. |
- return false; |
- } |
- |
- private: |
- WaitSetDispatcher* const dispatcher_; |
-}; |
- |
-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() { |
- mutex().AssertHeld(); |
- for (const auto& entry : waiting_dispatchers_) |
- entry.second.dispatcher->RemoveAwakable(waiter_.get(), nullptr); |
- waiting_dispatchers_.clear(); |
- |
- MutexLocker locker(&awoken_mutex_); |
- awoken_queue_.clear(); |
- processed_dispatchers_.clear(); |
-} |
- |
-MojoResult WaitSetDispatcher::AddWaitingDispatcherImplNoLock( |
- const scoped_refptr<Dispatcher>& dispatcher, |
- MojoHandleSignals signals, |
- uintptr_t context) { |
- mutex().AssertHeld(); |
- if (dispatcher == this) |
- 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()) { |
- return MOJO_RESULT_ALREADY_EXISTS; |
- } |
- |
- const MojoResult result = dispatcher->AddAwakable(waiter_.get(), signals, |
- dispatcher_handle, nullptr); |
- if (result == MOJO_RESULT_INVALID_ARGUMENT) { |
- // Dispatcher is closed. |
- return result; |
- } else if (result != MOJO_RESULT_OK) { |
- WakeDispatcher(result, dispatcher_handle); |
- } |
- |
- WaitState state; |
- state.dispatcher = dispatcher; |
- state.context = context; |
- state.signals = signals; |
- bool inserted = |
- waiting_dispatchers_.insert(std::make_pair(dispatcher_handle, state)) |
- .second; |
- DCHECK(inserted); |
- |
- return MOJO_RESULT_OK; |
-} |
- |
-MojoResult WaitSetDispatcher::RemoveWaitingDispatcherImplNoLock( |
- const scoped_refptr<Dispatcher>& dispatcher) { |
- mutex().AssertHeld(); |
- 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); |
- |
- MutexLocker locker(&awoken_mutex_); |
- int num_erased = 0; |
- for (auto it = awoken_queue_.begin(); it != awoken_queue_.end();) { |
- if (it->first == dispatcher_handle) { |
- it = awoken_queue_.erase(it); |
- num_erased++; |
- } else { |
- ++it; |
- } |
- } |
- // The dispatcher should only exist in the queue once. |
- DCHECK_LE(num_erased, 1); |
- processed_dispatchers_.erase( |
- std::remove(processed_dispatchers_.begin(), processed_dispatchers_.end(), |
- dispatcher_handle), |
- processed_dispatchers_.end()); |
- |
- return MOJO_RESULT_OK; |
-} |
- |
-MojoResult WaitSetDispatcher::GetReadyDispatchersImplNoLock( |
- UserPointer<uint32_t> count, |
- DispatcherVector* dispatchers, |
- UserPointer<MojoResult> results, |
- UserPointer<uintptr_t> contexts) { |
- mutex().AssertHeld(); |
- dispatchers->clear(); |
- |
- // Re-queue any already retrieved dispatchers. These should be the dispatchers |
- // that were returned on the last call to this function. This loop is |
- // necessary to preserve the logically level-triggering behaviour of waiting |
- // in Mojo. In particular, if no action is taken on a signal, that signal |
- // continues to be satisfied, and therefore a |MojoWait()| on that |
- // handle/signal continues to return immediately. |
- std::deque<uintptr_t> pending; |
- { |
- MutexLocker locker(&awoken_mutex_); |
- pending.swap(processed_dispatchers_); |
- } |
- for (uintptr_t d : pending) { |
- auto it = waiting_dispatchers_.find(d); |
- // Anything in |processed_dispatchers_| should also be in |
- // |waiting_dispatchers_| since dispatchers are removed from both in |
- // |RemoveWaitingDispatcherImplNoLock()|. |
- DCHECK(it != waiting_dispatchers_.end()); |
- |
- // |awoken_mutex_| cannot be held here because |
- // |Dispatcher::AddAwakable()| acquires the Dispatcher's mutex. This |
- // mutex is held while running |WakeDispatcher()| below, which needs to |
- // acquire |awoken_mutex_|. Holding |awoken_mutex_| here would result in |
- // a deadlock. |
- const MojoResult result = it->second.dispatcher->AddAwakable( |
- waiter_.get(), it->second.signals, d, nullptr); |
- |
- if (result == MOJO_RESULT_INVALID_ARGUMENT) { |
- // Dispatcher is closed. Implicitly remove it from the wait set since |
- // it may be impossible to remove using |MojoRemoveHandle()|. |
- waiting_dispatchers_.erase(it); |
- } else if (result != MOJO_RESULT_OK) { |
- WakeDispatcher(result, d); |
- } |
- } |
- |
- const uint32_t max_woken = count.Get(); |
- uint32_t num_woken = 0; |
- |
- MutexLocker locker(&awoken_mutex_); |
- while (!awoken_queue_.empty() && num_woken < max_woken) { |
- uintptr_t d = awoken_queue_.front().first; |
- MojoResult result = awoken_queue_.front().second; |
- awoken_queue_.pop_front(); |
- |
- auto it = waiting_dispatchers_.find(d); |
- DCHECK(it != waiting_dispatchers_.end()); |
- |
- results.At(num_woken).Put(result); |
- dispatchers->push_back(it->second.dispatcher); |
- if (!contexts.IsNull()) |
- contexts.At(num_woken).Put(it->second.context); |
- |
- if (result != MOJO_RESULT_CANCELLED) { |
- processed_dispatchers_.push_back(d); |
- } else { |
- waiting_dispatchers_.erase(it); |
- } |
- |
- num_woken++; |
- } |
- |
- count.Put(num_woken); |
- if (!num_woken) |
- return MOJO_RESULT_SHOULD_WAIT; |
- |
- return MOJO_RESULT_OK; |
-} |
- |
-void WaitSetDispatcher::CancelAllAwakablesNoLock() { |
- mutex().AssertHeld(); |
- MutexLocker locker(&awakable_mutex_); |
- awakable_list_.CancelAll(); |
-} |
- |
-MojoResult WaitSetDispatcher::AddAwakableImplNoLock( |
- Awakable* awakable, |
- MojoHandleSignals signals, |
- uintptr_t context, |
- HandleSignalsState* signals_state) { |
- mutex().AssertHeld(); |
- |
- HandleSignalsState state(GetHandleSignalsStateImplNoLock()); |
- if (state.satisfies(signals)) { |
- if (signals_state) |
- *signals_state = state; |
- return MOJO_RESULT_ALREADY_EXISTS; |
- } |
- if (!state.can_satisfy(signals)) { |
- if (signals_state) |
- *signals_state = state; |
- return MOJO_RESULT_FAILED_PRECONDITION; |
- } |
- |
- MutexLocker locker(&awakable_mutex_); |
- awakable_list_.Add(awakable, signals, context); |
- return MOJO_RESULT_OK; |
-} |
- |
-void WaitSetDispatcher::RemoveAwakableImplNoLock( |
- Awakable* awakable, |
- HandleSignalsState* signals_state) { |
- mutex().AssertHeld(); |
- MutexLocker locker(&awakable_mutex_); |
- awakable_list_.Remove(awakable); |
- if (signals_state) |
- *signals_state = GetHandleSignalsStateImplNoLock(); |
-} |
- |
-HandleSignalsState WaitSetDispatcher::GetHandleSignalsStateImplNoLock() const { |
- mutex().AssertHeld(); |
- HandleSignalsState rv; |
- rv.satisfiable_signals = MOJO_HANDLE_SIGNAL_READABLE; |
- MutexLocker locker(&awoken_mutex_); |
- if (!awoken_queue_.empty() || !processed_dispatchers_.empty()) |
- rv.satisfied_signals = MOJO_HANDLE_SIGNAL_READABLE; |
- return rv; |
-} |
- |
-scoped_refptr<Dispatcher> |
-WaitSetDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() { |
- mutex().AssertHeld(); |
- LOG(ERROR) << "Attempting to serialize WaitSet"; |
- CloseImplNoLock(); |
- return new WaitSetDispatcher(); |
-} |
- |
-void WaitSetDispatcher::WakeDispatcher(MojoResult result, uintptr_t context) { |
- { |
- MutexLocker locker(&awoken_mutex_); |
- |
- if (result == MOJO_RESULT_ALREADY_EXISTS) |
- result = MOJO_RESULT_OK; |
- |
- awoken_queue_.push_back(std::make_pair(context, result)); |
- } |
- |
- MutexLocker locker(&awakable_mutex_); |
- HandleSignalsState signals_state; |
- signals_state.satisfiable_signals = MOJO_HANDLE_SIGNAL_READABLE; |
- signals_state.satisfied_signals = MOJO_HANDLE_SIGNAL_READABLE; |
- awakable_list_.AwakeForStateChange(signals_state); |
-} |
- |
-} // namespace system |
-} // namespace mojo |