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
mojo / core / embedder / README.md [blame]
# Mojo Core Embedder API
This document is a subset of the [Mojo documentation](/mojo/README.md).
[TOC]
## Overview
The Mojo Core Embedder API enables process to initialize and use Mojo for IPC,
using an implementation of Mojo Core that is statically linked into the
application. See the note about dynamic linking
[here](/mojo/README.md#Mojo-Core) for more information about an alternative
approach to Mojo Core initialization.
**NOTE:** Unless you are introducing a new binary entry point into the system
(*e.g.,* a new executable with a new `main()` definition), you probably don't
need to know anything about the Embedder API. Most processes defined in the
Chrome repo today already fully initialize Mojo Core so that all other public
Mojo APIs just work out of the box.
## Basic Initialization
As an embedder, initializing Mojo Core requires a single call to
`mojo::core::Init`:
```
#include "mojo/core/embedder/embedder.h"
int main(int argc, char** argv) {
mojo::core::Init();
// Now you can create message pipes, write messages, etc
return 0;
}
```
This enables local API calls to work, so message pipes *etc* can be created and
used. In some cases (particuarly many unit testing scenarios) this is
sufficient, but to support any actual multiprocess communication (e.g. sending
or accepting Mojo invitations), a second IPC initialization step is required.
## IPC Initialization
Internal Mojo IPC implementation requires a background `TaskRunner` on which it
can watch for inbound I/O from other processes. This is configured using a
`ScopedIPCSupport` object, which keeps IPC support alive through the extent of
its lifetime.
Typically an application will create a dedicated background thread and give its
`TaskRunner` to Mojo. Note that in Chromium, we use the existing "IO thread" in
the browser process and content child processes. In general, any thread used
for Mojo IPC support must be running a `base::MessagePumpType::IO` loop.
```
#include "base/threading/thread.h"
#include "mojo/core/embedder/embedder.h"
#include "mojo/core/embedder/scoped_ipc_support.h"
int main(int argc, char** argv) {
mojo::core::Init();
base::Thread ipc_thread("ipc!");
ipc_thread.StartWithOptions(
base::Thread::Options(base::MessagePumpType::IO, 0));
// As long as this object is alive, all Mojo API surface relevant to IPC
// connections is usable, and message pipes which span a process boundary will
// continue to function.
mojo::core::ScopedIPCSupport ipc_support(
ipc_thread.task_runner(),
mojo::core::ScopedIPCSupport::ShutdownPolicy::CLEAN);
return 0;
}
```
This process is now fully prepared to use Mojo IPC!
Note that all existing process types in Chromium already perform this setup
very early during startup.
## Connecting Two Processes
Once IPC is initialized, you can bootstrap connections to other processes by
using the public
[Invitations API](/mojo/public/cpp/system/README.md#Invitations).