• 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_CORE_H_
6 #define MOJO_CORE_CORE_H_
7 
8 #include <memory>
9 #include <string>
10 #include <vector>
11 
12 #include "base/callback.h"
13 #include "base/macros.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/memory/shared_memory_handle.h"
16 #include "base/synchronization/lock.h"
17 #include "base/task_runner.h"
18 #include "build/build_config.h"
19 #include "mojo/core/dispatcher.h"
20 #include "mojo/core/handle_signals_state.h"
21 #include "mojo/core/handle_table.h"
22 #include "mojo/core/node_controller.h"
23 #include "mojo/core/system_impl_export.h"
24 #include "mojo/public/c/system/buffer.h"
25 #include "mojo/public/c/system/data_pipe.h"
26 #include "mojo/public/c/system/invitation.h"
27 #include "mojo/public/c/system/message_pipe.h"
28 #include "mojo/public/c/system/platform_handle.h"
29 #include "mojo/public/c/system/quota.h"
30 #include "mojo/public/c/system/trap.h"
31 #include "mojo/public/c/system/types.h"
32 
33 namespace base {
34 class PortProvider;
35 }
36 
37 namespace mojo {
38 namespace core {
39 
40 class MachPortRelay;
41 class PlatformSharedMemoryMapping;
42 
43 // |Core| is an object that implements the Mojo system calls. All public methods
44 // are thread-safe.
45 class MOJO_SYSTEM_IMPL_EXPORT Core {
46  public:
47   Core();
48   virtual ~Core();
49 
50   static Core* Get();
51 
52   // Called exactly once, shortly after construction, and before any other
53   // methods are called on this object.
54   void SetIOTaskRunner(scoped_refptr<base::TaskRunner> io_task_runner);
55 
56   // Retrieves the NodeController for the current process.
57   NodeController* GetNodeController();
58 
59   scoped_refptr<Dispatcher> GetDispatcher(MojoHandle handle);
60   scoped_refptr<Dispatcher> GetAndRemoveDispatcher(MojoHandle handle);
61 
62   void SetDefaultProcessErrorCallback(const ProcessErrorCallback& callback);
63 
64   // Creates a message pipe endpoint with an unbound peer port returned in
65   // |*peer|. Useful for setting up cross-process bootstrap message pipes. The
66   // returned message pipe handle is usable immediately by the caller.
67   //
68   // The value returned in |*peer| may be passed along with a broker client
69   // invitation. See SendBrokerClientInvitation() below.
70   MojoHandle CreatePartialMessagePipe(ports::PortRef* peer);
71 
72   // Like above but exchanges an existing ports::PortRef for a message pipe
73   // handle which wraps it.
74   MojoHandle CreatePartialMessagePipe(const ports::PortRef& port);
75 
76   // Sends a broker client invitation to |target_process| over the connection
77   // medium in |connection_params|. The other end of the connection medium in
78   // |connection_params| can be used within the target process to call
79   // AcceptBrokerClientInvitation() and complete the process's admission into
80   // this process graph.
81   //
82   // |attached_ports| is a list of named port references to be attached to the
83   // invitation. An attached port can be claimed (as a message pipe handle) by
84   // the invitee.
85   void SendBrokerClientInvitation(
86       base::ProcessHandle target_process,
87       ConnectionParams connection_params,
88       const std::vector<std::pair<std::string, ports::PortRef>>& attached_ports,
89       const ProcessErrorCallback& process_error_callback);
90 
91   // Accepts an invitation via |connection_params|. The other end of the
92   // connection medium in |connection_params| must have been used by some other
93   // process to send an invitation.
94   void AcceptBrokerClientInvitation(ConnectionParams connection_params);
95 
96   // Extracts a named message pipe endpoint from the broker client invitation
97   // accepted by this process. Must only be called after
98   // AcceptBrokerClientInvitation.
99   MojoHandle ExtractMessagePipeFromInvitation(const std::string& name);
100 
101   // Called to connect to a peer process. This should be called only if there
102   // is no common ancestor for the processes involved within this mojo system.
103   // Both processes must call this function, each passing one end of a platform
104   // channel. |port| is a port to be merged with the remote peer's port, which
105   // it will provide via the same API.
106   //
107   // |connection_name| if non-empty guarantees that no other isolated
108   // connections exist in the calling process using the same name. This is
109   // useful for invitation endpoints that use a named server accepting multiple
110   // connections.
111   void ConnectIsolated(ConnectionParams connection_params,
112                        const ports::PortRef& port,
113                        base::StringPiece connection_name);
114 
115   // Sets the mach port provider for this process.
116   void SetMachPortProvider(base::PortProvider* port_provider);
117 
118 #if defined(OS_MACOSX) && !defined(OS_IOS)
119   MachPortRelay* GetMachPortRelay();
120 #endif
121 
122   MojoHandle AddDispatcher(scoped_refptr<Dispatcher> dispatcher);
123 
124   // Adds new dispatchers for non-message-pipe handles received in a message.
125   // |dispatchers| and |handles| should be the same size.
126   bool AddDispatchersFromTransit(
127       const std::vector<Dispatcher::DispatcherInTransit>& dispatchers,
128       MojoHandle* handles);
129 
130   // Marks a set of handles as busy and acquires references to each of their
131   // dispatchers. The caller MUST eventually call ReleaseDispatchersForTransit()
132   // on the resulting |*dispatchers|. Note that |*dispatchers| contents are
133   // extended, not replaced, by this call.
134   MojoResult AcquireDispatchersForTransit(
135       const MojoHandle* handles,
136       size_t num_handles,
137       std::vector<Dispatcher::DispatcherInTransit>* dispatchers);
138 
139   // Releases dispatchers previously acquired by
140   // |AcquireDispatchersForTransit()|. |in_transit| should be |true| if the
141   // caller has fully serialized every dispatcher in |dispatchers|, in which
142   // case this will close and remove their handles from the handle table.
143   //
144   // If |in_transit| is false, this simply unmarks the dispatchers as busy,
145   // making them available for general use once again.
146   void ReleaseDispatchersForTransit(
147       const std::vector<Dispatcher::DispatcherInTransit>& dispatchers,
148       bool in_transit);
149 
150   // Requests that the EDK tear itself down. |callback| will be called once
151   // the shutdown process is complete. Note that |callback| is always called
152   // asynchronously on the calling thread if said thread is running a message
153   // loop, and the calling thread must continue running a MessageLoop at least
154   // until the callback is called. If there is no running loop, the |callback|
155   // may be called from any thread. Beware!
156   void RequestShutdown(const base::Closure& callback);
157 
158   // ---------------------------------------------------------------------------
159 
160   // The following methods are essentially implementations of the Mojo Core
161   // functions of the Mojo API, with the C interface translated to C++ by
162   // "mojo/core/embedder/entrypoints.cc". The best way to understand the
163   // contract of these methods is to look at the header files defining the
164   // corresponding API functions, referenced below.
165 
166   // These methods correspond to the API functions defined in
167   // "mojo/public/c/system/functions.h":
168   MojoTimeTicks GetTimeTicksNow();
169   MojoResult Close(MojoHandle handle);
170   MojoResult QueryHandleSignalsState(MojoHandle handle,
171                                      MojoHandleSignalsState* signals_state);
172   MojoResult CreateTrap(MojoTrapEventHandler handler,
173                         const MojoCreateTrapOptions* options,
174                         MojoHandle* trap_handle);
175   MojoResult AddTrigger(MojoHandle trap_handle,
176                         MojoHandle handle,
177                         MojoHandleSignals signals,
178                         MojoTriggerCondition condition,
179                         uintptr_t context,
180                         const MojoAddTriggerOptions* options);
181   MojoResult RemoveTrigger(MojoHandle trap_handle,
182                            uintptr_t context,
183                            const MojoRemoveTriggerOptions* options);
184   MojoResult ArmTrap(MojoHandle trap_handle,
185                      const MojoArmTrapOptions* options,
186                      uint32_t* num_blocking_events,
187                      MojoTrapEvent* blocking_events);
188   MojoResult CreateMessage(const MojoCreateMessageOptions* options,
189                            MojoMessageHandle* message_handle);
190   MojoResult DestroyMessage(MojoMessageHandle message_handle);
191   MojoResult SerializeMessage(MojoMessageHandle message_handle,
192                               const MojoSerializeMessageOptions* options);
193   MojoResult AppendMessageData(MojoMessageHandle message_handle,
194                                uint32_t additional_payload_size,
195                                const MojoHandle* handles,
196                                uint32_t num_handles,
197                                const MojoAppendMessageDataOptions* options,
198                                void** buffer,
199                                uint32_t* buffer_size);
200   MojoResult GetMessageData(MojoMessageHandle message_handle,
201                             const MojoGetMessageDataOptions* options,
202                             void** buffer,
203                             uint32_t* num_bytes,
204                             MojoHandle* handles,
205                             uint32_t* num_handles);
206   MojoResult SetMessageContext(MojoMessageHandle message_handle,
207                                uintptr_t context,
208                                MojoMessageContextSerializer serializer,
209                                MojoMessageContextDestructor destructor,
210                                const MojoSetMessageContextOptions* options);
211   MojoResult GetMessageContext(MojoMessageHandle message_handle,
212                                const MojoGetMessageContextOptions* options,
213                                uintptr_t* context);
214 
215   // These methods correspond to the API functions defined in
216   // "mojo/public/c/system/message_pipe.h":
217   MojoResult CreateMessagePipe(const MojoCreateMessagePipeOptions* options,
218                                MojoHandle* message_pipe_handle0,
219                                MojoHandle* message_pipe_handle1);
220   MojoResult WriteMessage(MojoHandle message_pipe_handle,
221                           MojoMessageHandle message_handle,
222                           const MojoWriteMessageOptions* options);
223   MojoResult ReadMessage(MojoHandle message_pipe_handle,
224                          const MojoReadMessageOptions* options,
225                          MojoMessageHandle* message_handle);
226   MojoResult FuseMessagePipes(MojoHandle handle0,
227                               MojoHandle handle1,
228                               const MojoFuseMessagePipesOptions* options);
229   MojoResult NotifyBadMessage(MojoMessageHandle message_handle,
230                               const char* error,
231                               size_t error_num_bytes,
232                               const MojoNotifyBadMessageOptions* options);
233 
234   // These methods correspond to the API functions defined in
235   // "mojo/public/c/system/data_pipe.h":
236   MojoResult CreateDataPipe(const MojoCreateDataPipeOptions* options,
237                             MojoHandle* data_pipe_producer_handle,
238                             MojoHandle* data_pipe_consumer_handle);
239   MojoResult WriteData(MojoHandle data_pipe_producer_handle,
240                        const void* elements,
241                        uint32_t* num_bytes,
242                        const MojoWriteDataOptions* options);
243   MojoResult BeginWriteData(MojoHandle data_pipe_producer_handle,
244                             const MojoBeginWriteDataOptions* options,
245                             void** buffer,
246                             uint32_t* buffer_num_bytes);
247   MojoResult EndWriteData(MojoHandle data_pipe_producer_handle,
248                           uint32_t num_bytes_written,
249                           const MojoEndWriteDataOptions* options);
250   MojoResult ReadData(MojoHandle data_pipe_consumer_handle,
251                       const MojoReadDataOptions* options,
252                       void* elements,
253                       uint32_t* num_bytes);
254   MojoResult BeginReadData(MojoHandle data_pipe_consumer_handle,
255                            const MojoBeginReadDataOptions* options,
256                            const void** buffer,
257                            uint32_t* buffer_num_bytes);
258   MojoResult EndReadData(MojoHandle data_pipe_consumer_handle,
259                          uint32_t num_bytes_read,
260                          const MojoEndReadDataOptions* options);
261 
262   // These methods correspond to the API functions defined in
263   // "mojo/public/c/system/buffer.h":
264   MojoResult CreateSharedBuffer(uint64_t num_bytes,
265                                 const MojoCreateSharedBufferOptions* options,
266                                 MojoHandle* shared_buffer_handle);
267   MojoResult DuplicateBufferHandle(
268       MojoHandle buffer_handle,
269       const MojoDuplicateBufferHandleOptions* options,
270       MojoHandle* new_buffer_handle);
271   MojoResult MapBuffer(MojoHandle buffer_handle,
272                        uint64_t offset,
273                        uint64_t num_bytes,
274                        const MojoMapBufferOptions* options,
275                        void** buffer);
276   MojoResult UnmapBuffer(void* buffer);
277   MojoResult GetBufferInfo(MojoHandle buffer_handle,
278                            const MojoGetBufferInfoOptions* options,
279                            MojoSharedBufferInfo* info);
280 
281   // These methods correspond to the API functions defined in
282   // "mojo/public/c/system/platform_handle.h".
283   MojoResult WrapPlatformHandle(const MojoPlatformHandle* platform_handle,
284                                 const MojoWrapPlatformHandleOptions* options,
285                                 MojoHandle* mojo_handle);
286   MojoResult UnwrapPlatformHandle(
287       MojoHandle mojo_handle,
288       const MojoUnwrapPlatformHandleOptions* options,
289       MojoPlatformHandle* platform_handle);
290   MojoResult WrapPlatformSharedMemoryRegion(
291       const MojoPlatformHandle* platform_handles,
292       uint32_t num_platform_handles,
293       uint64_t size,
294       const MojoSharedBufferGuid* guid,
295       MojoPlatformSharedMemoryRegionAccessMode access_mode,
296       const MojoWrapPlatformSharedMemoryRegionOptions* options,
297       MojoHandle* mojo_handle);
298   MojoResult UnwrapPlatformSharedMemoryRegion(
299       MojoHandle mojo_handle,
300       const MojoUnwrapPlatformSharedMemoryRegionOptions* options,
301       MojoPlatformHandle* platform_handles,
302       uint32_t* num_platform_handles,
303       uint64_t* size,
304       MojoSharedBufferGuid* guid,
305       MojoPlatformSharedMemoryRegionAccessMode* access_mode);
306 
307   // Invitation API.
308   MojoResult CreateInvitation(const MojoCreateInvitationOptions* options,
309                               MojoHandle* invitation_handle);
310   MojoResult AttachMessagePipeToInvitation(
311       MojoHandle invitation_handle,
312       const void* name,
313       uint32_t name_num_bytes,
314       const MojoAttachMessagePipeToInvitationOptions* options,
315       MojoHandle* message_pipe_handle);
316   MojoResult ExtractMessagePipeFromInvitation(
317       MojoHandle invitation_handle,
318       const void* name,
319       uint32_t name_num_bytes,
320       const MojoExtractMessagePipeFromInvitationOptions* options,
321       MojoHandle* message_pipe_handle);
322   MojoResult SendInvitation(
323       MojoHandle invitation_handle,
324       const MojoPlatformProcessHandle* process_handle,
325       const MojoInvitationTransportEndpoint* transport_endpoint,
326       MojoProcessErrorHandler error_handler,
327       uintptr_t error_handler_context,
328       const MojoSendInvitationOptions* options);
329   MojoResult AcceptInvitation(
330       const MojoInvitationTransportEndpoint* transport_endpoint,
331       const MojoAcceptInvitationOptions* options,
332       MojoHandle* invitation_handle);
333 
334   // Quota API.
335   MojoResult SetQuota(MojoHandle handle,
336                       MojoQuotaType type,
337                       uint64_t limit,
338                       const MojoSetQuotaOptions* options);
339   MojoResult QueryQuota(MojoHandle handle,
340                         MojoQuotaType type,
341                         const MojoQueryQuotaOptions* options,
342                         uint64_t* limit,
343                         uint64_t* usage);
344 
345   void GetActiveHandlesForTest(std::vector<MojoHandle>* handles);
346 
347  private:
348   // Used to pass ownership of our NodeController over to the IO thread in the
349   // event that we're torn down before said thread.
350   static void PassNodeControllerToIOThread(
351       std::unique_ptr<NodeController> node_controller);
352 
353   // Guards node_controller_.
354   //
355   // TODO(rockot): Consider removing this. It's only needed because we
356   // initialize node_controller_ lazily and that may happen on any thread.
357   // Otherwise it's effectively const and shouldn't need to be guarded.
358   //
359   // We can get rid of lazy initialization if we defer Mojo initialization far
360   // enough that zygotes don't do it. The zygote can't create a NodeController.
361   base::Lock node_controller_lock_;
362 
363   // This is lazily initialized on first access. Always use GetNodeController()
364   // to access it.
365   std::unique_ptr<NodeController> node_controller_;
366 
367   // The default callback to invoke, if any, when a process error is reported
368   // but cannot be associated with a specific process.
369   ProcessErrorCallback default_process_error_callback_;
370 
371   std::unique_ptr<HandleTable> handles_;
372 
373   base::Lock mapping_table_lock_;  // Protects |mapping_table_|.
374 
375   using MappingTable =
376       std::unordered_map<void*, std::unique_ptr<PlatformSharedMemoryMapping>>;
377   MappingTable mapping_table_;
378 
379   DISALLOW_COPY_AND_ASSIGN(Core);
380 };
381 
382 }  // namespace core
383 }  // namespace mojo
384 
385 #endif  // MOJO_CORE_CORE_H_
386