• 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_EDK_SYSTEM_DISPATCHER_H_
6 #define MOJO_EDK_SYSTEM_DISPATCHER_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <memory>
12 #include <ostream>
13 #include <vector>
14 
15 #include "base/macros.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/synchronization/lock.h"
18 #include "mojo/edk/embedder/platform_handle.h"
19 #include "mojo/edk/embedder/platform_shared_buffer.h"
20 #include "mojo/edk/system/handle_signals_state.h"
21 #include "mojo/edk/system/ports/name.h"
22 #include "mojo/edk/system/system_impl_export.h"
23 #include "mojo/edk/system/watcher.h"
24 #include "mojo/public/c/system/buffer.h"
25 #include "mojo/public/c/system/data_pipe.h"
26 #include "mojo/public/c/system/message_pipe.h"
27 #include "mojo/public/c/system/types.h"
28 
29 namespace mojo {
30 namespace edk {
31 
32 class Awakable;
33 class Dispatcher;
34 class MessageForTransit;
35 
36 using DispatcherVector = std::vector<scoped_refptr<Dispatcher>>;
37 
38 // A |Dispatcher| implements Mojo EDK calls that are associated with a
39 // particular MojoHandle, with the exception of MojoWait and MojoWaitMany (
40 // which are implemented directly in Core.).
41 class MOJO_SYSTEM_IMPL_EXPORT Dispatcher
42     : public base::RefCountedThreadSafe<Dispatcher> {
43  public:
44   struct DispatcherInTransit {
45     DispatcherInTransit();
46     DispatcherInTransit(const DispatcherInTransit& other);
47     ~DispatcherInTransit();
48 
49     scoped_refptr<Dispatcher> dispatcher;
50     MojoHandle local_handle;
51   };
52 
53   enum class Type {
54     UNKNOWN = 0,
55     MESSAGE_PIPE,
56     DATA_PIPE_PRODUCER,
57     DATA_PIPE_CONSUMER,
58     SHARED_BUFFER,
59     WAIT_SET,
60 
61     // "Private" types (not exposed via the public interface):
62     PLATFORM_HANDLE = -1,
63   };
64 
65   // All Dispatchers must minimally implement these methods.
66 
67   virtual Type GetType() const = 0;
68   virtual MojoResult Close() = 0;
69 
70   ///////////// Watch API ////////////////////
71 
72   virtual MojoResult Watch(MojoHandleSignals signals,
73                            const Watcher::WatchCallback& callback,
74                            uintptr_t context);
75 
76   virtual MojoResult CancelWatch(uintptr_t context);
77 
78   ///////////// Message pipe API /////////////
79 
80   virtual MojoResult WriteMessage(std::unique_ptr<MessageForTransit> message,
81                                   MojoWriteMessageFlags flags);
82 
83   virtual MojoResult ReadMessage(std::unique_ptr<MessageForTransit>* message,
84                                  uint32_t* num_bytes,
85                                  MojoHandle* handles,
86                                  uint32_t* num_handles,
87                                  MojoReadMessageFlags flags,
88                                  bool read_any_size);
89 
90   ///////////// Shared buffer API /////////////
91 
92   // |options| may be null. |new_dispatcher| must not be null, but
93   // |*new_dispatcher| should be null (and will contain the dispatcher for the
94   // new handle on success).
95   virtual MojoResult DuplicateBufferHandle(
96       const MojoDuplicateBufferHandleOptions* options,
97       scoped_refptr<Dispatcher>* new_dispatcher);
98 
99   virtual MojoResult MapBuffer(
100       uint64_t offset,
101       uint64_t num_bytes,
102       MojoMapBufferFlags flags,
103       std::unique_ptr<PlatformSharedBufferMapping>* mapping);
104 
105   ///////////// Data pipe consumer API /////////////
106 
107   virtual MojoResult ReadData(void* elements,
108                               uint32_t* num_bytes,
109                               MojoReadDataFlags flags);
110 
111   virtual MojoResult BeginReadData(const void** buffer,
112                                    uint32_t* buffer_num_bytes,
113                                    MojoReadDataFlags flags);
114 
115   virtual MojoResult EndReadData(uint32_t num_bytes_read);
116 
117   ///////////// Data pipe producer API /////////////
118 
119   virtual MojoResult WriteData(const void* elements,
120                                uint32_t* num_bytes,
121                                MojoWriteDataFlags flags);
122 
123   virtual MojoResult BeginWriteData(void** buffer,
124                                     uint32_t* buffer_num_bytes,
125                                     MojoWriteDataFlags flags);
126 
127   virtual MojoResult EndWriteData(uint32_t num_bytes_written);
128 
129   ///////////// Wait set API /////////////
130 
131   // Adds a dispatcher to wait on. When the dispatcher satisfies |signals|, it
132   // will be returned in the next call to |GetReadyDispatchers()|. If
133   // |dispatcher| has been added, it must be removed before adding again,
134   // otherwise |MOJO_RESULT_ALREADY_EXISTS| will be returned.
135   virtual MojoResult AddWaitingDispatcher(
136       const scoped_refptr<Dispatcher>& dispatcher,
137       MojoHandleSignals signals,
138       uintptr_t context);
139 
140   // Removes a dispatcher to wait on. If |dispatcher| has not been added,
141   // |MOJO_RESULT_NOT_FOUND| will be returned.
142   virtual MojoResult RemoveWaitingDispatcher(
143       const scoped_refptr<Dispatcher>& dispatcher);
144 
145   // Returns a set of ready dispatchers. |*count| is the maximum number of
146   // dispatchers to return, and will contain the number of dispatchers returned
147   // in |dispatchers| on completion.
148   virtual MojoResult GetReadyDispatchers(uint32_t* count,
149                                          DispatcherVector* dispatchers,
150                                          MojoResult* results,
151                                          uintptr_t* contexts);
152 
153   ///////////// General-purpose API for all handle types /////////
154 
155   // Gets the current handle signals state. (The default implementation simply
156   // returns a default-constructed |HandleSignalsState|, i.e., no signals
157   // satisfied or satisfiable.) Note: The state is subject to change from other
158   // threads.
159   virtual HandleSignalsState GetHandleSignalsState() const;
160 
161   // Adds an awakable to this dispatcher, which will be woken up when this
162   // object changes state to satisfy |signals| with context |context|. It will
163   // also be woken up when it becomes impossible for the object to ever satisfy
164   // |signals| with a suitable error status.
165   //
166   // If |signals_state| is non-null, on *failure* |*signals_state| will be set
167   // to the current handle signals state (on success, it is left untouched).
168   //
169   // Returns:
170   //  - |MOJO_RESULT_OK| if the awakable was added;
171   //  - |MOJO_RESULT_ALREADY_EXISTS| if |signals| is already satisfied;
172   //  - |MOJO_RESULT_INVALID_ARGUMENT| if the dispatcher has been closed; and
173   //  - |MOJO_RESULT_FAILED_PRECONDITION| if it is not (or no longer) possible
174   //    that |signals| will ever be satisfied.
175   virtual MojoResult AddAwakable(Awakable* awakable,
176                                  MojoHandleSignals signals,
177                                  uintptr_t context,
178                                  HandleSignalsState* signals_state);
179 
180   // Removes an awakable from this dispatcher. (It is valid to call this
181   // multiple times for the same |awakable| on the same object, so long as
182   // |AddAwakable()| was called at most once.) If |signals_state| is non-null,
183   // |*signals_state| will be set to the current handle signals state.
184   virtual void RemoveAwakable(Awakable* awakable,
185                               HandleSignalsState* signals_state);
186 
187   // Informs the caller of the total serialized size (in bytes) and the total
188   // number of platform handles and ports needed to transfer this dispatcher
189   // across a message pipe.
190   //
191   // Must eventually be followed by a call to EndSerializeAndClose(). Note that
192   // StartSerialize() and EndSerialize() are always called in sequence, and
193   // only between calls to BeginTransit() and either (but not both)
194   // CompleteTransitAndClose() or CancelTransit().
195   //
196   // For this reason it is IMPERATIVE that the implementation ensure a
197   // consistent serializable state between BeginTransit() and
198   // CompleteTransitAndClose()/CancelTransit().
199   virtual void StartSerialize(uint32_t* num_bytes,
200                               uint32_t* num_ports,
201                               uint32_t* num_platform_handles);
202 
203   // Serializes this dispatcher into |destination|, |ports|, and |handles|.
204   // Returns true iff successful, false otherwise. In either case the dispatcher
205   // will close.
206   //
207   // NOTE: Transit MAY still fail after this call returns. Implementations
208   // should not assume PlatformHandle ownership has transferred until
209   // CompleteTransitAndClose() is called. In other words, if CancelTransit() is
210   // called, the implementation should retain its PlatformHandles in working
211   // condition.
212   virtual bool EndSerialize(void* destination,
213                             ports::PortName* ports,
214                             PlatformHandle* handles);
215 
216   // Does whatever is necessary to begin transit of the dispatcher.  This
217   // should return |true| if transit is OK, or false if the underlying resource
218   // is deemed busy by the implementation.
219   virtual bool BeginTransit();
220 
221   // Does whatever is necessary to complete transit of the dispatcher, including
222   // closure. This is only called upon successfully transmitting an outgoing
223   // message containing this serialized dispatcher.
224   virtual void CompleteTransitAndClose();
225 
226   // Does whatever is necessary to cancel transit of the dispatcher. The
227   // dispatcher should remain in a working state and resume normal operation.
228   virtual void CancelTransit();
229 
230   // Deserializes a specific dispatcher type from an incoming message.
231   static scoped_refptr<Dispatcher> Deserialize(
232       Type type,
233       const void* bytes,
234       size_t num_bytes,
235       const ports::PortName* ports,
236       size_t num_ports,
237       PlatformHandle* platform_handles,
238       size_t num_platform_handles);
239 
240  protected:
241   friend class base::RefCountedThreadSafe<Dispatcher>;
242 
243   Dispatcher();
244   virtual ~Dispatcher();
245 
246   DISALLOW_COPY_AND_ASSIGN(Dispatcher);
247 };
248 
249 // So logging macros and |DCHECK_EQ()|, etc. work.
250 MOJO_SYSTEM_IMPL_EXPORT inline std::ostream& operator<<(std::ostream& out,
251                                                         Dispatcher::Type type) {
252   return out << static_cast<int>(type);
253 }
254 
255 }  // namespace edk
256 }  // namespace mojo
257 
258 #endif  // MOJO_EDK_SYSTEM_DISPATCHER_H_
259