blob: 827b18014f32c9e27146feab0aca010c23009b76 [file] [log] [blame]
Avi Drissmand387f0922022-09-14 20:51:311// Copyright 2013 The Chromium Authors
jam76bcf0c2015-10-02 21:01:282// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Ken Rockotdba46db2018-07-04 18:41:045#ifndef MOJO_CORE_CORE_H_
6#define MOJO_CORE_CORE_H_
jam76bcf0c2015-10-02 21:01:287
dcheng40c732a82016-04-22 00:57:388#include <memory>
lhchavez723b70d2016-12-22 20:42:499#include <string>
Hyowon Kim624a7aa72023-12-05 07:56:2810#include <string_view>
rockotce69a042016-01-26 19:23:2111#include <vector>
jam76bcf0c2015-10-02 21:01:2812
Avi Drissmand70f89a2023-01-11 23:52:5513#include "base/functional/callback.h"
Lei Zhangb8567682023-01-06 17:54:0414#include "base/memory/scoped_refptr.h"
jam76bcf0c2015-10-02 21:01:2815#include "base/synchronization/lock.h"
Patrick Monette643cdf62021-10-15 19:13:4216#include "base/task/single_thread_task_runner.h"
Ken Rockot0e45f802018-06-27 23:56:0117#include "build/build_config.h"
Ken Rockotdba46db2018-07-04 18:41:0418#include "mojo/core/dispatcher.h"
19#include "mojo/core/handle_signals_state.h"
20#include "mojo/core/handle_table.h"
21#include "mojo/core/node_controller.h"
22#include "mojo/core/system_impl_export.h"
rockot85dce0862015-11-13 01:33:5923#include "mojo/public/c/system/buffer.h"
24#include "mojo/public/c/system/data_pipe.h"
Ken Rockotf86cdb8b2018-05-19 23:35:0125#include "mojo/public/c/system/invitation.h"
rockot85dce0862015-11-13 01:33:5926#include "mojo/public/c/system/message_pipe.h"
rockot28a287e2016-05-24 02:51:3727#include "mojo/public/c/system/platform_handle.h"
Ken Rockot0db0bcf2018-07-12 22:01:1228#include "mojo/public/c/system/quota.h"
Ken Rockot13e55a32018-03-09 00:11:1929#include "mojo/public/c/system/trap.h"
rockot85dce0862015-11-13 01:33:5930#include "mojo/public/c/system/types.h"
jam76bcf0c2015-10-02 21:01:2831
32namespace mojo {
Ken Rockotdba46db2018-07-04 18:41:0433namespace core {
jam76bcf0c2015-10-02 21:01:2834
Ken Rockot062ff1a52018-04-23 20:42:3835class PlatformSharedMemoryMapping;
36
jam76bcf0c2015-10-02 21:01:2837// |Core| is an object that implements the Mojo system calls. All public methods
38// are thread-safe.
39class MOJO_SYSTEM_IMPL_EXPORT Core {
40 public:
lhchavez723b70d2016-12-22 20:42:4941 Core();
Peter Boströma8176282021-09-23 22:33:5642
43 Core(const Core&) = delete;
44 Core& operator=(const Core&) = delete;
45
jam76bcf0c2015-10-02 21:01:2846 virtual ~Core();
47
Ken Rockot898d796d52018-03-23 19:03:5248 static Core* Get();
49
rockotce69a042016-01-26 19:23:2150 // Called exactly once, shortly after construction, and before any other
51 // methods are called on this object.
Gabriel Charettee926fc12019-12-16 19:00:0252 void SetIOTaskRunner(
53 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner);
jam76bcf0c2015-10-02 21:01:2854
rockotce69a042016-01-26 19:23:2155 // Retrieves the NodeController for the current process.
56 NodeController* GetNodeController();
57
jam76bcf0c2015-10-02 21:01:2858 scoped_refptr<Dispatcher> GetDispatcher(MojoHandle handle);
Ken Rockot062ff1a52018-04-23 20:42:3859 scoped_refptr<Dispatcher> GetAndRemoveDispatcher(MojoHandle handle);
jam76bcf0c2015-10-02 21:01:2860
Ken Rockotea1716a02017-05-11 05:49:1061 // Creates a message pipe endpoint with an unbound peer port returned in
62 // |*peer|. Useful for setting up cross-process bootstrap message pipes. The
63 // returned message pipe handle is usable immediately by the caller.
64 //
65 // The value returned in |*peer| may be passed along with a broker client
66 // invitation. See SendBrokerClientInvitation() below.
Ken Rockotd86d1e42018-03-15 22:47:4367 MojoHandle CreatePartialMessagePipe(ports::PortRef* peer);
amistry6ad1e812016-06-06 05:36:3068
Ken Rockotea1716a02017-05-11 05:49:1069 // Like above but exchanges an existing ports::PortRef for a message pipe
70 // handle which wraps it.
Ken Rockotd86d1e42018-03-15 22:47:4371 MojoHandle CreatePartialMessagePipe(const ports::PortRef& port);
Ken Rockotea1716a02017-05-11 05:49:1072
73 // Sends a broker client invitation to |target_process| over the connection
74 // medium in |connection_params|. The other end of the connection medium in
75 // |connection_params| can be used within the target process to call
76 // AcceptBrokerClientInvitation() and complete the process's admission into
77 // this process graph.
78 //
79 // |attached_ports| is a list of named port references to be attached to the
80 // invitation. An attached port can be claimed (as a message pipe handle) by
81 // the invitee.
82 void SendBrokerClientInvitation(
Robert Sesek0e7f165a2020-11-20 21:31:4583 base::Process target_process,
Ken Rockotea1716a02017-05-11 05:49:1084 ConnectionParams connection_params,
85 const std::vector<std::pair<std::string, ports::PortRef>>& attached_ports,
86 const ProcessErrorCallback& process_error_callback);
87
Ken Rockotea1716a02017-05-11 05:49:1088 // Extracts a named message pipe endpoint from the broker client invitation
89 // accepted by this process. Must only be called after
90 // AcceptBrokerClientInvitation.
Ken Rockotd86d1e42018-03-15 22:47:4391 MojoHandle ExtractMessagePipeFromInvitation(const std::string& name);
rockotce69a042016-01-26 19:23:2192
sammcb0a39f8c2016-08-10 06:29:5493 // Called to connect to a peer process. This should be called only if there
94 // is no common ancestor for the processes involved within this mojo system.
95 // Both processes must call this function, each passing one end of a platform
Ken Rockot47f4e892017-05-18 20:30:2196 // channel. |port| is a port to be merged with the remote peer's port, which
97 // it will provide via the same API.
98 //
Ken Rockot277b84c2018-06-08 09:39:4899 // |connection_name| if non-empty guarantees that no other isolated
100 // connections exist in the calling process using the same name. This is
101 // useful for invitation endpoints that use a named server accepting multiple
102 // connections.
103 void ConnectIsolated(ConnectionParams connection_params,
104 const ports::PortRef& port,
Hyowon Kim85512d9e2023-11-30 01:36:59105 std::string_view connection_name);
sammcb0a39f8c2016-08-10 06:29:54106
rockotce69a042016-01-26 19:23:21107 MojoHandle AddDispatcher(scoped_refptr<Dispatcher> dispatcher);
108
109 // Adds new dispatchers for non-message-pipe handles received in a message.
110 // |dispatchers| and |handles| should be the same size.
111 bool AddDispatchersFromTransit(
112 const std::vector<Dispatcher::DispatcherInTransit>& dispatchers,
113 MojoHandle* handles);
114
Ken Rockot15b2b0b2017-06-12 20:36:05115 // Marks a set of handles as busy and acquires references to each of their
116 // dispatchers. The caller MUST eventually call ReleaseDispatchersForTransit()
Ken Rockot766e7662017-08-10 05:37:15117 // on the resulting |*dispatchers|. Note that |*dispatchers| contents are
118 // extended, not replaced, by this call.
Ken Rockot15b2b0b2017-06-12 20:36:05119 MojoResult AcquireDispatchersForTransit(
120 const MojoHandle* handles,
121 size_t num_handles,
122 std::vector<Dispatcher::DispatcherInTransit>* dispatchers);
123
124 // Releases dispatchers previously acquired by
125 // |AcquireDispatchersForTransit()|. |in_transit| should be |true| if the
126 // caller has fully serialized every dispatcher in |dispatchers|, in which
127 // case this will close and remove their handles from the handle table.
128 //
129 // If |in_transit| is false, this simply unmarks the dispatchers as busy,
130 // making them available for general use once again.
131 void ReleaseDispatchersForTransit(
132 const std::vector<Dispatcher::DispatcherInTransit>& dispatchers,
133 bool in_transit);
134
rockotce69a042016-01-26 19:23:21135 // Requests that the EDK tear itself down. |callback| will be called once
136 // the shutdown process is complete. Note that |callback| is always called
137 // asynchronously on the calling thread if said thread is running a message
138 // loop, and the calling thread must continue running a MessageLoop at least
139 // until the callback is called. If there is no running loop, the |callback|
140 // may be called from any thread. Beware!
Anand K. Mistryb6558d92019-11-07 01:16:27141 void RequestShutdown(base::OnceClosure callback);
rockotce69a042016-01-26 19:23:21142
jam76bcf0c2015-10-02 21:01:28143 // ---------------------------------------------------------------------------
144
145 // The following methods are essentially implementations of the Mojo Core
146 // functions of the Mojo API, with the C interface translated to C++ by
Ken Rockotdba46db2018-07-04 18:41:04147 // "mojo/core/embedder/entrypoints.cc". The best way to understand the
148 // contract of these methods is to look at the header files defining the
149 // corresponding API functions, referenced below.
jam76bcf0c2015-10-02 21:01:28150
151 // These methods correspond to the API functions defined in
rockot85dce0862015-11-13 01:33:59152 // "mojo/public/c/system/functions.h":
jam76bcf0c2015-10-02 21:01:28153 MojoTimeTicks GetTimeTicksNow();
154 MojoResult Close(MojoHandle handle);
rockotc7949542017-03-16 09:03:47155 MojoResult QueryHandleSignalsState(MojoHandle handle,
156 MojoHandleSignalsState* signals_state);
Ken Rockot13e55a32018-03-09 00:11:19157 MojoResult CreateTrap(MojoTrapEventHandler handler,
158 const MojoCreateTrapOptions* options,
159 MojoHandle* trap_handle);
160 MojoResult AddTrigger(MojoHandle trap_handle,
161 MojoHandle handle,
162 MojoHandleSignals signals,
163 MojoTriggerCondition condition,
164 uintptr_t context,
165 const MojoAddTriggerOptions* options);
166 MojoResult RemoveTrigger(MojoHandle trap_handle,
167 uintptr_t context,
168 const MojoRemoveTriggerOptions* options);
169 MojoResult ArmTrap(MojoHandle trap_handle,
170 const MojoArmTrapOptions* options,
Ken Rockot7831a952018-07-12 01:11:30171 uint32_t* num_blocking_events,
172 MojoTrapEvent* blocking_events);
Ken Rockotf3208fc2018-03-07 20:35:08173 MojoResult CreateMessage(const MojoCreateMessageOptions* options,
174 MojoMessageHandle* message_handle);
Ken Rockota2af2b232017-06-16 05:54:31175 MojoResult DestroyMessage(MojoMessageHandle message_handle);
Ken Rockotf3208fc2018-03-07 20:35:08176 MojoResult SerializeMessage(MojoMessageHandle message_handle,
177 const MojoSerializeMessageOptions* options);
Andrea Orru96e94342024-03-16 01:45:33178 MojoResult ReserveMessageCapacity(MojoMessageHandle message_handle,
179 uint32_t payload_buffer_size,
180 uint32_t* buffer_size);
Ken Rockot8e49dd72018-03-07 18:06:40181 MojoResult AppendMessageData(MojoMessageHandle message_handle,
182 uint32_t additional_payload_size,
183 const MojoHandle* handles,
184 uint32_t num_handles,
185 const MojoAppendMessageDataOptions* options,
186 void** buffer,
187 uint32_t* buffer_size);
188 MojoResult GetMessageData(MojoMessageHandle message_handle,
189 const MojoGetMessageDataOptions* options,
190 void** buffer,
191 uint32_t* num_bytes,
192 MojoHandle* handles,
193 uint32_t* num_handles);
Ken Rockotf3208fc2018-03-07 20:35:08194 MojoResult SetMessageContext(MojoMessageHandle message_handle,
195 uintptr_t context,
196 MojoMessageContextSerializer serializer,
197 MojoMessageContextDestructor destructor,
198 const MojoSetMessageContextOptions* options);
Ken Rockot65a6f7e2017-06-30 21:59:03199 MojoResult GetMessageContext(MojoMessageHandle message_handle,
Ken Rockotf3208fc2018-03-07 20:35:08200 const MojoGetMessageContextOptions* options,
201 uintptr_t* context);
jam76bcf0c2015-10-02 21:01:28202
203 // These methods correspond to the API functions defined in
rockot85dce0862015-11-13 01:33:59204 // "mojo/public/c/system/message_pipe.h":
Ken Rockot61a3aab2017-06-20 16:19:57205 MojoResult CreateMessagePipe(const MojoCreateMessagePipeOptions* options,
206 MojoHandle* message_pipe_handle0,
207 MojoHandle* message_pipe_handle1);
jam76bcf0c2015-10-02 21:01:28208 MojoResult WriteMessage(MojoHandle message_pipe_handle,
Ken Rockot349df722017-06-16 05:48:49209 MojoMessageHandle message_handle,
Ken Rockotc12080c2018-05-03 18:10:21210 const MojoWriteMessageOptions* options);
jam76bcf0c2015-10-02 21:01:28211 MojoResult ReadMessage(MojoHandle message_pipe_handle,
Ken Rockotc12080c2018-05-03 18:10:21212 const MojoReadMessageOptions* options,
213 MojoMessageHandle* message_handle);
214 MojoResult FuseMessagePipes(MojoHandle handle0,
215 MojoHandle handle1,
216 const MojoFuseMessagePipesOptions* options);
Ken Rockot5d983722017-05-31 04:46:57217 MojoResult NotifyBadMessage(MojoMessageHandle message_handle,
rockotb46bf912016-06-11 23:18:16218 const char* error,
Ken Rockotc12080c2018-05-03 18:10:21219 size_t error_num_bytes,
220 const MojoNotifyBadMessageOptions* options);
jam76bcf0c2015-10-02 21:01:28221
222 // These methods correspond to the API functions defined in
rockot85dce0862015-11-13 01:33:59223 // "mojo/public/c/system/data_pipe.h":
Ken Rockot61a3aab2017-06-20 16:19:57224 MojoResult CreateDataPipe(const MojoCreateDataPipeOptions* options,
225 MojoHandle* data_pipe_producer_handle,
226 MojoHandle* data_pipe_consumer_handle);
jam76bcf0c2015-10-02 21:01:28227 MojoResult WriteData(MojoHandle data_pipe_producer_handle,
228 const void* elements,
229 uint32_t* num_bytes,
Ken Rockotc12080c2018-05-03 18:10:21230 const MojoWriteDataOptions* options);
jam76bcf0c2015-10-02 21:01:28231 MojoResult BeginWriteData(MojoHandle data_pipe_producer_handle,
Ken Rockotc12080c2018-05-03 18:10:21232 const MojoBeginWriteDataOptions* options,
jam76bcf0c2015-10-02 21:01:28233 void** buffer,
Ken Rockotc12080c2018-05-03 18:10:21234 uint32_t* buffer_num_bytes);
jam76bcf0c2015-10-02 21:01:28235 MojoResult EndWriteData(MojoHandle data_pipe_producer_handle,
Ken Rockotc12080c2018-05-03 18:10:21236 uint32_t num_bytes_written,
237 const MojoEndWriteDataOptions* options);
jam76bcf0c2015-10-02 21:01:28238 MojoResult ReadData(MojoHandle data_pipe_consumer_handle,
Ken Rockotc12080c2018-05-03 18:10:21239 const MojoReadDataOptions* options,
jam76bcf0c2015-10-02 21:01:28240 void* elements,
Ken Rockotc12080c2018-05-03 18:10:21241 uint32_t* num_bytes);
jam76bcf0c2015-10-02 21:01:28242 MojoResult BeginReadData(MojoHandle data_pipe_consumer_handle,
Ken Rockotc12080c2018-05-03 18:10:21243 const MojoBeginReadDataOptions* options,
jam76bcf0c2015-10-02 21:01:28244 const void** buffer,
Ken Rockotc12080c2018-05-03 18:10:21245 uint32_t* buffer_num_bytes);
jam76bcf0c2015-10-02 21:01:28246 MojoResult EndReadData(MojoHandle data_pipe_consumer_handle,
Ken Rockotc12080c2018-05-03 18:10:21247 uint32_t num_bytes_read,
248 const MojoEndReadDataOptions* options);
jam76bcf0c2015-10-02 21:01:28249
250 // These methods correspond to the API functions defined in
rockot85dce0862015-11-13 01:33:59251 // "mojo/public/c/system/buffer.h":
Ken Rockotc12080c2018-05-03 18:10:21252 MojoResult CreateSharedBuffer(uint64_t num_bytes,
253 const MojoCreateSharedBufferOptions* options,
Ken Rockot61a3aab2017-06-20 16:19:57254 MojoHandle* shared_buffer_handle);
jam76bcf0c2015-10-02 21:01:28255 MojoResult DuplicateBufferHandle(
256 MojoHandle buffer_handle,
257 const MojoDuplicateBufferHandleOptions* options,
258 MojoHandle* new_buffer_handle);
259 MojoResult MapBuffer(MojoHandle buffer_handle,
260 uint64_t offset,
261 uint64_t num_bytes,
Ken Rockotc12080c2018-05-03 18:10:21262 const MojoMapBufferOptions* options,
263 void** buffer);
jam76bcf0c2015-10-02 21:01:28264 MojoResult UnmapBuffer(void* buffer);
Lei Zhang7b818882018-03-24 01:38:40265 MojoResult GetBufferInfo(MojoHandle buffer_handle,
Ken Rockotc12080c2018-05-03 18:10:21266 const MojoGetBufferInfoOptions* options,
Lei Zhang7b818882018-03-24 01:38:40267 MojoSharedBufferInfo* info);
jam76bcf0c2015-10-02 21:01:28268
rockot28a287e2016-05-24 02:51:37269 // These methods correspond to the API functions defined in
270 // "mojo/public/c/system/platform_handle.h".
Ken Rockota22cf312018-06-21 19:56:54271 MojoResult WrapPlatformHandle(const MojoPlatformHandle* platform_handle,
272 const MojoWrapPlatformHandleOptions* options,
273 MojoHandle* mojo_handle);
274 MojoResult UnwrapPlatformHandle(
rockot28a287e2016-05-24 02:51:37275 MojoHandle mojo_handle,
Ken Rockot88be0452018-05-16 17:31:04276 const MojoUnwrapPlatformHandleOptions* options,
277 MojoPlatformHandle* platform_handle);
278 MojoResult WrapPlatformSharedMemoryRegion(
279 const MojoPlatformHandle* platform_handles,
280 uint32_t num_platform_handles,
281 uint64_t size,
282 const MojoSharedBufferGuid* guid,
283 MojoPlatformSharedMemoryRegionAccessMode access_mode,
284 const MojoWrapPlatformSharedMemoryRegionOptions* options,
285 MojoHandle* mojo_handle);
286 MojoResult UnwrapPlatformSharedMemoryRegion(
287 MojoHandle mojo_handle,
288 const MojoUnwrapPlatformSharedMemoryRegionOptions* options,
289 MojoPlatformHandle* platform_handles,
290 uint32_t* num_platform_handles,
291 uint64_t* size,
Ken Rockot61a3aab2017-06-20 16:19:57292 MojoSharedBufferGuid* guid,
Ken Rockot88be0452018-05-16 17:31:04293 MojoPlatformSharedMemoryRegionAccessMode* access_mode);
rockot28a287e2016-05-24 02:51:37294
Ken Rockotf86cdb8b2018-05-19 23:35:01295 // Invitation API.
296 MojoResult CreateInvitation(const MojoCreateInvitationOptions* options,
297 MojoHandle* invitation_handle);
298 MojoResult AttachMessagePipeToInvitation(
299 MojoHandle invitation_handle,
Ken Rockot189566cd2018-05-24 21:04:17300 const void* name,
301 uint32_t name_num_bytes,
Ken Rockotf86cdb8b2018-05-19 23:35:01302 const MojoAttachMessagePipeToInvitationOptions* options,
303 MojoHandle* message_pipe_handle);
304 MojoResult ExtractMessagePipeFromInvitation(
305 MojoHandle invitation_handle,
Ken Rockot189566cd2018-05-24 21:04:17306 const void* name,
307 uint32_t name_num_bytes,
Ken Rockotf86cdb8b2018-05-19 23:35:01308 const MojoExtractMessagePipeFromInvitationOptions* options,
309 MojoHandle* message_pipe_handle);
310 MojoResult SendInvitation(
311 MojoHandle invitation_handle,
312 const MojoPlatformProcessHandle* process_handle,
313 const MojoInvitationTransportEndpoint* transport_endpoint,
314 MojoProcessErrorHandler error_handler,
315 uintptr_t error_handler_context,
316 const MojoSendInvitationOptions* options);
317 MojoResult AcceptInvitation(
318 const MojoInvitationTransportEndpoint* transport_endpoint,
319 const MojoAcceptInvitationOptions* options,
320 MojoHandle* invitation_handle);
321
Ken Rockot0db0bcf2018-07-12 22:01:12322 // Quota API.
323 MojoResult SetQuota(MojoHandle handle,
324 MojoQuotaType type,
325 uint64_t limit,
326 const MojoSetQuotaOptions* options);
327 MojoResult QueryQuota(MojoHandle handle,
328 MojoQuotaType type,
329 const MojoQueryQuotaOptions* options,
330 uint64_t* limit,
331 uint64_t* usage);
332
Ken Rockotf6a42072020-06-03 23:57:24333 MojoResult SetDefaultProcessErrorHandler(
334 MojoDefaultProcessErrorHandler handler,
335 const MojoSetDefaultProcessErrorHandlerOptions* options);
336
rockotce69a042016-01-26 19:23:21337 void GetActiveHandlesForTest(std::vector<MojoHandle>* handles);
jam76bcf0c2015-10-02 21:01:28338
rockotce69a042016-01-26 19:23:21339 private:
rockotce69a042016-01-26 19:23:21340 // Used to pass ownership of our NodeController over to the IO thread in the
341 // event that we're torn down before said thread.
342 static void PassNodeControllerToIOThread(
dcheng40c732a82016-04-22 00:57:38343 std::unique_ptr<NodeController> node_controller);
jam76bcf0c2015-10-02 21:01:28344
rockot935f2632016-02-20 03:40:59345 // Guards node_controller_.
346 //
347 // TODO(rockot): Consider removing this. It's only needed because we
348 // initialize node_controller_ lazily and that may happen on any thread.
349 // Otherwise it's effectively const and shouldn't need to be guarded.
350 //
351 // We can get rid of lazy initialization if we defer Mojo initialization far
352 // enough that zygotes don't do it. The zygote can't create a NodeController.
353 base::Lock node_controller_lock_;
354
rockotce69a042016-01-26 19:23:21355 // This is lazily initialized on first access. Always use GetNodeController()
356 // to access it.
dcheng40c732a82016-04-22 00:57:38357 std::unique_ptr<NodeController> node_controller_;
rockotce69a042016-01-26 19:23:21358
rockot160577e92016-08-03 20:24:44359 // The default callback to invoke, if any, when a process error is reported
360 // but cannot be associated with a specific process.
361 ProcessErrorCallback default_process_error_callback_;
362
erikchen337e9da2017-06-09 17:49:45363 std::unique_ptr<HandleTable> handles_;
jam76bcf0c2015-10-02 21:01:28364
365 base::Lock mapping_table_lock_; // Protects |mapping_table_|.
Ken Rockot062ff1a52018-04-23 20:42:38366
367 using MappingTable =
368 std::unordered_map<void*, std::unique_ptr<PlatformSharedMemoryMapping>>;
jam76bcf0c2015-10-02 21:01:28369 MappingTable mapping_table_;
jam76bcf0c2015-10-02 21:01:28370};
371
Ken Rockotdba46db2018-07-04 18:41:04372} // namespace core
jam76bcf0c2015-10-02 21:01:28373} // namespace mojo
374
Ken Rockotdba46db2018-07-04 18:41:04375#endif // MOJO_CORE_CORE_H_