Home | History | Annotate | Download | only in system
      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_CORE_H_
      6 #define MOJO_EDK_SYSTEM_CORE_H_
      7 
      8 #include <memory>
      9 #include <vector>
     10 
     11 #include "base/callback.h"
     12 #include "base/macros.h"
     13 #include "base/memory/ref_counted.h"
     14 #include "base/memory/shared_memory_handle.h"
     15 #include "base/synchronization/lock.h"
     16 #include "base/task_runner.h"
     17 #include "mojo/edk/embedder/scoped_platform_handle.h"
     18 #include "mojo/edk/system/dispatcher.h"
     19 #include "mojo/edk/system/handle_signals_state.h"
     20 #include "mojo/edk/system/handle_table.h"
     21 #include "mojo/edk/system/mapping_table.h"
     22 #include "mojo/edk/system/node_controller.h"
     23 #include "mojo/edk/system/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/message_pipe.h"
     27 #include "mojo/public/c/system/platform_handle.h"
     28 #include "mojo/public/c/system/types.h"
     29 #include "mojo/public/cpp/system/message_pipe.h"
     30 
     31 namespace base {
     32 class PortProvider;
     33 }
     34 
     35 namespace mojo {
     36 namespace edk {
     37 
     38 // |Core| is an object that implements the Mojo system calls. All public methods
     39 // are thread-safe.
     40 class MOJO_SYSTEM_IMPL_EXPORT Core {
     41  public:
     42   explicit Core();
     43   virtual ~Core();
     44 
     45   // Called exactly once, shortly after construction, and before any other
     46   // methods are called on this object.
     47   void SetIOTaskRunner(scoped_refptr<base::TaskRunner> io_task_runner);
     48 
     49   // Retrieves the NodeController for the current process.
     50   NodeController* GetNodeController();
     51 
     52   scoped_refptr<Dispatcher> GetDispatcher(MojoHandle handle);
     53 
     54   // Called in the parent process any time a new child is launched.
     55   void AddChild(base::ProcessHandle process_handle,
     56                 ScopedPlatformHandle platform_handle,
     57                 const std::string& child_token,
     58                 const ProcessErrorCallback& process_error_callback);
     59 
     60   // Called in the parent process when a child process fails to launch.
     61   void ChildLaunchFailed(const std::string& child_token);
     62 
     63   // Called in a child process exactly once during early initialization.
     64   void InitChild(ScopedPlatformHandle platform_handle);
     65 
     66   // Creates a message pipe endpoint associated with |token|, which a child
     67   // holding the token can later locate and connect to.
     68   ScopedMessagePipeHandle CreateParentMessagePipe(
     69       const std::string& token, const std::string& child_token);
     70 
     71   // Creates a message pipe endpoint and connects it to a pipe the parent has
     72   // associated with |token|.
     73   ScopedMessagePipeHandle CreateChildMessagePipe(const std::string& token);
     74 
     75   // Sets the mach port provider for this process.
     76   void SetMachPortProvider(base::PortProvider* port_provider);
     77 
     78   MojoHandle AddDispatcher(scoped_refptr<Dispatcher> dispatcher);
     79 
     80   // Adds new dispatchers for non-message-pipe handles received in a message.
     81   // |dispatchers| and |handles| should be the same size.
     82   bool AddDispatchersFromTransit(
     83       const std::vector<Dispatcher::DispatcherInTransit>& dispatchers,
     84       MojoHandle* handles);
     85 
     86   // See "mojo/edk/embedder/embedder.h" for more information on these functions.
     87   MojoResult CreatePlatformHandleWrapper(ScopedPlatformHandle platform_handle,
     88                                          MojoHandle* wrapper_handle);
     89 
     90   MojoResult PassWrappedPlatformHandle(MojoHandle wrapper_handle,
     91                                        ScopedPlatformHandle* platform_handle);
     92 
     93   MojoResult CreateSharedBufferWrapper(
     94       base::SharedMemoryHandle shared_memory_handle,
     95       size_t num_bytes,
     96       bool read_only,
     97       MojoHandle* mojo_wrapper_handle);
     98 
     99   MojoResult PassSharedMemoryHandle(
    100       MojoHandle mojo_handle,
    101       base::SharedMemoryHandle* shared_memory_handle,
    102       size_t* num_bytes,
    103       bool* read_only);
    104 
    105   // Requests that the EDK tear itself down. |callback| will be called once
    106   // the shutdown process is complete. Note that |callback| is always called
    107   // asynchronously on the calling thread if said thread is running a message
    108   // loop, and the calling thread must continue running a MessageLoop at least
    109   // until the callback is called. If there is no running loop, the |callback|
    110   // may be called from any thread. Beware!
    111   void RequestShutdown(const base::Closure& callback);
    112 
    113   MojoResult SetProperty(MojoPropertyType type, const void* value);
    114 
    115   // ---------------------------------------------------------------------------
    116 
    117   // The following methods are essentially implementations of the Mojo Core
    118   // functions of the Mojo API, with the C interface translated to C++ by
    119   // "mojo/edk/embedder/entrypoints.cc". The best way to understand the contract
    120   // of these methods is to look at the header files defining the corresponding
    121   // API functions, referenced below.
    122 
    123   // These methods correspond to the API functions defined in
    124   // "mojo/public/c/system/functions.h":
    125   MojoTimeTicks GetTimeTicksNow();
    126   MojoResult Close(MojoHandle handle);
    127   MojoResult Wait(MojoHandle handle,
    128                   MojoHandleSignals signals,
    129                   MojoDeadline deadline,
    130                   MojoHandleSignalsState* signals_state);
    131   MojoResult WaitMany(const MojoHandle* handles,
    132                       const MojoHandleSignals* signals,
    133                       uint32_t num_handles,
    134                       MojoDeadline deadline,
    135                       uint32_t* result_index,
    136                       MojoHandleSignalsState* signals_states);
    137   MojoResult Watch(MojoHandle handle,
    138                    MojoHandleSignals signals,
    139                    MojoWatchCallback callback,
    140                    uintptr_t context);
    141   MojoResult CancelWatch(MojoHandle handle, uintptr_t context);
    142   MojoResult AllocMessage(uint32_t num_bytes,
    143                           const MojoHandle* handles,
    144                           uint32_t num_handles,
    145                           MojoAllocMessageFlags flags,
    146                           MojoMessageHandle* message);
    147   MojoResult FreeMessage(MojoMessageHandle message);
    148   MojoResult GetMessageBuffer(MojoMessageHandle message, void** buffer);
    149   MojoResult GetProperty(MojoPropertyType type, void* value);
    150 
    151   // These methods correspond to the API functions defined in
    152   // "mojo/public/c/system/wait_set.h":
    153   MojoResult CreateWaitSet(MojoHandle* wait_set_handle);
    154   MojoResult AddHandle(MojoHandle wait_set_handle,
    155                        MojoHandle handle,
    156                        MojoHandleSignals signals);
    157   MojoResult RemoveHandle(MojoHandle wait_set_handle,
    158                           MojoHandle handle);
    159   MojoResult GetReadyHandles(MojoHandle wait_set_handle,
    160                              uint32_t* count,
    161                              MojoHandle* handles,
    162                              MojoResult* results,
    163                              MojoHandleSignalsState* signals_states);
    164 
    165   // These methods correspond to the API functions defined in
    166   // "mojo/public/c/system/message_pipe.h":
    167   MojoResult CreateMessagePipe(
    168       const MojoCreateMessagePipeOptions* options,
    169       MojoHandle* message_pipe_handle0,
    170       MojoHandle* message_pipe_handle1);
    171   MojoResult WriteMessage(MojoHandle message_pipe_handle,
    172                           const void* bytes,
    173                           uint32_t num_bytes,
    174                           const MojoHandle* handles,
    175                           uint32_t num_handles,
    176                           MojoWriteMessageFlags flags);
    177   MojoResult WriteMessageNew(MojoHandle message_pipe_handle,
    178                              MojoMessageHandle message,
    179                              MojoWriteMessageFlags flags);
    180   MojoResult ReadMessage(MojoHandle message_pipe_handle,
    181                          void* bytes,
    182                          uint32_t* num_bytes,
    183                          MojoHandle* handles,
    184                          uint32_t* num_handles,
    185                          MojoReadMessageFlags flags);
    186   MojoResult ReadMessageNew(MojoHandle message_pipe_handle,
    187                             MojoMessageHandle* message,
    188                             uint32_t* num_bytes,
    189                             MojoHandle* handles,
    190                             uint32_t* num_handles,
    191                             MojoReadMessageFlags flags);
    192   MojoResult FuseMessagePipes(MojoHandle handle0, MojoHandle handle1);
    193   MojoResult NotifyBadMessage(MojoMessageHandle message,
    194                               const char* error,
    195                               size_t error_num_bytes);
    196 
    197   // These methods correspond to the API functions defined in
    198   // "mojo/public/c/system/data_pipe.h":
    199   MojoResult CreateDataPipe(
    200       const MojoCreateDataPipeOptions* options,
    201       MojoHandle* data_pipe_producer_handle,
    202       MojoHandle* data_pipe_consumer_handle);
    203   MojoResult WriteData(MojoHandle data_pipe_producer_handle,
    204                        const void* elements,
    205                        uint32_t* num_bytes,
    206                        MojoWriteDataFlags flags);
    207   MojoResult BeginWriteData(MojoHandle data_pipe_producer_handle,
    208                             void** buffer,
    209                             uint32_t* buffer_num_bytes,
    210                             MojoWriteDataFlags flags);
    211   MojoResult EndWriteData(MojoHandle data_pipe_producer_handle,
    212                           uint32_t num_bytes_written);
    213   MojoResult ReadData(MojoHandle data_pipe_consumer_handle,
    214                       void* elements,
    215                       uint32_t* num_bytes,
    216                       MojoReadDataFlags flags);
    217   MojoResult BeginReadData(MojoHandle data_pipe_consumer_handle,
    218                            const void** buffer,
    219                            uint32_t* buffer_num_bytes,
    220                            MojoReadDataFlags flags);
    221   MojoResult EndReadData(MojoHandle data_pipe_consumer_handle,
    222                          uint32_t num_bytes_read);
    223 
    224   // These methods correspond to the API functions defined in
    225   // "mojo/public/c/system/buffer.h":
    226   MojoResult CreateSharedBuffer(
    227       const MojoCreateSharedBufferOptions* options,
    228       uint64_t num_bytes,
    229       MojoHandle* shared_buffer_handle);
    230   MojoResult DuplicateBufferHandle(
    231       MojoHandle buffer_handle,
    232       const MojoDuplicateBufferHandleOptions* options,
    233       MojoHandle* new_buffer_handle);
    234   MojoResult MapBuffer(MojoHandle buffer_handle,
    235                        uint64_t offset,
    236                        uint64_t num_bytes,
    237                        void** buffer,
    238                        MojoMapBufferFlags flags);
    239   MojoResult UnmapBuffer(void* buffer);
    240 
    241   // These methods correspond to the API functions defined in
    242   // "mojo/public/c/system/platform_handle.h".
    243   MojoResult WrapPlatformHandle(const MojoPlatformHandle* platform_handle,
    244                                 MojoHandle* mojo_handle);
    245   MojoResult UnwrapPlatformHandle(MojoHandle mojo_handle,
    246                                   MojoPlatformHandle* platform_handle);
    247   MojoResult WrapPlatformSharedBufferHandle(
    248       const MojoPlatformHandle* platform_handle,
    249       size_t size,
    250       MojoPlatformSharedBufferHandleFlags flags,
    251       MojoHandle* mojo_handle);
    252   MojoResult UnwrapPlatformSharedBufferHandle(
    253       MojoHandle mojo_handle,
    254       MojoPlatformHandle* platform_handle,
    255       size_t* size,
    256       MojoPlatformSharedBufferHandleFlags* flags);
    257 
    258   void GetActiveHandlesForTest(std::vector<MojoHandle>* handles);
    259 
    260  private:
    261   MojoResult WaitManyInternal(const MojoHandle* handles,
    262                               const MojoHandleSignals* signals,
    263                               uint32_t num_handles,
    264                               MojoDeadline deadline,
    265                               uint32_t *result_index,
    266                               HandleSignalsState* signals_states);
    267 
    268   // Used to pass ownership of our NodeController over to the IO thread in the
    269   // event that we're torn down before said thread.
    270   static void PassNodeControllerToIOThread(
    271       std::unique_ptr<NodeController> node_controller);
    272 
    273   // Guards node_controller_.
    274   //
    275   // TODO(rockot): Consider removing this. It's only needed because we
    276   // initialize node_controller_ lazily and that may happen on any thread.
    277   // Otherwise it's effectively const and shouldn't need to be guarded.
    278   //
    279   // We can get rid of lazy initialization if we defer Mojo initialization far
    280   // enough that zygotes don't do it. The zygote can't create a NodeController.
    281   base::Lock node_controller_lock_;
    282 
    283   // This is lazily initialized on first access. Always use GetNodeController()
    284   // to access it.
    285   std::unique_ptr<NodeController> node_controller_;
    286 
    287   base::Lock handles_lock_;
    288   HandleTable handles_;
    289 
    290   base::Lock mapping_table_lock_;  // Protects |mapping_table_|.
    291   MappingTable mapping_table_;
    292 
    293   base::Lock property_lock_;
    294   // Properties that can be read using the MojoGetProperty() API.
    295   bool property_sync_call_allowed_ = true;
    296 
    297   DISALLOW_COPY_AND_ASSIGN(Core);
    298 };
    299 
    300 }  // namespace edk
    301 }  // namespace mojo
    302 
    303 #endif  // MOJO_EDK_SYSTEM_CORE_H_
    304