summaryrefslogtreecommitdiffstats
path: root/mojo/edk/system/core.h
blob: 18da0ba375c744883f7a6e8a6ed0743517ccff36 (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
// 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 <vector>

#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.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/types.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:
  explicit 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);

  // Called in the parent process any time a new child is launched.
  void AddChild(base::ProcessHandle process_handle,
                ScopedPlatformHandle platform_handle);

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

  // Creates a message pipe endpoint connected to an endpoint in a remote
  // embedder. |platform_handle| is used as a channel to negotiate the
  // connection.
  ScopedMessagePipeHandle CreateMessagePipe(
      ScopedPlatformHandle platform_handle);

  // 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);

  // 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);

  // Watches on the given handle for the given signals, calling |callback| when
  // a signal is satisfied or when all signals become unsatisfiable. |callback|
  // must satisfy stringent requirements -- see |Awakable::Awake()| in
  // awakable.h. In particular, it must not call any Mojo system functions.
  MojoResult AsyncWait(MojoHandle handle,
                       MojoHandleSignals signals,
                       const base::Callback<void(MojoResult)>& callback);

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

  // 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 Wait(MojoHandle handle,
                  MojoHandleSignals signals,
                  MojoDeadline deadline,
                  MojoHandleSignalsState* signals_state);
  MojoResult WaitMany(const MojoHandle* handles,
                      const MojoHandleSignals* signals,
                      uint32_t num_handles,
                      MojoDeadline deadline,
                      uint32_t* result_index,
                      MojoHandleSignalsState* signals_states);
  MojoResult Watch(MojoHandle handle,
                   MojoHandleSignals signals,
                   MojoWatchCallback callback,
                   uintptr_t context);
  MojoResult CancelWatch(MojoHandle handle, uintptr_t context);

  // These methods correspond to the API functions defined in
  // "mojo/public/c/system/wait_set.h":
  MojoResult CreateWaitSet(MojoHandle* wait_set_handle);
  MojoResult AddHandle(MojoHandle wait_set_handle,
                       MojoHandle handle,
                       MojoHandleSignals signals);
  MojoResult RemoveHandle(MojoHandle wait_set_handle,
                          MojoHandle handle);
  MojoResult GetReadyHandles(MojoHandle wait_set_handle,
                             uint32_t* count,
                             MojoHandle* handles,
                             MojoResult* results,
                             MojoHandleSignalsState* signals_states);

  // 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 ReadMessage(MojoHandle message_pipe_handle,
                         void* bytes,
                         uint32_t* num_bytes,
                         MojoHandle* handles,
                         uint32_t* num_handles,
                         MojoReadMessageFlags flags);
  MojoResult FuseMessagePipes(MojoHandle handle0, MojoHandle handle1);

  // 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);

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

 private:
  MojoResult WaitManyInternal(const MojoHandle* handles,
                              const MojoHandleSignals* signals,
                              uint32_t num_handles,
                              MojoDeadline deadline,
                              uint32_t *result_index,
                              HandleSignalsState* signals_states);

  // 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(
      scoped_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.
  scoped_ptr<NodeController> node_controller_;

  base::Lock handles_lock_;
  HandleTable handles_;

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

  DISALLOW_COPY_AND_ASSIGN(Core);
};

}  // namespace edk
}  // namespace mojo

#endif  // MOJO_EDK_SYSTEM_CORE_H_