1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef MOJO_COMMON_MESSAGE_PUMP_MOJO_H_ 6 #define MOJO_COMMON_MESSAGE_PUMP_MOJO_H_ 7 8 #include <map> 9 10 #include "base/memory/scoped_ptr.h" 11 #include "base/message_loop/message_pump.h" 12 #include "base/synchronization/lock.h" 13 #include "base/time/time.h" 14 #include "mojo/common/mojo_common_export.h" 15 #include "mojo/public/cpp/system/core.h" 16 17 namespace mojo { 18 namespace common { 19 20 class MessagePumpMojoHandler; 21 22 // Mojo implementation of MessagePump. 23 class MOJO_COMMON_EXPORT MessagePumpMojo : public base::MessagePump { 24 public: 25 MessagePumpMojo(); 26 virtual ~MessagePumpMojo(); 27 28 // Static factory function (for using with |base::Thread::Options|, wrapped 29 // using |base::Bind()|). 30 static scoped_ptr<base::MessagePump> Create(); 31 32 // Returns the MessagePumpMojo instance of the current thread, if it exists. 33 static MessagePumpMojo* current(); 34 IsCurrent()35 static bool IsCurrent() { return !!current(); } 36 37 // Registers a MessagePumpMojoHandler for the specified handle. Only one 38 // handler can be registered for a specified handle. 39 // NOTE: a value of 0 for |deadline| indicates an indefinite timeout. 40 void AddHandler(MessagePumpMojoHandler* handler, 41 const Handle& handle, 42 MojoHandleSignals wait_signals, 43 base::TimeTicks deadline); 44 45 void RemoveHandler(const Handle& handle); 46 47 // MessagePump: 48 virtual void Run(Delegate* delegate) OVERRIDE; 49 virtual void Quit() OVERRIDE; 50 virtual void ScheduleWork() OVERRIDE; 51 virtual void ScheduleDelayedWork( 52 const base::TimeTicks& delayed_work_time) OVERRIDE; 53 54 private: 55 struct RunState; 56 struct WaitState; 57 58 // Contains the data needed to track a request to AddHandler(). 59 struct Handler { HandlerHandler60 Handler() : handler(NULL), wait_signals(MOJO_HANDLE_SIGNAL_NONE), id(0) {} 61 62 MessagePumpMojoHandler* handler; 63 MojoHandleSignals wait_signals; 64 base::TimeTicks deadline; 65 // See description of |MessagePumpMojo::next_handler_id_| for details. 66 int id; 67 }; 68 69 typedef std::map<Handle, Handler> HandleToHandler; 70 71 // Implementation of Run(). 72 void DoRunLoop(RunState* run_state, Delegate* delegate); 73 74 // Services the set of handles ready. If |block| is true this waits for a 75 // handle to become ready, otherwise this does not block. 76 void DoInternalWork(const RunState& run_state, bool block); 77 78 // Removes the first invalid handle. This is called if MojoWaitMany finds an 79 // invalid handle. 80 void RemoveFirstInvalidHandle(const WaitState& wait_state); 81 82 void SignalControlPipe(const RunState& run_state); 83 84 WaitState GetWaitState(const RunState& run_state) const; 85 86 // Returns the deadline for the call to MojoWaitMany(). 87 MojoDeadline GetDeadlineForWait(const RunState& run_state) const; 88 89 // If non-NULL we're running (inside Run()). Member is reference to value on 90 // stack. 91 RunState* run_state_; 92 93 // Lock for accessing |run_state_|. In general the only method that we have to 94 // worry about is ScheduleWork(). All other methods are invoked on the same 95 // thread. 96 base::Lock run_state_lock_; 97 98 HandleToHandler handlers_; 99 100 // An ever increasing value assigned to each Handler::id. Used to detect 101 // uniqueness while notifying. That is, while notifying expired timers we copy 102 // |handlers_| and only notify handlers whose id match. If the id does not 103 // match it means the handler was removed then added so that we shouldn't 104 // notify it. 105 int next_handler_id_; 106 107 DISALLOW_COPY_AND_ASSIGN(MessagePumpMojo); 108 }; 109 110 } // namespace common 111 } // namespace mojo 112 113 #endif // MOJO_COMMON_MESSAGE_PUMP_MOJO_H_ 114