Home | History | Annotate | Download | only in system
      1 # Mojo C System API
      2 This document is a subset of the [Mojo documentation](/mojo/README.md).
      3 
      4 [TOC]
      5 
      6 ## Overview
      7 The Mojo C System API is a lightweight API (with an stable, forward-compatible
      8 ABI) upon which all higher-level public Mojo APIs are built.
      9 
     10 This API exposes the fundamental capabilities to: create, read from, and write
     11 to **message pipes**; create, read from, and write to **data pipes**; create
     12 **shared buffers** and generate sharable handles to them; wrap platform-specific
     13 handle objects (such as **file descriptors**, **Windows handles**, and
     14 **Mach ports**) for seamless transit over message pipes; and efficiently watch
     15 handles for various types of state transitions. Finally, there are also APIs to
     16 bootstrap Mojo IPC between two processes.
     17 
     18 This document provides a brief guide to API usage with example code snippets.
     19 For a detailed API references please consult the headers in
     20 [//mojo/public/c/system](https://cs.chromium.org/chromium/src/mojo/public/c/system/).
     21 
     22 ### A Note About Multithreading
     23 
     24 The Mojo C System API is entirely thread-agnostic. This means that all functions
     25 may be called from any thread in a process, and there are no restrictions on how
     26 many threads can use the same object at the same time.
     27 
     28 Of course this does not mean you can completely ignore potential concurrency
     29 issues -- such as a handle being closed on one thread while another thread is
     30 trying to perform an operation on the same handle -- but there is nothing
     31 fundamentally incorrect about using any given API or handle from multiple
     32 threads.
     33 
     34 ### A Note About Synchronization
     35 
     36 Every Mojo API call is non-blocking and synchronously yields some kind of status
     37 result code, but the call's side effects -- such as affecting the state of
     38 one or more handles in the system -- may or may not occur asynchronously.
     39 
     40 Mojo objects can be observed for interesting state changes in a way that is
     41 thread-agnostic and in some ways similar to POSIX signal handlers: *i.e.*
     42 user-provided notification handlers may be invoked at any time on arbitrary
     43 threads in the process. It is entirely up to the API user to take appropriate
     44 measures to synchronize operations against other application state.
     45 
     46 The higher level [system](/mojo/README.md#High-Level-System-APIs) and
     47 [bindings](/mojo/README.md#High-Level-Bindings-APIs) APIs provide helpers to
     48 simplify Mojo usage in this regard, at the expense of some flexibility.
     49 
     50 ## Result Codes
     51 
     52 Most API functions return a value of type `MojoResult`. This is an integral
     53 result code used to convey some meaningful level of detail about the result of a
     54 requested operation.
     55 
     56 See [//mojo/public/c/system/types.h](https://cs.chromium.org/chromium/src/mojo/public/c/system/types.h)
     57 for different possible values. See documentation for individual API calls for
     58 more specific contextual meaning of various result codes.
     59 
     60 ## Handles
     61 
     62 Every Mojo IPC primitive is identified by a generic, opaque integer handle of
     63 type `MojoHandle`. Handles can be acquired by creating new objects using various
     64 API calls, or by reading messages which contain attached handles.
     65 
     66 A `MojoHandle` can represent a message pipe endpoint, a data pipe consumer,
     67 a data pipe producer, a shared buffer reference, a wrapped native platform
     68 handle such as a POSIX file descriptor or a Windows system handle, a trap object
     69 (see [Signals & Traps](#Signals-Traps) below), or a process invitation (see
     70 [Invitations](#Invitations) below).
     71 
     72 Message pipes, data pipes, shared buffers, and platform handles can all be
     73 attached to messages and sent over message pipes. Traps are an inherently
     74 process-local concept, and invitations are transmitted using special dedicated
     75 APIs.
     76 
     77 Any `MojoHandle` may be closed by calling `MojoClose`:
     78 
     79 ``` c
     80 MojoHandle x = DoSomethingToGetAValidHandle();
     81 MojoResult result = MojoClose(x);
     82 ```
     83 
     84 If the handle passed to `MojoClose` was a valid handle, it will be closed and
     85 `MojoClose` returns `MOJO_RESULT_OK`. Otherwise it returns
     86 `MOJO_RESULT_INVALID_ARGUMENT`.
     87 
     88 Similar to native system handles on various popular platforms, `MojoHandle`
     89 values may be reused over time. Thus it is important to avoid logical errors
     90 which lead to misplaced handle ownership, double-closes, *etc.*
     91 
     92 ## Message Pipes
     93 
     94 A message pipe is a bidirectional messaging channel which can carry arbitrary
     95 unstructured binary messages with zero or more `MojoHandle` attachments to be
     96 transferred from one end of a pipe to the other. Message pipes work seamlessly
     97 across process boundaries or within a single process.
     98 
     99 [Invitations](#Invitations) provide the means to bootstrap one or more
    100 primordial cross-process message pipes between two processes. Once such a pipe
    101 is established, additional handles -- including other message pipe handles --
    102 may be sent to a remote process using that pipe (or in turn, over other pipes
    103 sent over that pipe, or pipes sent over *that* pipe, and so on...)
    104 
    105 The public C System API exposes the ability to read and write messages on pipes
    106 and to create new message pipes.
    107 
    108 See [//mojo/public/c/system/message_pipe.h](https://cs.chromium.org/chromium/src/mojo/public/c/system/message_pipe.h)
    109 for detailed message pipe API documentation.
    110 
    111 ### Creating Message Pipes
    112 
    113 `MojoCreateMessagePipe` can be used to create a new message pipe:
    114 
    115 ``` c
    116 MojoHandle a, b;
    117 MojoResult result = MojoCreateMessagePipe(NULL, &a, &b);
    118 ```
    119 
    120 After this snippet, `result` should be `MOJO_RESULT_OK` (it's really hard for
    121 this to fail!), and `a` and `b` will contain valid Mojo handles, one for each
    122 end of the new message pipe.
    123 
    124 Any messages written to `a` are eventually readable from `b`, and any messages
    125 written to `b` are eventually readable from `a`. If `a` is closed at any point,
    126 `b` will eventually become aware of this fact; likewise if `b` is closed, `a`
    127 will become aware of that.
    128 
    129 The state of these conditions can be queried and watched asynchronously as
    130 described in the [Signals & Traps](#Signals-Traps) section below.
    131 
    132 ### Creating Messages
    133 
    134 Message pipes carry message objects which may or may not be serialized. You can
    135 create a new message object as follows:
    136 
    137 ``` c
    138 MojoMessageHandle message;
    139 MojoResult result = MojoCreateMessage(nullptr, &message);
    140 ```
    141 
    142 Note that we have a special `MojoMessageHandle` type for message objects.
    143 
    144 Messages may be serialized with attached data or unserialized with an
    145 opaque context value. Unserialized messages support lazy serialization, allowing
    146 custom serialization logic to be invoked only if and when serialization is
    147 required, e.g. when the message needs to cross a process or language boundary.
    148 
    149 To make a serialized message, you might write something like:
    150 
    151 ``` c
    152 void* buffer;
    153 uint32_t buffer_size;
    154 MojoResult result = MojoAppendMessageData(message, nullptr, 6, nullptr, 0,
    155                                           &buffer, &buffer_size);
    156 memcpy(buffer, "hello", 6);
    157 ```
    158 
    159 This attaches a data buffer to `message` with at least `6` bytes of storage
    160 capacity. The outputs returned in `buffer` and `buffer_size` can be used by the
    161 caller to fill in the message contents.
    162 
    163 Multiple calls to `MojoAppendMessageData` may be made on a single message
    164 object, and each call appends to any payload and handles accumulated so far.
    165 Before you can transmit a message carrying data you must commit to never calling
    166 `MojoAppendMessageData` again. You do this by passing the
    167 `MOJO_APPEND_MESSAGE_DATA_FLAG_COMMIT_SIZE` flag:
    168 
    169 ``` c
    170 MojoAppendMessageDataOptions options;
    171 options.struct_size = sizeof(options);
    172 options.flags = MOJO_APPEND_MESSAGE_DATA_FLAG_COMMIT_SIZE;
    173 MojoResult result = MojoAppendMessageData(message, &options, 0, nullptr, 0,
    174                                           &buffer, &buffer_size);
    175 ```
    176 
    177 Creating lazily-serialized messages is also straightforward:
    178 
    179 ``` c
    180 struct MyMessage {
    181   // some interesting data...
    182 };
    183 
    184 void SerializeMessage(MojoMessageHandle message, uintptr_t context) {
    185   struct MyMessage* my_message = (struct MyMessage*)context;
    186 
    187   MojoResult result = MojoAppendMessageData(message, ...);
    188   // Serialize however you like.
    189 }
    190 
    191 void DestroyMessage(uintptr_t context) {
    192   free((void*)context);
    193 }
    194 
    195 MyMessage* data = malloc(sizeof(MyMessage));
    196 // initialize *data...
    197 
    198 MojoResult result = MojoSetMessageContext(
    199     message, (uintptr_t)data, &SerializeMessage, &DestroyMessage, nullptr);
    200 ```
    201 
    202 If we change our mind and decide not to send the message, we can destroy it:
    203 
    204 ``` c
    205 MojoResult result = MojoDestroyMessage(message);
    206 ```
    207 
    208 Note that attempting to write a message will transfer ownership of the message
    209 object (and any attached handles) into the message pipe, and there is therefore
    210 no need to subsequently call `MojoDestroyMessage` on that message.
    211 
    212 ### Writing Messages
    213 
    214 ``` c
    215 result = MojoWriteMessage(a, message, nullptr);
    216 ```
    217 
    218 `MojoWriteMessage` is a *non-blocking* call: it always returns
    219 immediately. If its return code is `MOJO_RESULT_OK` the message will eventually
    220 find its way to the other end of the pipe -- assuming that end isn't closed
    221 first, of course. If the return code is anything else, the message is deleted
    222 and not transferred.
    223 
    224 In this case since we know `b` is still open, we also know the message will
    225 eventually arrive at `b`. `b` can be queried or watched to become aware of when
    226 the message arrives, but we'll ignore that complexity for now. See
    227 [Signals & Traps](#Signals-Traps) below for more information.
    228 
    229 *** aside
    230 **NOTE**: Although this is an implementation detail and not strictly guaranteed
    231 by the System API, it is true in the current implementation that the message
    232 will arrive at `b` before the above `MojoWriteMessage` call even returns,
    233 because `b` is in the same process as `a` and has never been transferred over
    234 another pipe.
    235 ***
    236 
    237 ### Reading Messages
    238 
    239 We can read a new message object from a pipe:
    240 
    241 ``` c
    242 MojoMessageHandle message;
    243 MojoResult result = MojoReadMessage(b, nullptr, &message);
    244 ```
    245 
    246 and extract its data:
    247 
    248 ``` c
    249 void* buffer = NULL;
    250 uint32_t num_bytes;
    251 MojoResult result = MojoGetMessageData(message, nullptr, &buffer, &num_bytes,
    252                                        nullptr, nullptr);
    253 printf("Pipe says: %s", (const char*)buffer);
    254 ```
    255 
    256 `result` should be `MOJO_RESULT_OK` and this snippet should write `"hello"` to
    257 `stdout`.
    258 
    259 If we try were to try reading again now that there are no messages on `b`:
    260 
    261 ``` c
    262 MojoMessageHandle message;
    263 MojoResult result = MojoReadMessage(b, nullptr, &message);
    264 ```
    265 
    266 We'll get a `result` of `MOJO_RESULT_SHOULD_WAIT`, indicating that the pipe is
    267 not yet readable.
    268 
    269 Note that message also may not have been serialized if it came from within the
    270 same process, in which case it may have no attached data and
    271 `MojoGetMessageData` will return `MOJO_RESULT_FAILED_PRECONDITION`. The
    272 message's unserialized context can instead be retrieved using
    273 `MojoGetMessageContext`.
    274 
    275 Messages read from a message pipe are owned by the caller and must be
    276 subsequently destroyed using `MojoDestroyMessage` (or, in theory, written to
    277 another pipe using `MojoWriteMessage`.)
    278 
    279 ### Messages With Handles
    280 
    281 Probably the most useful feature of Mojo IPC is that message pipes can carry
    282 arbitrary Mojo handles, including other message pipes. This is also
    283 straightforward.
    284 
    285 Here's an example which creates two pipes, using the first pipe to transfer
    286 one end of the second pipe. If you have a good imagination you can pretend the
    287 first pipe spans a process boundary, which makes the example more practically
    288 interesting:
    289 
    290 ``` c
    291 MojoHandle a, b;
    292 MojoHandle c, d;
    293 MojoCreateMessagePipe(NULL, &a, &b);
    294 MojoCreateMessagePipe(NULL, &c, &d);
    295 
    296 // Allocate a message with an empty payload and handle |c| attached. Note that
    297 // this takes ownership of |c|, effectively invalidating its handle value.
    298 MojoMessageHandle message;
    299 void* buffer;
    300 uint32_t buffer_size;
    301 MojoCreateMessage(nullptr, &message);
    302 
    303 MojoAppendMessageDataOptions options;
    304 options.struct_size = sizeof(options);
    305 options.flags = MOJO_APPEND_MESSAGE_DATA_FLAG_COMMIT_SIZE;
    306 MojoAppendMessageData(message, &options, 2, &c, 1, &buffer, &buffer_size);
    307 memcpy(buffer, "hi", 2);
    308 MojoWriteMessage(a, message, nullptr);
    309 
    310 // Some time later...
    311 MojoHandle e;
    312 uint32_t num_handles = 1;
    313 MojoReadMessage(b, nullptr, &message);
    314 MojoGetMessageData(message, nullptr, &buffer, &buffer_size, &e, &num_handles);
    315 ```
    316 
    317 At this point the handle in `e` is now referencing the same message pipe
    318 endpoint which was originally referenced by `c`.
    319 
    320 Note that `num_handles` above is initialized to 1 before we pass its address to
    321 `MojoGetMessageData`. This is to indicate how much `MojoHandle` storage is
    322 available at the output buffer we gave it (`&e` above).
    323 
    324 If we didn't know how many handles to expect in an incoming message -- which is
    325 often the case -- we can use `MojoGetMessageData` to query for this information
    326 first:
    327 
    328 ``` c
    329 MojoMessageHandle message;
    330 void* buffer;
    331 uint32_t num_bytes = 0;
    332 uint32_t num_handles = 0;
    333 MojoResult result = MojoGetMessageData(message, nullptr, &buffer, &num_bytes,
    334                                        nullptr, &num_handles);
    335 ```
    336 
    337 If `message` has some non-zero number of handles, `result` will be
    338 `MOJO_RESULT_RESOURCE_EXHAUSTED`, and both `num_bytes` and `num_handles` will be
    339 updated to reflect the payload size and number of attached handles in the
    340 message.
    341 
    342 ## Data Pipes
    343 
    344 Data pipes provide an efficient unidirectional channel for moving large amounts
    345 of unframed data between two endpoints. Every data pipe has a fixed
    346 **element size** and **capacity**. Reads and writes must be done in sizes that
    347 are a multiple of the element size, and writes to the pipe can only be queued
    348 up to the pipe's capacity before reads must be done to make more space
    349 available.
    350 
    351 Every data pipe has a single **producer** handle used to write data into the
    352 pipe and a single **consumer** handle used to read data out of the pipe.
    353 
    354 Finally, data pipes support both immediate I/O -- reading into and writing out
    355 from user-supplied buffers -- as well as two-phase I/O, allowing callers to
    356 temporarily lock some portion of the data pipe in order to read or write its
    357 contents directly.
    358 
    359 See [//mojo/public/c/system/data_pipe.h](https://cs.chromium.org/chromium/src/mojo/public/c/system/data_pipe.h)
    360 for detailed data pipe API documentation.
    361 
    362 ### Creating Data Pipes
    363 
    364 Use `MojoCreateDataPipe` to create a new data pipe. The
    365 `MojoCreateDataPipeOptions` structure is used to configure the new pipe, but
    366 this can be omitted to assume the default options of a single-byte element size
    367 and an implementation-defined default capacity (64 kB at the time of this
    368 writing.)
    369 
    370 ``` c
    371 MojoHandle producer, consumer;
    372 MojoResult result = MojoCreateDataPipe(NULL, &producer, &consumer);
    373 ```
    374 
    375 ### Immediate I/O
    376 
    377 Data can be written into or read out of a data pipe using buffers provided by
    378 the caller. This is generally more convenient than two-phase I/O but is
    379 also less efficient due to extra copying.
    380 
    381 ``` c
    382 uint32_t num_bytes = 12;
    383 MojoResult result = MojoWriteData(producer, "datadatadata", &num_bytes,
    384                                   nullptr);
    385 ```
    386 
    387 The above snippet will attempt to write 12 bytes into the data pipe, which
    388 should succeed and return `MOJO_RESULT_OK`. If the available capacity on the
    389 pipe was less than the amount requested (the input value of `*num_bytes`) this
    390 will copy what it can into the pipe and return the number of bytes written in
    391 `*num_bytes`. If no data could be copied this will instead return
    392 `MOJO_RESULT_SHOULD_WAIT`.
    393 
    394 Reading from the consumer is a similar operation.
    395 
    396 ``` c
    397 char buffer[64];
    398 uint32_t num_bytes = 64;
    399 MojoResult result = MojoReadData(consumer, nullptr, buffer, &num_bytes);
    400 ```
    401 
    402 This will attempt to read up to 64 bytes, returning the actual number of bytes
    403 read in `*num_bytes`.
    404 
    405 `MojoReadData` supports a number of interesting flags to change the behavior:
    406 you can peek at the data (copy bytes out without removing them from the pipe),
    407 query the number of bytes available without doing any actual reading of the
    408 contents, or discard data from the pipe without bothering to copy it anywhere.
    409 
    410 This also supports a `MOJO_READ_DATA_FLAG_ALL_OR_NONE` which ensures that the
    411 call succeeds **only** if the exact number of bytes requested could be read.
    412 Otherwise such a request will fail with `MOJO_READ_DATA_OUT_OF_RANGE`.
    413 
    414 ### Two-Phase I/O
    415 
    416 Data pipes also support two-phase I/O operations, allowing a caller to
    417 temporarily lock a portion of the data pipe's storage for direct memory access.
    418 
    419 ``` c
    420 void* buffer;
    421 uint32_t num_bytes = 1024;
    422 MojoResult result = MojoBeginWriteData(producer, nullptr, &buffer, &num_bytes);
    423 ```
    424 
    425 This requests write access to a region of up to 1024 bytes of the data pipe's
    426 next available capacity. Upon success, `buffer` will point to the writable
    427 storage and `num_bytes` will indicate the size of the buffer there.
    428 
    429 The caller should then write some data into the memory region and release it
    430 ASAP, indicating the number of bytes actually written:
    431 
    432 ``` c
    433 memcpy(buffer, "hello", 6);
    434 MojoResult result = MojoEndWriteData(producer, 6, nullptr);
    435 ```
    436 
    437 Two-phase reads look similar:
    438 
    439 ``` c
    440 void* buffer;
    441 uint32_t num_bytes = 1024;
    442 MojoResult result = MojoBeginReadData(consumer, nullptr, &buffer, &num_bytes);
    443 // result should be MOJO_RESULT_OK, since there is some data available.
    444 
    445 printf("Pipe says: %s", (const char*)buffer);  // Should say "hello".
    446 
    447 // Say we only consumed one byte.
    448 result = MojoEndReadData(consumer, 1, nullptr);
    449 
    450 num_bytes = 1024;
    451 result = MojoBeginReadData(consumer, nullptr, &buffer, &num_bytes);
    452 printf("Pipe says: %s", (const char*)buffer);  // Should say "ello".
    453 result = MojoEndReadData(consumer, 5, nullptr);
    454 ```
    455 
    456 ## Shared Buffers
    457 
    458 Shared buffers are chunks of memory which can be mapped simultaneously by
    459 multiple processes. Mojo provides a simple API to make these available to
    460 applications.
    461 
    462 See [//mojo/public/c/system/buffer.h](https://cs.chromium.org/chromium/src/mojo/public/c/system/buffer.h)
    463 for detailed shared buffer API documentation.
    464 
    465 ### Creating Buffer Handles
    466 
    467 Usage is straightforward. You can create a new buffer:
    468 
    469 ``` c
    470 // Allocate a shared buffer of 4 kB.
    471 MojoHandle buffer;
    472 MojoResult result = MojoCreateSharedBuffer(4096, NULL, &buffer);
    473 ```
    474 
    475 You can also duplicate an existing shared buffer handle:
    476 
    477 ``` c
    478 MojoHandle another_name_for_buffer;
    479 MojoResult result = MojoDuplicateBufferHandle(buffer, NULL,
    480                                               &another_name_for_buffer);
    481 ```
    482 
    483 This is useful if you want to retain a handle to the buffer while also sharing
    484 handles with one or more other clients. The allocated buffer remains valid as
    485 long as at least one shared buffer handle exists to reference it.
    486 
    487 ### Mapping Buffers
    488 
    489 You can map (and later unmap) a specified range of the buffer to get direct
    490 memory access to its contents:
    491 
    492 ``` c
    493 void* data;
    494 MojoResult result = MojoMapBuffer(buffer, 0, 64, nullptr, &data);
    495 
    496 *(int*)data = 42;
    497 result = MojoUnmapBuffer(data);
    498 ```
    499 
    500 A buffer may have any number of active mappings at a time, in any number of
    501 processes.
    502 
    503 ### Read-Only Handles
    504 
    505 An option can also be specified on `MojoDuplicateBufferHandle` to ensure
    506 that the newly duplicated handle can only be mapped to read-only memory:
    507 
    508 ``` c
    509 MojoHandle read_only_buffer;
    510 MojoDuplicateBufferHandleOptions options;
    511 options.struct_size = sizeof(options);
    512 options.flags = MOJO_DUPLICATE_BUFFER_HANDLE_FLAG_READ_ONLY;
    513 MojoResult result = MojoDuplicateBufferHandle(buffer, &options,
    514                                               &read_only_buffer);
    515 
    516 // Attempt to map and write to the buffer using the read-only handle:
    517 void* data;
    518 result = MojoMapBuffer(read_only_buffer, 0, 64, nullptr, &data);
    519 *(int*)data = 42;  // CRASH
    520 ```
    521 
    522 *** note
    523 **NOTE:** One important limitation of the current implementation is that
    524 read-only handles can only be produced from a handle that was originally created
    525 by `MojoCreateSharedBuffer` (*i.e.*, you cannot create a read-only duplicate
    526 from a non-read-only duplicate), and the handle cannot have been transferred
    527 over a message pipe first.
    528 ***
    529 
    530 ## Native Platform Handles (File Descriptors, Windows Handles, *etc.*)
    531 
    532 Native platform handles to system objects can be wrapped as Mojo handles for
    533 seamless transit over message pipes. Mojo currently supports wrapping POSIX
    534 file descriptors, Windows handles, Mach ports, and Fuchsia zx_handles.
    535 
    536 See [//mojo/public/c/system/platform_handle.h](https://cs.chromium.org/chromium/src/mojo/public/c/system/platform_handle.h)
    537 for detailed platform handle API documentation.
    538 
    539 ### Wrapping Basic Handle Types
    540 
    541 Wrapping a POSIX file descriptor is simple:
    542 
    543 ``` c
    544 MojoPlatformHandle platform_handle;
    545 platform_handle.struct_size = sizeof(platform_handle);
    546 platform_handle.type = MOJO_PLATFORM_HANDLE_TYPE_FILE_DESCRIPTOR;
    547 platform_handle.value = (uint64_t)fd;
    548 MojoHandle handle;
    549 MojoResult result = MojoWrapPlatformHandle(&platform_handle, nullptr, &handle);
    550 ```
    551 
    552 Note that at this point `handle` effectively owns the file descriptor
    553 and if you were to call `MojoClose(handle)`, the file descriptor would be closed
    554 too; but we're not going to close it here! We're going to pretend we've sent it
    555 over a message pipe, and now we want to unwrap it on the other side:
    556 
    557 ``` c
    558 MojoPlatformHandle platform_handle;
    559 platform_handle.struct_size = sizeof(platform_handle);
    560 MojoResult result = MojoUnwrapPlatformHandle(handle, nullptr, &platform_handle);
    561 int fd = (int)platform_handle.value;
    562 ```
    563 
    564 The situation looks nearly identical for wrapping and unwrapping Windows handles
    565 and Mach ports.
    566 
    567 ### Wrapping Shared Buffer Handles
    568 
    569 Unlike other handle types, shared buffers have special meaning in Mojo, and it
    570 may be desirable to wrap a native platform handle -- along with some extra
    571 metadata -- such that be treated like a real Mojo shared buffer handle.
    572 Conversely it can also be useful to unpack a Mojo shared buffer handle into
    573 a native platform handle which references the buffer object. Both of these
    574 things can be done using the `MojoWrapPlatformSharedBuffer` and
    575 `MojoUnwrapPlatformSharedBuffer` APIs.
    576 
    577 On Windows, the wrapped platform handle must always be a Windows handle to
    578 a file mapping object.
    579 
    580 On OS X, the wrapped platform handle must be a memory-object send right.
    581 
    582 On all other POSIX systems, the wrapped platform handle must be a file
    583 descriptor for a shared memory object.
    584 
    585 ## Signals & Traps
    586 
    587 Message pipe and data pipe (producer and consumer) handles can change state in
    588 ways that may be interesting to a Mojo API user. For example, you may wish to
    589 know when a message pipe handle has messages available to be read or when its
    590 peer has been closed. Such states are reflected by a fixed set of boolean
    591 signals on each pipe handle.
    592 
    593 ### Signals
    594 
    595 Every message pipe and data pipe handle maintains a notion of
    596 **signaling state** which may be queried at any time. For example:
    597 
    598 ``` c
    599 MojoHandle a, b;
    600 MojoCreateMessagePipe(NULL, &a, &b);
    601 
    602 MojoHandleSignalsState state;
    603 MojoResult result = MojoQueryHandleSignalsState(a, &state);
    604 ```
    605 
    606 The `MojoHandleSignalsState` structure exposes two fields: `satisfied_signals`
    607 and `satisfiable_signals`. Both of these are bitmasks of the type
    608 `MojoHandleSignals` (see [//mojo/public/c/system/types.h](https://cs.chromium.org/chromium/src/mojo/public/c/system/types.h)
    609 for more details.)
    610 
    611 The `satisfied_signals` bitmask indicates signals which were satisfied on the
    612 handle at the time of the call, while the `satisfiable_signals` bitmask
    613 indicates signals which were still possible to satisfy at the time of the call.
    614 It is thus by definition always true that:
    615 
    616 ``` c
    617 (satisfied_signals | satisfiable_signals) == satisfiable_signals
    618 ```
    619 
    620 In other words a signal obviously cannot be satisfied if it is no longer
    621 satisfiable. Furthermore once a signal is unsatisfiable, *i.e.* is no longer
    622 set in `sastisfiable_signals`, it can **never** become satisfiable again.
    623 
    624 To illustrate this more clearly, consider the message pipe created above. Both
    625 ends of the pipe are still open and neither has been written to yet. Thus both
    626 handles start out with the same signaling state:
    627 
    628 | Field                 | State |
    629 |-----------------------|-------|
    630 | `satisfied_signals`   | `MOJO_HANDLE_SIGNAL_WRITABLE`
    631 | `satisfiable_signals` | `MOJO_HANDLE_SIGNAL_READABLE + MOJO_HANDLE_SIGNAL_WRITABLE + MOJO_HANDLE_SIGNAL_PEER_CLOSED`
    632 
    633 Writing a message to handle `b` will eventually alter the signaling state of `a`
    634 such that `MOJO_HANDLE_SIGNAL_READABLE` also becomes satisfied. If we were to
    635 then close `b`, the signaling state of `a` would look like:
    636 
    637 | Field                 | State |
    638 |-----------------------|-------|
    639 | `satisfied_signals`   | `MOJO_HANDLE_SIGNAL_READABLE + MOJO_HANDLE_SIGNAL_PEER_CLOSED`
    640 | `satisfiable_signals` | `MOJO_HANDLE_SIGNAL_READABLE + MOJO_HANDLE_SIGNAL_PEER_CLOSED`
    641 
    642 Note that even though `a`'s peer is known to be closed (hence making `a`
    643 permanently unwritable) it remains readable because there's still an unread
    644 received message waiting to be read from `a`.
    645 
    646 Finally if we read the last message from `a` its signaling state becomes:
    647 
    648 | Field                 | State |
    649 |-----------------------|-------|
    650 | `satisfied_signals`   | `MOJO_HANDLE_SIGNAL_PEER_CLOSED`
    651 | `satisfiable_signals` | `MOJO_HANDLE_SIGNAL_PEER_CLOSED`
    652 
    653 and we know definitively that `a` can never be read from again.
    654 
    655 ### Trapping Signals
    656 
    657 The ability to query a handle's signaling state can be useful, but it's not
    658 sufficient to support robust and efficient pipe usage. Mojo traps empower users
    659 with the ability to **trap** changes in a handle's signaling state and
    660 automatically invoke a notification handler in response.
    661 
    662 When a trap is created it must be bound to a function pointer matching
    663 the following signature, defined in
    664 [//mojo/public/c/system/trap.h](https://cs.chromium.org/chromium/src/mojo/public/c/system/trap.h):
    665 
    666 ``` c
    667 typedef void (*MojoTrapEventHandler)(const struct MojoTrapEvent* event);
    668 ```
    669 
    670 The `event` parameter conveys details about why the event handler is being
    671 invoked. The handler may be called **at any time** and **from any thread**, so
    672 it is critical that handler implementations account for this.
    673 
    674 It's also helpful to understand a bit about the mechanism by which the handler
    675 can be invoked. Essentially, any Mojo C System API call may elicit a handle
    676 state change of some kind. If such a change is relevant to conditions watched by
    677 a trap, and that trap is in a state which allows it raise a corresponding
    678 notification, its notification handler will be invoked synchronously some time
    679 before the stack unwinds beyond the outermost System API call on the current
    680 thread.
    681 
    682 Handle state changes can also occur as a result of incoming IPC from an external
    683 process. If a pipe in the current process is connected to an endpoint in another
    684 process and the internal Mojo system receives an incoming message bound for the
    685 local endpoint, the arrival of that message may trigger a state change on the
    686 receiving handle and may therefore invoke one or more traps' notification
    687 handlers as a result.
    688 
    689 The `MOJO_TRAP_EVENT_FLAG_WITHIN_API_CALL` flag on the `flags` field of `event`
    690 is used to indicate whether the handler was invoked due to such an internal
    691 system IPC event (if the flag is unset), or if it was invoked synchronously due
    692 to some local API call (if the flag is set.) This distinction can be useful to
    693 make in certain cases to *e.g.* avoid accidental reentrancy in user code.
    694 
    695 ### Creating a Trap
    696 
    697 Creating a trap is simple:
    698 
    699 ``` c
    700 
    701 void OnNotification(const struct MojoTrapEvent* event) {
    702   // ...
    703 }
    704 
    705 MojoHandle t;
    706 MojoResult result = MojoCreateTrap(&OnNotification, NULL, &t);
    707 ```
    708 
    709 Like all other `MojoHandle` types, traps may be destroyed by closing them with
    710 `MojoClose`. Unlike most other `MojoHandle` types, trap handles are **not**
    711 transferrable across message pipes.
    712 
    713 In order for a trap to be useful, it has have at least one **trigger** attached
    714 to it.
    715 
    716 ### Adding a Trigger to a Trap
    717 
    718 Any given trap can watch any given (message or data pipe) handle for some set
    719 of signaling conditions. A handle may be watched simultaneously by multiple
    720 traps, and a single trap can watch multiple different handles simultaneously.
    721 
    722 ``` c
    723 MojoHandle a, b;
    724 MojoCreateMessagePipe(NULL, &a, &b);
    725 
    726 // Watch handle |a| for readability.
    727 const uintptr_t context = 1234;
    728 MojoResult result = MojoAddTrigger(t, a, MOJO_HANDLE_SIGNAL_READABLE,
    729                                    MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED,
    730                                    context, NULL);
    731 ```
    732 
    733 We've successfully instructed trap `t` to begin watching pipe handle `a` for
    734 readability. However, our recently created trap is still in a **disarmed**
    735 state, meaning that it will never fire a notification pertaining to this
    736 trigger. It must be **armed** before that can happen.
    737 
    738 ### Arming a Trap
    739 
    740 In order for a trap to invoke its notification handler in response to a relevant
    741 signaling state change on a watched handle, it must first be armed. A trap may
    742 only be armed if none of its attached triggers would elicit a notification
    743 immediately once armed.
    744 
    745 In this case `a` is clearly not yet readable, so arming should succeed:
    746 
    747 ``` c
    748 MojoResult result = MojoArmTrap(t, NULL, NULL, NULL);
    749 ```
    750 
    751 Now we can write to `b` to make `a` readable:
    752 
    753 ``` c
    754 MojoMessageHandle m;
    755 MojoCreateMessage(nullptr, &m);
    756 MojoWriteMessage(b, m, nullptr);
    757 ```
    758 
    759 Eventually -- and in practice possibly before `MojoWriteMessage` even
    760 returns -- this will cause `OnNotification` to be invoked on the calling thread
    761 with the `context` value (*i.e.* 1234) that was given when the trigger was added
    762 to the trap.
    763 
    764 The `result` field of the event will be `MOJO_RESULT_OK` to indicate that the
    765 trigger's condition has been met. If the handle's state had instead changed in
    766 such a way that the trigger's condition could never be met again (*e.g.* if `b`
    767 were instead closed), `result` would instead indicate
    768 `MOJO_RESULT_FAILED_PRECONDITION`.
    769 
    770 **NOTE:** Immediately before a trigger decides to invoke its event handler, it
    771 automatically disarms itself to prevent another state change from eliciting
    772 another notification. Therefore a trap must be repeatedly rearmed in order to
    773 continue dispatching events.
    774 
    775 As noted above, arming a watcher may fail if any of its triggers would be
    776 activated immediately.  In that case, the caller may provide buffers to
    777 `MojoArmTrap` to receive information about a subset of the triggers which caused
    778 it to fail:
    779 
    780 ``` c
    781 // Provide some storage for information about triggers that would have been
    782 // activated immediately.
    783 uint32_t num_blocking_events = 2;
    784 MojoTrapEvent blocking_events[2] = {{sizeof(MojoTrapEvent)},
    785                                     {sizeof(MojoTrapEvent)}};
    786 MojoResult result = MojoArmTrap(t, NULL, &num_blocking_events,
    787                                 &blocking_events);
    788 ```
    789 
    790 Because `a` is still readable this operation will now fail with
    791 `MOJO_RESULT_FAILED_PRECONDITION`. The input value of `num_blocking_events`
    792 informs `MojoArmTrap` that it may store information regarding up to 2 triggers
    793 which have prevented arming. In this case of course there is only one active
    794 trigger, so upon return we will see:
    795 
    796 * `num_blocking_events` is `1`.
    797 * `blocking_events[0].trigger_context` is `1234`.
    798 * `blocking_events[0].result` is `MOJO_RESULT_OK`
    799 * `blocking_events[0].signals_state` is the last known signaling state of handle
    800   `a`.
    801 
    802 In other words the stored information mirrors what would have been the resulting
    803 event structure if the trap were allowed to arm and then notify immediately.
    804 
    805 ### Removing a Trigger
    806 
    807 There are three ways a trigger can be removed:
    808 
    809 * The handle being watched by the trigger is closed
    810 * The trap handle is closed, in which case all of its attached triggers are
    811   implicitly removed.
    812 * `MojoRemoveTrigger` is called for a given `context`.
    813 
    814 In the above example this means any of the following operations will cancel the
    815 watch on `a`:
    816 
    817 ``` c
    818 // Close the watched handle...
    819 MojoClose(a);
    820 
    821 // OR close the trap handle...
    822 MojoClose(t);
    823 
    824 // OR explicitly remove it.
    825 MojoResult result = MojoRemoveTrigger(t, 1234, NULL);
    826 ```
    827 
    828 In every case the trap's event handler is invoked for the cancelled trigger(es)
    829 regardless of whether or not the trap was armed at the time. The event handler
    830 receives a `result` of `MOJO_RESULT_CANCELLED` for each of these invocations,
    831 and this is guaranteed to be the final event for any given trigger context.
    832 
    833 ### Practical Trigger Context Usage
    834 
    835 It is common and probably wise to treat a trigger's `context` value as an opaque
    836 pointer to some thread-safe state associated in some way with the handle being
    837 watched. Here's a small example which uses a single trap to watch both ends of a
    838 message pipe and accumulate a count of messages received at each end.
    839 
    840 ``` c
    841 // NOTE: For the sake of simplicity this example code is not in fact
    842 // thread-safe. As long as there's only one thread running in the process and
    843 // no external process connections, this is fine.
    844 
    845 struct WatchedHandleState {
    846   MojoHandle trap;
    847   MojoHandle handle;
    848   int message_count;
    849 };
    850 
    851 void OnNotification(const struct MojoTrapEvent* event) {
    852   struct WatchedHandleState* state =
    853       (struct WatchedHandleState*)(event->trigger_context);
    854   MojoResult rv;
    855 
    856   if (event->result == MOJO_RESULT_CANCELLED) {
    857     // Cancellation is always the last event and is guaranteed to happen for
    858     // every context, assuming no handles are leaked. We treat this as an
    859     // opportunity to free the WatchedHandleState.
    860     free(state);
    861     return;
    862   }
    863 
    864   if (result == MOJO_RESULT_FAILED_PRECONDITION) {
    865     // No longer readable, i.e. the other handle must have been closed. Better
    866     // cancel. Note that we could also just call MojoClose(state->trap) here
    867     // since we know there's only one attached trigger.
    868     MojoRemoveTrigger(state->trap, event->trigger_context, NULL);
    869     return;
    870   }
    871 
    872   // This is the only handle watched by the trap, so as long as we can't arm
    873   // the watcher we know something's up with this handle. Try to read messages
    874   // until we can successfully arm again or something goes terribly wrong.
    875   while (MojoArmTrap(state->trap, NULL NULL, NULL) ==
    876          MOJO_RESULT_FAILED_PRECONDITION) {
    877     rv = MojoReadMessageNew(state->handle, NULL, NULL, NULL,
    878                             MOJO_READ_MESSAGE_FLAG_MAY_DISCARD);
    879     if (rv == MOJO_RESULT_OK) {
    880       state->message_count++;
    881     } else if (rv == MOJO_RESULT_FAILED_PRECONDITION) {
    882       MojoRemoveTrigger(state->trap, event->trigger_context, NULL);
    883       return;
    884     }
    885   }
    886 }
    887 
    888 MojoHandle a, b;
    889 MojoCreateMessagePipe(NULL, &a, &b);
    890 
    891 MojoHandle a_trap, b_trap;
    892 MojoCreateTrap(&OnNotification, NULL, &a_trap);
    893 MojoCreateTrap(&OnNotification, NULL, &b_trap)
    894 
    895 struct WatchedHandleState* a_state = malloc(sizeof(struct WatchedHandleState));
    896 a_state->trap = a_trap;
    897 a_state->handle = a;
    898 a_state->message_count = 0;
    899 
    900 struct WatchedHandleState* b_state = malloc(sizeof(struct WatchedHandleState));
    901 b_state->trap = b_trap;
    902 b_state->handle = b;
    903 b_state->message_count = 0;
    904 
    905 MojoAddTrigger(a_trap, a, MOJO_HANDLE_SIGNAL_READABLE,
    906                MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED, (uintptr_t)a_state,
    907                NULL);
    908 MojoAddTrigger(b_trap, b, MOJO_HANDLE_SIGNAL_READABLE,
    909                MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED, (uintptr_t)b_state,
    910                NULL);
    911 
    912 MojoArmTrap(a_trap, NULL, NULL, NULL);
    913 MojoArmTrap(b_trap, NULL, NULL, NULL);
    914 ```
    915 
    916 Now any writes to `a` will increment `message_count` in `b_state`, and any
    917 writes to `b` will increment `message_count` in `a_state`.
    918 
    919 If either `a` or `b` is closed, both watches will be cancelled - one because
    920 watch cancellation is implicit in handle closure, and the other because its
    921 watcher will eventually detect that the handle is no longer readable.
    922 
    923 ## Invitations
    924 
    925 TODO.
    926 
    927 For now see the
    928 [C header](https://cs.chromium.org/src/mojo/public/c/system/invitation.h) and
    929 the documentation for the equivalent
    930 [C++ API](/mojo/public/cpp/system/README.md#Invitations).
    931