# Mojo C++ System API
This document is a subset of the [Mojo documentation](/mojo/README.md).

[TOC]

## Overview
The Mojo C++ System API provides a convenient set of helper classes and
functions for working with Mojo primitives. Unlike the low-level
[C API](/mojo/public/c/system/README.md) (upon which this is built) this library
takes advantage of C++ language features and common STL and `//base` types to
provide a slightly more idiomatic interface to the Mojo system layer, making it
generally easier to use.

This document provides a brief guide to API usage with example code snippets.
For a detailed API references please consult the headers in
[//mojo/public/cpp/system](https://cs.chromium.org/chromium/src/mojo/public/cpp/system/README.md).

Note that all API symbols referenced in this document are implicitly in the
top-level `mojo` namespace.

## Scoped, Typed Handles

All types of Mojo handles in the C API are simply opaque, integral `MojoHandle`
values. The C++ API has more strongly typed wrappers defined for different
handle types: `MessagePipeHandle`, `SharedBufferHandle`,
`DataPipeConsumerHandle`, `DataPipeProducerHandle`, `TrapHandle`, and
`InvitationHandle`.

Each of these also has a corresponding, move-only, scoped type for safer usage:
`ScopedMessagePipeHandle`, `ScopedSharedBufferHandle`, and so on. When a scoped
handle type is destroyed, its handle is automatically closed via `MojoClose`.
When working with raw handles you should **always** prefer to use one of the
scoped types for ownership.

Similar to `std::unique_ptr`, scoped handle types expose a `get()` method to get
at the underlying unscoped handle type as well as the `->` operator to
dereference the scoper and make calls directly on the underlying handle type.

## Message Pipes

There are two ways to create a new message pipe using the C++ API. You may
construct a `MessagePipe` object:

``` cpp
mojo::MessagePipe pipe;

// NOTE: Because pipes are bi-directional there is no implicit semantic
// difference between |handle0| or |handle1| here. They're just two ends of a
// pipe. The choice to treat one as a "client" and one as a "server" is entirely
// the API user's decision.
mojo::ScopedMessagePipeHandle client = std::move(pipe.handle0);
mojo::ScopedMessagePipeHandle server = std::move(pipe.handle1);
```

or you may call `CreateMessagePipe`:

``` cpp
mojo::ScopedMessagePipeHandle client;
mojo::ScopedMessagePipeHandle server;
mojo::CreateMessagePipe(nullptr, &client, &server);
```

There are also some helper functions for constructing message objects and
reading/writing them on pipes using the library's more strongly-typed C++
handles:

``` cpp
mojo::ScopedMessageHandle message;
mojo::AllocMessage(6, nullptr, 0, MOJO_ALLOC_MESSAGE_FLAG_NONE, &message);

void *buffer;
mojo::GetMessageBuffer(message.get(), &buffer);

constexpr std::string_view kMessage = "hello";
std::ranges::copy(kMessage, static_cast<char*>(buffer));

mojo::WriteMessageNew(client.get(), std::move(message),
                      MOJO_WRITE_MESSAGE_FLAG_NONE);

// Some time later...

mojo::ScopedMessageHandle received_message;
uint32_t num_bytes;
mojo::ReadMessageNew(server.get(), &received_message, &num_bytes, nullptr,
                     nullptr, MOJO_READ_MESSAGE_FLAG_NONE);
```

See [message_pipe.h](https://cs.chromium.org/chromium/src/mojo/public/cpp/system/message_pipe.h)
for detailed C++ message pipe API documentation.

## Data Pipes

Similar to [Message Pipes](#Message-Pipes), the C++ library has some simple
helpers for more strongly-typed data pipe usage:

``` cpp
mojo::DataPipe pipe;
mojo::ScopedDataPipeProducerHandle producer = std::move(pipe.producer_handle);
mojo::ScopedDataPipeConsumerHandle consumer = std::move(pipe.consumer_handle);

// Or alternatively:
mojo::ScopedDataPipeProducerHandle producer;
mojo::ScopedDataPipeConsumerHandle consumer;
mojo::CreateDataPipe(nullptr, producer, consumer);
```

C++ helpers which correspond directly to the
[Data Pipe C API](/mojo/public/c/system/README.md#Data-Pipes) for immediate and
two-phase I/O are provided as well. For example:

``` cpp
uint32_t num_bytes = 7;
producer.WriteData("hihihi", &num_bytes, MOJO_WRITE_DATA_FLAG_NONE);

// Some time later...

char buffer[64];
uint32_t num_bytes = 64;
consumer.ReadData(buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE);
```

See [data_pipe.h](https://cs.chromium.org/chromium/src/mojo/public/cpp/system/data_pipe.h)
for detailed C++ data pipe API documentation.

## Shared Buffers

A new shared buffer can be allocated like so:

``` cpp
mojo::ScopedSharedBufferHandle buffer =
    mojo::SharedBufferHandle::Create(4096);
```

This new handle can be cloned arbitrarily many times by using the underlying
handle's `Clone` method:

``` cpp
mojo::ScopedSharedBufferHandle another_handle =
    buffer->Clone(mojo::SharedBufferHandle::AccessMode::READ_WRITE);
mojo::ScopedSharedBufferHandle read_only_handle =
    buffer->Clone(mojo::SharedBufferHandle::AccessMode::READ_ONLY);
```

And finally the library also provides a scoper for mapping the shared buffer's
memory:

``` cpp
mojo::ScopedSharedBufferMapping mapping = buffer->Map(64);
static_cast<int*>(mapping.get())[0] = 42;

mojo::ScopedSharedBufferMapping another_mapping = buffer->MapAtOffset(64, 4);
static_cast<int*>(mapping.get())[0] = 43;
```

When `mapping` and `another_mapping` are destroyed, they automatically unmap
their respective memory regions.

See [buffer.h](https://cs.chromium.org/chromium/src/mojo/public/cpp/system/buffer.h)
for detailed C++ shared buffer API documentation.

## Native Platform Handles (File Descriptors, Windows Handles, *etc.*)

The C++ library provides several helpers for wrapping system handle types.
These are specifically useful when working with a few `//base` types, namely
`base::PlatformFile`, `base::SharedMemoryHandle` (deprecated), and various
strongly-typed shared memory region types like
`base::ReadOnlySharedMemoryRegion`. See
[platform_handle.h](https://cs.chromium.org/chromium/src/mojo/public/cpp/system/platform_handle.h)
for detailed C++ platform handle API documentation.

## Signals & Traps

For an introduction to the concepts of handle signals and traps, check out
the C API's documentation on
[Signals & Traps](/mojo/public/c/system/README.md#Signals-Traps).

### Querying Signals

Any C++ handle type's last known signaling state can be queried by calling the
`QuerySignalsState` method on the handle:

``` cpp
mojo::MessagePipe message_pipe;
mojo::DataPipe data_pipe;
mojo::HandleSignalsState a = message_pipe.handle0->QuerySignalsState();
mojo::HandleSignalsState b = data_pipe.consumer->QuerySignalsState();
```

The `HandleSignalsState` is a thin wrapper interface around the C API's
`MojoHandleSignalsState` structure with convenient accessors for testing
the signal bitmasks. Whereas when using the C API you might write:

``` c
struct MojoHandleSignalsState state;
MojoQueryHandleSignalsState(handle0, &state);
if (state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE) {
  // ...
}
```

the C++ API equivalent would be:

``` cpp
if (message_pipe.handle0->QuerySignalsState().readable()) {
  // ...
}
```

### Watching Handles

The [`mojo::SimpleWatcher`](https://cs.chromium.org/chromium/src/mojo/public/cpp/system/simple_watcher.h)
class serves as a convenient helper for using the
[low-level traps API](/mojo/public/c/system/README.md#Signals-Traps)
to watch a handle for signaling state changes. A `SimpleWatcher` is bound to a
single sequence and always dispatches its notifications on a
`base::SequencedTaskRunner`.

`SimpleWatcher` has two possible modes of operation, selected at construction
time by the `mojo::SimpleWatcher::ArmingPolicy` enum:

* `MANUAL` mode requires the user to manually call `Arm` and/or `ArmOrNotify`
  before any notifications will fire regarding the state of the watched handle.
  Every time the notification callback is run, the `SimpleWatcher` must be
  rearmed again before the next one can fire. See
  [Arming a Trap](/mojo/public/c/system/README.md#Arming-a-Trap) and the
  documentation in `SimpleWatcher`'s header.

* `AUTOMATIC` mode ensures that the `SimpleWatcher` always either is armed or
  has a pending notification task queued for execution.

`AUTOMATIC` mode is more convenient but can result in redundant notification
tasks, especially if the provided callback does not make a strong effort to
return the watched handle to an uninteresting signaling state (by *e.g.*,
reading all its available messages when notified of readability.)

Example usage:

``` cpp
class PipeReader {
 public:
  PipeReader(mojo::ScopedMessagePipeHandle pipe)
      : pipe_(std::move(pipe)),
        watcher_(mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC) {
    // NOTE: base::Unretained is safe because the callback can never be run
    // after SimpleWatcher destruction.
    watcher_.Watch(pipe_.get(), MOJO_HANDLE_SIGNAL_READABLE,
                   base::BindRepeating(&PipeReader::OnReadable,
                                       base::Unretained(this)));
  }

  ~PipeReader() {}

 private:
  void OnReadable(MojoResult result) {
    while (result == MOJO_RESULT_OK) {
      mojo::ScopedMessageHandle message;
      uint32_t num_bytes;
      result = mojo::ReadMessageNew(pipe_.get(), &message, &num_bytes, nullptr,
                                    nullptr, MOJO_READ_MESSAGE_FLAG_NONE);
      DCHECK_EQ(result, MOJO_RESULT_OK);
      messages_.emplace_back(std::move(message));
    }
  }

  mojo::ScopedMessagePipeHandle pipe_;
  mojo::SimpleWatcher watcher_;
  std::vector<mojo::ScopedMessageHandle> messages_;
};

mojo::MessagePipe pipe;
PipeReader reader(std::move(pipe.handle0));

// Written messages will asynchronously end up in |reader.messages_|.
WriteABunchOfStuff(pipe.handle1.get());
```

## Synchronous Waiting

The C++ System API defines some utilities to block a calling sequence while
waiting for one or more handles to change signaling state in an interesting way.
These threads combine usage of the
[low-level traps API](/mojo/public/c/system/README.md#Signals-Traps)
with common synchronization primitives (namely `base::WaitableEvent`.)

While these API features should be used sparingly, they are sometimes necessary.

See the documentation in
[wait.h](https://cs.chromium.org/chromium/src/mojo/public/cpp/system/wait.h)
and [wait_set.h](https://cs.chromium.org/chromium/src/mojo/public/cpp/system/wait_set.h)
for a more detailed API reference.

### Waiting On a Single Handle

The `mojo::Wait` function simply blocks the calling sequence until a given
signal mask is either partially satisfied or fully unsatisfiable on a given
handle.

``` cpp
mojo::MessagePipe pipe;
mojo::WriteMessageRaw(pipe.handle0.get(), "hey", 3, nullptr, nullptr,
                      MOJO_WRITE_MESSAGE_FLAG_NONE);
MojoResult result = mojo::Wait(pipe.handle1.get(), MOJO_HANDLE_SIGNAL_READABLE);
DCHECK_EQ(result, MOJO_RESULT_OK);

// Guaranteed to succeed because we know |handle1| is readable now.
mojo::ScopedMessageHandle message;
uint32_t num_bytes;
mojo::ReadMessageNew(pipe.handle1.get(), &num_bytes, nullptr, nullptr,
                     MOJO_READ_MESSAGE_FLAG_NONE);
```

`mojo::Wait` is most typically useful in limited testing scenarios.

### Waiting On Multiple Handles

`mojo::WaitMany` provides a simple API to wait on multiple handles
simultaneously, returning when any handle's given signal mask is either
partially satisfied or fully unsatisfiable.

``` cpp
mojo::MessagePipe a, b;
GoDoSomethingWithPipes(std:move(a.handle1), std::move(b.handle1));

mojo::MessagePipeHandle handles[2] = {a.handle0.get(), b.handle0.get()};
MojoHandleSignals signals[2] = {MOJO_HANDLE_SIGNAL_READABLE,
                                MOJO_HANDLE_SIGNAL_READABLE};
size_t ready_index;
MojoResult result = mojo::WaitMany(handles, signals, 2, &ready_index);
if (ready_index == 0) {
  // a.handle0 was ready.
} else {
  // b.handle0 was ready.
}
```

Similar to `mojo::Wait`, `mojo::WaitMany` is primarily useful in testing. When
waiting on multiple handles in production code, you should almost always instead
use a more efficient and more flexible `mojo::WaitSet` as described in the next
section.

### Waiting On Handles and Events Simultaneously

Typically when waiting on one or more handles to signal, the set of handles and
conditions being waited upon do not change much between consecutive blocking
waits. It's also often useful to be able to interrupt the blocking operation
as efficiently as possible.

[`mojo::WaitSet`](https://cs.chromium.org/chromium/src/mojo/public/cpp/system/wait_set.h)
is designed with these conditions in mind. A `WaitSet` maintains a persistent
set of (not-owned) Mojo handles and `base::WaitableEvent`s, which may be
explicitly added to or removed from the set at any time.

The `WaitSet` may be waited upon repeatedly, each time blocking the calling
sequence until either one of the handles attains an interesting signaling state
or one of the events is signaled. For example let's suppose we want to wait up
to 5 seconds for either one of two handles to become readable:

``` cpp
base::WaitableEvent timeout_event(
    base::WaitableEvent::ResetPolicy::MANUAL,
    base::WaitableEvent::InitialState::NOT_SIGNALED);
mojo::MessagePipe a, b;

GoDoStuffWithPipes(std::move(a.handle1), std::move(b.handle1));

mojo::WaitSet wait_set;
wait_set.AddHandle(a.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE);
wait_set.AddHandle(b.handle0.get(), MOJO_HANDLE_SIGNAL_READABLE);
wait_set.AddEvent(&timeout_event);

// Ensure the Wait() lasts no more than 5 seconds.
bg_thread->task_runner()->PostDelayedTask(FROM_HERE, base::BindOnce([](base::WaitableEvent* e) { e->Signal(); }, &timeout_event);
    base::Seconds(5));

base::WaitableEvent* ready_event = nullptr;
size_t num_ready_handles = 1;
mojo::Handle ready_handle;
MojoResult ready_result;
wait_set.Wait(&ready_event, &num_ready_handles, &ready_handle, &ready_result);

// The apex of thread-safety.
bg_thread->Stop();

if (ready_event) {
  // The event signaled...
}

if (num_ready_handles > 0) {
  // At least one of the handles signaled...
  // NOTE: This and the above condition are not mutually exclusive. If handle
  // signaling races with timeout, both things might be true.
}
```

## Invitations
Invitations are the means by which two processes can have Mojo IPC bootstrapped
between them. An invitation must be transmitted over some platform-specific IPC
primitive (*e.g.* a Windows named pipe or UNIX domain socket), and the public
[platform support library](/mojo/public/cpp/platform/README.md) provides some
lightweight, cross-platform abstractions for those primitives.

For any two processes looking to be connected, one must send an
`OutgoingInvitation` and the other must accept an `IncomingInvitation`. The
sender can attach named message pipe handles to the `OutgoingInvitation`, and
the receiver can extract them from its `IncomingInvitation`.

Basic usage might look something like this in the case where one process is
responsible for launching the other.

``` cpp
#include "base/command_line.h"
#include "base/process/launch.h"
#include "mojo/public/cpp/platform/platform_channel.h"
#include "mojo/public/cpp/system/invitation.h"
#include "mojo/public/cpp/system/message_pipe.h"

mojo::ScopedMessagePipeHandle LaunchAndConnectSomething() {
  // Under the hood, this is essentially always an OS pipe (domain socket pair,
  // Windows named pipe, Fuchsia channel, etc).
  mojo::PlatformChannel channel;

  mojo::OutgoingInvitation invitation;

  // Attach a message pipe to be extracted by the receiver. The other end of the
  // pipe is returned for us to use locally.
  mojo::ScopedMessagePipeHandle pipe =
      invitation->AttachMessagePipe("arbitrary pipe name");

  base::LaunchOptions options;
  base::CommandLine command_line("some_executable")
  channel.PrepareToPassRemoteEndpoint(&options, &command_line);
  base::Process child_process = base::LaunchProcess(command_line, options);
  channel.RemoteProcessLaunchAttempted();

  OutgoingInvitation::Send(std::move(invitation), child_process.Handle(),
                           channel.TakeLocalEndpoint());
  return pipe;
}
```

The launched process can in turn accept an `IncomingInvitation`:

``` cpp
#include "base/command_line.h"
#include "base/threading/thread.h"
#include "mojo/core/embedder/embedder.h"
#include "mojo/core/embedder/scoped_ipc_support.h"
#include "mojo/public/cpp/platform/platform_channel.h"
#include "mojo/public/cpp/system/invitation.h"
#include "mojo/public/cpp/system/message_pipe.h"

int main(int argc, char** argv) {
  // Basic Mojo initialization for a new process.
  mojo::core::Init();
  base::Thread ipc_thread("ipc!");
  ipc_thread.StartWithOptions(
      base::Thread::Options(base::MessagePumpType::IO, 0));
  mojo::core::ScopedIPCSupport ipc_support(
      ipc_thread.task_runner(),
      mojo::core::ScopedIPCSupport::ShutdownPolicy::CLEAN);

  // Accept an invitation.
  mojo::IncomingInvitation invitation = mojo::IncomingInvitation::Accept(
      mojo::PlatformChannel::RecoverPassedEndpointFromCommandLine(
          *base::CommandLine::ForCurrentProcess()));
  mojo::ScopedMessagePipeHandle pipe =
      invitation->ExtractMessagePipe("arbitrary pipe name");

  // etc...
  return GoListenForMessagesAndRunForever(std::move(pipe));
}
```

Now we have IPC initialized between the two processes.

Also keep in mind that bindings interfaces are just message pipes with some
semantic and syntactic sugar wrapping them, so you can use these primordial
message pipe handles as mojom interfaces. For example:

``` cpp
// Process A
mojo::OutgoingInvitation invitation;
auto pipe = invitation->AttachMessagePipe("x");
mojo::Receiver<foo::mojom::Bar> receiver(
    &bar_impl,
    mojo::PendingReceiver<foo::mojom::Bar>(std::move(pipe)));

// Process B
auto invitation = mojo::IncomingInvitation::Accept(...);
auto pipe = invitation->ExtractMessagePipe("x");
mojo::Remote<foo::mojom::Bar> bar(
    mojo::PendingRemote<foo::mojom::Bar>(std::move(pipe), 0));

// Will asynchronously invoke bar_impl.DoSomething() in process A.
bar->DoSomething();
```

And just to be sure, the usage here could be reversed: the invitation sender
could just as well treat its pipe endpoint as a `Remote<Bar>` while the receiver
treats theirs as a `PendingReceiver<Bar>` to be bound.

### Process Networks
Accepting an invitation admits the accepting process into the sender's connected
network of processes. Once this is done, it's possible for the newly admitted
process to establish communication with any other process in that network via
normal message pipe passing.

This does not mean that the invited process can proactively locate and connect
to other processes without assistance; rather it means that Mojo handles created
by the process can safely be transferred to any other process in the network
over established message pipes, and similarly that Mojo handles created by any
other process in the network can be safely passed to the newly admitted process.

### Invitation Restrictions
A process may only belong to a single network at a time.

Additionally, once a process has joined a network, it cannot join another for
the remainder of its lifetime even if it has lost the connection to its original
network. This restriction will soon be lifted, but for now developers must be
mindful of it when authoring any long-running daemon process that will accept an
incoming invitation.

### Isolated Invitations
It is possible to have two independent networks of Mojo-connected processes; for
example, a long-running system daemon which uses Mojo to talk to child processes
of its own, as well as the Chrome browser process running with no common
ancestor, talking to its own child processes.

In this scenario it may be desirable to have a process in one network talk to a
process in the other network. Normal invitations cannot be used here since both
processes already belong to a network. In this case, an **isolated** invitation
can be used. These work just like regular invitations, except the sender must
call `OutgoingInvitation::SendIsolated` and the receiver must call
`IncomingInvitation::AcceptIsolated`.

Once a connection is established via isolated invitation, Mojo IPC can be used
normally, with the exception that transitive process connections are not
supported; that is, if process A sends a message pipe handle to process B via
an isolated connection, process B cannot reliably send that pipe handle onward
to another process in its own network. Isolated invitations therefore may only
be used to facilitate direct 1:1 communication between two processes.
