aboutsummaryrefslogtreecommitdiff
path: root/mojo/edk/system/core.h
blob: 1f6d865d2348e11c9ce267eb9cc0e2a52a3aa3bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MOJO_EDK_SYSTEM_CORE_H_
#define MOJO_EDK_SYSTEM_CORE_H_

#include <memory>
#include <string>
#include <vector>

#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/shared_memory_handle.h"
#include "base/synchronization/lock.h"
#include "base/task_runner.h"
#include "mojo/edk/embedder/scoped_platform_handle.h"
#include "mojo/edk/system/dispatcher.h"
#include "mojo/edk/system/handle_signals_state.h"
#include "mojo/edk/system/handle_table.h"
#include "mojo/edk/system/mapping_table.h"
#include "mojo/edk/system/node_controller.h"
#include "mojo/edk/system/system_impl_export.h"
#include "mojo/public/c/system/buffer.h"
#include "mojo/public/c/system/data_pipe.h"
#include "mojo/public/c/system/message_pipe.h"
#include "mojo/public/c/system/platform_handle.h"
#include "mojo/public/c/system/types.h"
#include "mojo/public/c/system/watcher.h"
#include "mojo/public/cpp/system/message_pipe.h"

namespace base {
class PortProvider;
}

namespace mojo {
namespace edk {

// |Core| is an object that implements the Mojo system calls. All public methods
// are thread-safe.
class MOJO_SYSTEM_IMPL_EXPORT Core {
 public:
  Core();
  virtual ~Core();

  // Called exactly once, shortly after construction, and before any other
  // methods are called on this object.
  void SetIOTaskRunner(scoped_refptr<base::TaskRunner> io_task_runner);

  // Retrieves the NodeController for the current process.
  NodeController* GetNodeController();

  scoped_refptr<Dispatcher> GetDispatcher(MojoHandle handle);

  void SetDefaultProcessErrorCallback(const ProcessErrorCallback& callback);

  // Called in the parent process any time a new child is launched.
  void AddChild(base::ProcessHandle process_handle,
                ConnectionParams connection_params,
                const std::string& child_token,
                const ProcessErrorCallback& process_error_callback);

  // Called in the parent process when a child process fails to launch.
  void ChildLaunchFailed(const std::string& child_token);

  // Called to connect to a peer process. This should be called only if there
  // is no common ancestor for the processes involved within this mojo system.
  // Both processes must call this function, each passing one end of a platform
  // channel. This returns one end of a message pipe to each process.
  ScopedMessagePipeHandle ConnectToPeerProcess(ScopedPlatformHandle pipe_handle,
                                               const std::string& peer_token);
  void ClosePeerConnection(const std::string& peer_token);

  // Called in a child process exactly once during early initialization.
  void InitChild(ConnectionParams connection_params);

  // Creates a message pipe endpoint associated with |token|, which a child
  // holding the token can later locate and connect to.
  ScopedMessagePipeHandle CreateParentMessagePipe(
      const std::string& token, const std::string& child_token);

  // Creates a message pipe endpoint and connects it to a pipe the parent has
  // associated with |token|.
  ScopedMessagePipeHandle CreateChildMessagePipe(const std::string& token);

  // Sets the mach port provider for this process.
  void SetMachPortProvider(base::PortProvider* port_provider);

  MojoHandle AddDispatcher(scoped_refptr<Dispatcher> dispatcher);

  // Adds new dispatchers for non-message-pipe handles received in a message.
  // |dispatchers| and |handles| should be the same size.
  bool AddDispatchersFromTransit(
      const std::vector<Dispatcher::DispatcherInTransit>& dispatchers,
      MojoHandle* handles);

  // See "mojo/edk/embedder/embedder.h" for more information on these functions.
  MojoResult CreatePlatformHandleWrapper(ScopedPlatformHandle platform_handle,
                                         MojoHandle* wrapper_handle);

  MojoResult PassWrappedPlatformHandle(MojoHandle wrapper_handle,
                                       ScopedPlatformHandle* platform_handle);

  MojoResult CreateSharedBufferWrapper(
      base::SharedMemoryHandle shared_memory_handle,
      size_t num_bytes,
      bool read_only,
      MojoHandle* mojo_wrapper_handle);

  MojoResult PassSharedMemoryHandle(
      MojoHandle mojo_handle,
      base::SharedMemoryHandle* shared_memory_handle,
      size_t* num_bytes,
      bool* read_only);

  // Requests that the EDK tear itself down. |callback| will be called once
  // the shutdown process is complete. Note that |callback| is always called
  // asynchronously on the calling thread if said thread is running a message
  // loop, and the calling thread must continue running a MessageLoop at least
  // until the callback is called. If there is no running loop, the |callback|
  // may be called from any thread. Beware!
  void RequestShutdown(const base::Closure& callback);

  MojoResult SetProperty(MojoPropertyType type, const void* value);

  // ---------------------------------------------------------------------------

  // The following methods are essentially implementations of the Mojo Core
  // functions of the Mojo API, with the C interface translated to C++ by
  // "mojo/edk/embedder/entrypoints.cc". The best way to understand the contract
  // of these methods is to look at the header files defining the corresponding
  // API functions, referenced below.

  // These methods correspond to the API functions defined in
  // "mojo/public/c/system/functions.h":
  MojoTimeTicks GetTimeTicksNow();
  MojoResult Close(MojoHandle handle);
  MojoResult QueryHandleSignalsState(MojoHandle handle,
                                     MojoHandleSignalsState* signals_state);
  MojoResult CreateWatcher(MojoWatcherCallback callback,
                           MojoHandle* watcher_handle);
  MojoResult Watch(MojoHandle watcher_handle,
                   MojoHandle handle,
                   MojoHandleSignals signals,
                   uintptr_t context);
  MojoResult CancelWatch(MojoHandle watcher_handle, uintptr_t context);
  MojoResult ArmWatcher(MojoHandle watcher_handle,
                        uint32_t* num_ready_contexts,
                        uintptr_t* ready_contexts,
                        MojoResult* ready_results,
                        MojoHandleSignalsState* ready_signals_states);
  MojoResult AllocMessage(uint32_t num_bytes,
                          const MojoHandle* handles,
                          uint32_t num_handles,
                          MojoAllocMessageFlags flags,
                          MojoMessageHandle* message);
  MojoResult FreeMessage(MojoMessageHandle message);
  MojoResult GetMessageBuffer(MojoMessageHandle message, void** buffer);
  MojoResult GetProperty(MojoPropertyType type, void* value);

  // These methods correspond to the API functions defined in
  // "mojo/public/c/system/message_pipe.h":
  MojoResult CreateMessagePipe(
      const MojoCreateMessagePipeOptions* options,
      MojoHandle* message_pipe_handle0,
      MojoHandle* message_pipe_handle1);
  MojoResult WriteMessage(MojoHandle message_pipe_handle,
                          const void* bytes,
                          uint32_t num_bytes,
                          const MojoHandle* handles,
                          uint32_t num_handles,
                          MojoWriteMessageFlags flags);
  MojoResult WriteMessageNew(MojoHandle message_pipe_handle,
                             MojoMessageHandle message,
                             MojoWriteMessageFlags flags);
  MojoResult ReadMessage(MojoHandle message_pipe_handle,
                         void* bytes,
                         uint32_t* num_bytes,
                         MojoHandle* handles,
                         uint32_t* num_handles,
                         MojoReadMessageFlags flags);
  MojoResult ReadMessageNew(MojoHandle message_pipe_handle,
                            MojoMessageHandle* message,
                            uint32_t* num_bytes,
                            MojoHandle* handles,
                            uint32_t* num_handles,
                            MojoReadMessageFlags flags);
  MojoResult FuseMessagePipes(MojoHandle handle0, MojoHandle handle1);
  MojoResult NotifyBadMessage(MojoMessageHandle message,
                              const char* error,
                              size_t error_num_bytes);

  // These methods correspond to the API functions defined in
  // "mojo/public/c/system/data_pipe.h":
  MojoResult CreateDataPipe(
      const MojoCreateDataPipeOptions* options,
      MojoHandle* data_pipe_producer_handle,
      MojoHandle* data_pipe_consumer_handle);
  MojoResult WriteData(MojoHandle data_pipe_producer_handle,
                       const void* elements,
                       uint32_t* num_bytes,
                       MojoWriteDataFlags flags);
  MojoResult BeginWriteData(MojoHandle data_pipe_producer_handle,
                            void** buffer,
                            uint32_t* buffer_num_bytes,
                            MojoWriteDataFlags flags);
  MojoResult EndWriteData(MojoHandle data_pipe_producer_handle,
                          uint32_t num_bytes_written);
  MojoResult ReadData(MojoHandle data_pipe_consumer_handle,
                      void* elements,
                      uint32_t* num_bytes,
                      MojoReadDataFlags flags);
  MojoResult BeginReadData(MojoHandle data_pipe_consumer_handle,
                           const void** buffer,
                           uint32_t* buffer_num_bytes,
                           MojoReadDataFlags flags);
  MojoResult EndReadData(MojoHandle data_pipe_consumer_handle,
                         uint32_t num_bytes_read);

  // These methods correspond to the API functions defined in
  // "mojo/public/c/system/buffer.h":
  MojoResult CreateSharedBuffer(
      const MojoCreateSharedBufferOptions* options,
      uint64_t num_bytes,
      MojoHandle* shared_buffer_handle);
  MojoResult DuplicateBufferHandle(
      MojoHandle buffer_handle,
      const MojoDuplicateBufferHandleOptions* options,
      MojoHandle* new_buffer_handle);
  MojoResult MapBuffer(MojoHandle buffer_handle,
                       uint64_t offset,
                       uint64_t num_bytes,
                       void** buffer,
                       MojoMapBufferFlags flags);
  MojoResult UnmapBuffer(void* buffer);

  // These methods correspond to the API functions defined in
  // "mojo/public/c/system/platform_handle.h".
  MojoResult WrapPlatformHandle(const MojoPlatformHandle* platform_handle,
                                MojoHandle* mojo_handle);
  MojoResult UnwrapPlatformHandle(MojoHandle mojo_handle,
                                  MojoPlatformHandle* platform_handle);
  MojoResult WrapPlatformSharedBufferHandle(
      const MojoPlatformHandle* platform_handle,
      size_t size,
      MojoPlatformSharedBufferHandleFlags flags,
      MojoHandle* mojo_handle);
  MojoResult UnwrapPlatformSharedBufferHandle(
      MojoHandle mojo_handle,
      MojoPlatformHandle* platform_handle,
      size_t* size,
      MojoPlatformSharedBufferHandleFlags* flags);

  void GetActiveHandlesForTest(std::vector<MojoHandle>* handles);

 private:
  // Used to pass ownership of our NodeController over to the IO thread in the
  // event that we're torn down before said thread.
  static void PassNodeControllerToIOThread(
      std::unique_ptr<NodeController> node_controller);

  // Guards node_controller_.
  //
  // TODO(rockot): Consider removing this. It's only needed because we
  // initialize node_controller_ lazily and that may happen on any thread.
  // Otherwise it's effectively const and shouldn't need to be guarded.
  //
  // We can get rid of lazy initialization if we defer Mojo initialization far
  // enough that zygotes don't do it. The zygote can't create a NodeController.
  base::Lock node_controller_lock_;

  // This is lazily initialized on first access. Always use GetNodeController()
  // to access it.
  std::unique_ptr<NodeController> node_controller_;

  // The default callback to invoke, if any, when a process error is reported
  // but cannot be associated with a specific process.
  ProcessErrorCallback default_process_error_callback_;

  base::Lock handles_lock_;
  HandleTable handles_;

  base::Lock mapping_table_lock_;  // Protects |mapping_table_|.
  MappingTable mapping_table_;

  base::Lock property_lock_;
  // Properties that can be read using the MojoGetProperty() API.
  bool property_sync_call_allowed_ = true;

  DISALLOW_COPY_AND_ASSIGN(Core);
};

}  // namespace edk
}  // namespace mojo

#endif  // MOJO_EDK_SYSTEM_CORE_H_