1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Copyright 2015 The Chromium Authors. All rights reserved. 2645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// Use of this source code is governed by a BSD-style license that can be 3645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez// found in the LICENSE file. 4645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 5645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#ifndef MOJO_EDK_SYSTEM_WAIT_SET_DISPATCHER_H_ 6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#define MOJO_EDK_SYSTEM_WAIT_SET_DISPATCHER_H_ 7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <stdint.h> 9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <deque> 11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <memory> 12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <unordered_map> 13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include <utility> 14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/macros.h" 16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "base/synchronization/lock.h" 17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/system/awakable_list.h" 18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/system/dispatcher.h" 19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#include "mojo/edk/system/system_impl_export.h" 20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace mojo { 22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chaveznamespace edk { 23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass MOJO_SYSTEM_IMPL_EXPORT WaitSetDispatcher : public Dispatcher { 25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez public: 26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez WaitSetDispatcher(); 27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Dispatcher: 29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez Type GetType() const override; 30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoResult Close() override; 31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoResult AddWaitingDispatcher(const scoped_refptr<Dispatcher>& dispatcher, 32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoHandleSignals signals, 33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez uintptr_t context) override; 34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoResult RemoveWaitingDispatcher( 35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez const scoped_refptr<Dispatcher>& dispatcher) override; 36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoResult GetReadyDispatchers(uint32_t* count, 37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DispatcherVector* dispatchers, 38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoResult* results, 39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez uintptr_t* contexts) override; 40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez HandleSignalsState GetHandleSignalsState() const override; 41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoResult AddAwakable(Awakable* awakable, 42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoHandleSignals signals, 43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez uintptr_t context, 44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez HandleSignalsState* signals_state) override; 45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez void RemoveAwakable(Awakable* awakable, 46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez HandleSignalsState* signals_state) override; 47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bool BeginTransit() override; 48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez private: 50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Internal implementation of Awakable. 51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez class Waiter; 52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez struct WaitState { 54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez WaitState(); 55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez WaitState(const WaitState& other); 56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez ~WaitState(); 57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez scoped_refptr<Dispatcher> dispatcher; 59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez MojoHandleSignals signals; 60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez uintptr_t context; 61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez }; 62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez ~WaitSetDispatcher() override; 64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez HandleSignalsState GetHandleSignalsStateNoLock() const; 66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Signal that the dispatcher indexed by |context| has been woken up with 68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // |result| and is now ready. 69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez void WakeDispatcher(MojoResult result, uintptr_t context); 70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Guards |is_closed_|, |waiting_dispatchers_|, and |waiter_|. 72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // 73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // TODO: Consider removing this. 74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez mutable base::Lock lock_; 75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez bool is_closed_ = false; 76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Map of dispatchers being waited on. Key is a Dispatcher* casted to a 78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // uintptr_t, and should be treated as an opaque value and not casted back. 79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez std::unordered_map<uintptr_t, WaitState> waiting_dispatchers_; 80645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 81645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Separate lock that can be locked without locking |lock_|. 82645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez mutable base::Lock awoken_lock_; 83645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // List of dispatchers that have been woken up. Any dispatcher in this queue 84645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // will NOT currently be waited on. 85645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez std::deque<std::pair<uintptr_t, MojoResult>> awoken_queue_; 86645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // List of dispatchers that have been woken up and retrieved. 87645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez std::deque<uintptr_t> processed_dispatchers_; 88645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 89645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Separate lock that can be locked without locking |lock_|. 90645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez base::Lock awakable_lock_; 91645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // List of dispatchers being waited on. 92645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez AwakableList awakable_list_; 93645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 94645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez // Waiter used to wait on dispatchers. 95645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez std::unique_ptr<Waiter> waiter_; 96645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 97645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez DISALLOW_COPY_AND_ASSIGN(WaitSetDispatcher); 98645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez}; 99645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 100645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez} // namespace edk 101645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez} // namespace mojo 102645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 103645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez#endif // MOJO_EDK_SYSTEM_WAIT_SET_DISPATCHER_H_ 104