Home | History | Annotate | Download | only in core
      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