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