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