• 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_CORE_DISPATCHER_H_
6 #define MOJO_CORE_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/strings/string_piece.h"
18 #include "base/synchronization/lock.h"
19 #include "mojo/core/handle_signals_state.h"
20 #include "mojo/core/ports/name.h"
21 #include "mojo/core/ports/port_ref.h"
22 #include "mojo/core/system_impl_export.h"
23 #include "mojo/core/watch.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/quota.h"
28 #include "mojo/public/c/system/trap.h"
29 #include "mojo/public/c/system/types.h"
30 #include "mojo/public/cpp/platform/platform_handle.h"
31 
32 namespace mojo {
33 namespace core {
34 
35 namespace ports {
36 class UserMessageEvent;
37 }
38 
39 class Dispatcher;
40 class PlatformSharedMemoryMapping;
41 
42 using DispatcherVector = std::vector<scoped_refptr<Dispatcher>>;
43 
44 // A |Dispatcher| implements Mojo EDK calls that are associated with a
45 // particular MojoHandle.
46 class MOJO_SYSTEM_IMPL_EXPORT Dispatcher
47     : public base::RefCountedThreadSafe<Dispatcher> {
48  public:
49   struct DispatcherInTransit {
50     DispatcherInTransit();
51     DispatcherInTransit(const DispatcherInTransit& other);
52     ~DispatcherInTransit();
53 
54     scoped_refptr<Dispatcher> dispatcher;
55     MojoHandle local_handle;
56   };
57 
58   enum class Type {
59     UNKNOWN = 0,
60     MESSAGE_PIPE,
61     DATA_PIPE_PRODUCER,
62     DATA_PIPE_CONSUMER,
63     SHARED_BUFFER,
64     WATCHER,
65     INVITATION,
66 
67     // "Private" types (not exposed via the public interface):
68     PLATFORM_HANDLE = -1,
69   };
70 
71   // All Dispatchers must minimally implement these methods.
72 
73   virtual Type GetType() const = 0;
74   virtual MojoResult Close() = 0;
75 
76   ///////////// Watcher API ////////////////////
77 
78   virtual MojoResult WatchDispatcher(scoped_refptr<Dispatcher> dispatcher,
79                                      MojoHandleSignals signals,
80                                      MojoTriggerCondition condition,
81                                      uintptr_t context);
82   virtual MojoResult CancelWatch(uintptr_t context);
83   virtual MojoResult Arm(uint32_t* num_blocking_events,
84                          MojoTrapEvent* blocking_events);
85 
86   ///////////// Message pipe API /////////////
87 
88   virtual MojoResult WriteMessage(
89       std::unique_ptr<ports::UserMessageEvent> message);
90 
91   virtual MojoResult ReadMessage(
92       std::unique_ptr<ports::UserMessageEvent>* message);
93 
94   ///////////// Shared buffer API /////////////
95 
96   // |options| may be null. |new_dispatcher| must not be null, but
97   // |*new_dispatcher| should be null (and will contain the dispatcher for the
98   // new handle on success).
99   virtual MojoResult DuplicateBufferHandle(
100       const MojoDuplicateBufferHandleOptions* options,
101       scoped_refptr<Dispatcher>* new_dispatcher);
102 
103   virtual MojoResult MapBuffer(
104       uint64_t offset,
105       uint64_t num_bytes,
106       std::unique_ptr<PlatformSharedMemoryMapping>* mapping);
107 
108   virtual MojoResult GetBufferInfo(MojoSharedBufferInfo* info);
109 
110   ///////////// Data pipe consumer API /////////////
111 
112   virtual MojoResult ReadData(const MojoReadDataOptions& options,
113                               void* elements,
114                               uint32_t* num_bytes);
115 
116   virtual MojoResult BeginReadData(const void** buffer,
117                                    uint32_t* buffer_num_bytes);
118 
119   virtual MojoResult EndReadData(uint32_t num_bytes_read);
120 
121   ///////////// Data pipe producer API /////////////
122 
123   virtual MojoResult WriteData(const void* elements,
124                                uint32_t* num_bytes,
125                                const MojoWriteDataOptions& options);
126 
127   virtual MojoResult BeginWriteData(void** buffer, uint32_t* buffer_num_bytes);
128 
129   virtual MojoResult EndWriteData(uint32_t num_bytes_written);
130 
131   // Invitation API.
132   virtual MojoResult AttachMessagePipe(base::StringPiece name,
133                                        ports::PortRef remote_peer_port);
134   virtual MojoResult ExtractMessagePipe(base::StringPiece name,
135                                         MojoHandle* message_pipe_handle);
136 
137   // Quota API.
138   virtual MojoResult SetQuota(MojoQuotaType type, uint64_t limit);
139   virtual MojoResult QueryQuota(MojoQuotaType type,
140                                 uint64_t* limit,
141                                 uint64_t* usage);
142 
143   ///////////// General-purpose API for all handle types /////////
144 
145   // Gets the current handle signals state. (The default implementation simply
146   // returns a default-constructed |HandleSignalsState|, i.e., no signals
147   // satisfied or satisfiable.) Note: The state is subject to change from other
148   // threads.
149   virtual HandleSignalsState GetHandleSignalsState() const;
150 
151   // Adds a WatcherDispatcher reference to this dispatcher, to be notified of
152   // all subsequent changes to handle state including signal changes or closure.
153   // The reference is associated with a |context| for disambiguation of
154   // removals.
155   virtual MojoResult AddWatcherRef(
156       const scoped_refptr<WatcherDispatcher>& watcher,
157       uintptr_t context);
158 
159   // Removes a WatcherDispatcher reference from this dispatcher.
160   virtual MojoResult RemoveWatcherRef(WatcherDispatcher* watcher,
161                                       uintptr_t context);
162 
163   // Informs the caller of the total serialized size (in bytes) and the total
164   // number of platform handles and ports needed to transfer this dispatcher
165   // across a message pipe.
166   //
167   // Must eventually be followed by a call to EndSerializeAndClose(). Note that
168   // StartSerialize() and EndSerialize() are always called in sequence, and
169   // only between calls to BeginTransit() and either (but not both)
170   // CompleteTransitAndClose() or CancelTransit().
171   //
172   // For this reason it is IMPERATIVE that the implementation ensure a
173   // consistent serializable state between BeginTransit() and
174   // CompleteTransitAndClose()/CancelTransit().
175   virtual void StartSerialize(uint32_t* num_bytes,
176                               uint32_t* num_ports,
177                               uint32_t* num_platform_handles);
178 
179   // Serializes this dispatcher into |destination|, |ports|, and |handles|.
180   // Returns true iff successful, false otherwise. In either case the dispatcher
181   // will close.
182   //
183   // NOTE: Transit MAY still fail after this call returns. Implementations
184   // should not assume PlatformHandle ownership has transferred until
185   // CompleteTransitAndClose() is called. In other words, if CancelTransit() is
186   // called, the implementation should retain its PlatformHandles in working
187   // condition.
188   virtual bool EndSerialize(void* destination,
189                             ports::PortName* ports,
190                             PlatformHandle* handles);
191 
192   // Does whatever is necessary to begin transit of the dispatcher.  This
193   // should return |true| if transit is OK, or false if the underlying resource
194   // is deemed busy by the implementation.
195   virtual bool BeginTransit();
196 
197   // Does whatever is necessary to complete transit of the dispatcher, including
198   // closure. This is only called upon successfully transmitting an outgoing
199   // message containing this serialized dispatcher.
200   virtual void CompleteTransitAndClose();
201 
202   // Does whatever is necessary to cancel transit of the dispatcher. The
203   // dispatcher should remain in a working state and resume normal operation.
204   virtual void CancelTransit();
205 
206   // Deserializes a specific dispatcher type from an incoming message.
207   static scoped_refptr<Dispatcher> Deserialize(Type type,
208                                                const void* bytes,
209                                                size_t num_bytes,
210                                                const ports::PortName* ports,
211                                                size_t num_ports,
212                                                PlatformHandle* platform_handles,
213                                                size_t platform_handle_count);
214 
215  protected:
216   friend class base::RefCountedThreadSafe<Dispatcher>;
217 
218   Dispatcher();
219   virtual ~Dispatcher();
220 
221   DISALLOW_COPY_AND_ASSIGN(Dispatcher);
222 };
223 
224 // So logging macros and |DCHECK_EQ()|, etc. work.
225 MOJO_SYSTEM_IMPL_EXPORT inline std::ostream& operator<<(std::ostream& out,
226                                                         Dispatcher::Type type) {
227   return out << static_cast<int>(type);
228 }
229 
230 }  // namespace core
231 }  // namespace mojo
232 
233 #endif  // MOJO_CORE_DISPATCHER_H_
234