• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_MESSAGE_PUMP_MESSAGE_PUMP_MOJO_H_
6 #define MOJO_MESSAGE_PUMP_MESSAGE_PUMP_MOJO_H_
7 
8 #include <stdint.h>
9 
10 #include <functional>
11 #include <memory>
12 #include <set>
13 #include <unordered_map>
14 
15 #include "base/macros.h"
16 #include "base/message_loop/message_pump.h"
17 #include "base/observer_list.h"
18 #include "base/synchronization/lock.h"
19 #include "base/synchronization/waitable_event.h"
20 #include "base/time/time.h"
21 #include "mojo/message_pump/mojo_message_pump_export.h"
22 #include "mojo/public/cpp/system/core.h"
23 
24 namespace mojo {
25 namespace common {
26 
27 class MessagePumpMojoHandler;
28 
29 // Mojo implementation of MessagePump.
30 class MOJO_MESSAGE_PUMP_EXPORT MessagePumpMojo : public base::MessagePump {
31  public:
32   class MOJO_MESSAGE_PUMP_EXPORT Observer {
33    public:
Observer()34     Observer() {}
35 
36     virtual void WillSignalHandler() = 0;
37     virtual void DidSignalHandler() = 0;
38 
39    protected:
~Observer()40     virtual ~Observer() {}
41   };
42 
43   MessagePumpMojo();
44   ~MessagePumpMojo() override;
45 
46   // Static factory function (for using with |base::Thread::Options|, wrapped
47   // using |base::Bind()|).
48   static std::unique_ptr<base::MessagePump> Create();
49 
50   // Returns the MessagePumpMojo instance of the current thread, if it exists.
51   static MessagePumpMojo* current();
52 
IsCurrent()53   static bool IsCurrent() { return !!current(); }
54 
55   // Registers a MessagePumpMojoHandler for the specified handle. Only one
56   // handler can be registered for a specified handle.
57   // NOTE: a value of 0 for |deadline| indicates an indefinite timeout.
58   void AddHandler(MessagePumpMojoHandler* handler,
59                   const Handle& handle,
60                   MojoHandleSignals wait_signals,
61                   base::TimeTicks deadline);
62 
63   void RemoveHandler(const Handle& handle);
64 
65   void AddObserver(Observer*);
66   void RemoveObserver(Observer*);
67 
68   // MessagePump:
69   void Run(Delegate* delegate) override;
70   void Quit() override;
71   void ScheduleWork() override;
72   void ScheduleDelayedWork(const base::TimeTicks& delayed_work_time) override;
73 
74  private:
75   struct RunState;
76 
77   // Contains the data needed to track a request to AddHandler().
78   struct Handler {
HandlerHandler79     Handler() : handler(NULL), wait_signals(MOJO_HANDLE_SIGNAL_NONE), id(0) {}
80 
81     MessagePumpMojoHandler* handler;
82     MojoHandleSignals wait_signals;
83     base::TimeTicks deadline;
84     // See description of |MessagePumpMojo::next_handler_id_| for details.
85     int id;
86   };
87 
88   struct HandleHasher {
operatorHandleHasher89     size_t operator()(const Handle& handle) const {
90       return std::hash<uint32_t>()(static_cast<uint32_t>(handle.value()));
91     }
92   };
93 
94   using HandleToHandler = std::unordered_map<Handle, Handler, HandleHasher>;
95 
96   // Implementation of Run().
97   void DoRunLoop(RunState* run_state, Delegate* delegate);
98 
99   // Services the set of handles ready. If |block| is true this waits for a
100   // handle to become ready, otherwise this does not block. Returns |true| if a
101   // handle has become ready, |false| otherwise.
102   bool DoInternalWork(const RunState& run_state, bool block);
103 
104   bool DoNonMojoWork(const RunState& run_state, bool block);
105 
106   // Waits for handles in the wait set to become ready. Returns |true| if ready
107   // handles may be available, or |false| if the wait's deadline was exceeded.
108   // Note, ready handles may be unavailable, even though |true| was returned.
109   bool WaitForReadyHandles(const RunState& run_state) const;
110 
111   // Retrieves any 'ready' handles from the wait set, and runs the handler's
112   // OnHandleReady() or OnHandleError() functions as necessary. Returns |true|
113   // if any handles were ready and processed.
114   bool ProcessReadyHandles();
115 
116   // Removes any handles that have expired their deadline. Runs the handler's
117   // OnHandleError() function with |MOJO_RESULT_DEADLINE_EXCEEDED| as the
118   // result. Returns |true| if any handles were removed.
119   bool RemoveExpiredHandles();
120 
121   void SignalControlPipe();
122 
123   // Returns the deadline for the call to MojoWait().
124   MojoDeadline GetDeadlineForWait(const RunState& run_state) const;
125 
126   // Run |OnHandleReady()| for the handler registered with |handle|. |handle|
127   // must be registered.
128   void SignalHandleReady(Handle handle);
129 
130   // Run |OnHandleError()| for the handler registered with |handle| and the
131   // error code |result|. |handle| must be registered, and will be removed
132   // before calling |OnHandleError()|.
133   void SignalHandleError(Handle handle, MojoResult result);
134 
135   void WillSignalHandler();
136   void DidSignalHandler();
137 
138   // If non-NULL we're running (inside Run()). Member is reference to value on
139   // stack.
140   RunState* run_state_;
141 
142   // Lock for accessing |run_state_|. In general the only method that we have to
143   // worry about is ScheduleWork(). All other methods are invoked on the same
144   // thread.
145   base::Lock run_state_lock_;
146 
147   HandleToHandler handlers_;
148   // Set of handles that have a deadline set. Avoids iterating over all elements
149   // in |handles_| in the common case (no deadline set).
150   // TODO(amistry): Make this better and avoid special-casing deadlines.
151   std::set<Handle> deadline_handles_;
152 
153   // An ever increasing value assigned to each Handler::id. Used to detect
154   // uniqueness while notifying. That is, while notifying expired timers we copy
155   // |handlers_| and only notify handlers whose id match. If the id does not
156   // match it means the handler was removed then added so that we shouldn't
157   // notify it.
158   int next_handler_id_;
159 
160   base::ObserverList<Observer> observers_;
161 
162   // Mojo handle for the wait set.
163   ScopedHandle wait_set_handle_;
164   // Used to wake up run loop from |SignalControlPipe()|.
165   ScopedMessagePipeHandle read_handle_;
166   ScopedMessagePipeHandle write_handle_;
167 
168   // Used to sleep until there is more work to do, when the Mojo EDK is shutting
169   // down.
170   base::WaitableEvent event_;
171 
172   DISALLOW_COPY_AND_ASSIGN(MessagePumpMojo);
173 };
174 
175 }  // namespace common
176 }  // namespace mojo
177 
178 #endif  // MOJO_MESSAGE_PUMP_MESSAGE_PUMP_MOJO_H_
179