OLD | NEW |
1 # Message pipes | 1 # Message pipes |
2 | 2 |
3 Message pipes are the primary communication mechanism between Mojo programs. A | 3 Message pipes are the primary communication mechanism between Mojo programs. A |
4 *message pipe* is a point-to-point (with each side being called a message pipe | 4 *message pipe* is a point-to-point (with each side being called a message pipe |
5 *endpoint*), bidirectional message passing mechanism, where messages may contain | 5 *endpoint*), bidirectional message passing mechanism, where messages may contain |
6 both data and Mojo handles. | 6 both data and Mojo handles. |
7 | 7 |
8 It's important to understand that a message pipe is a "transport": it provides a | 8 It's important to understand that a message pipe is a "transport": it provides a |
9 way for data and handles to be sent between Mojo programs. The system is unaware | 9 way for data and handles to be sent between Mojo programs. The system is unaware |
10 of the meaning of the data or of the handles (other than their intrinsic | 10 of the meaning of the data or of the handles (other than their intrinsic |
11 properties). | 11 properties). |
12 | 12 |
13 That said, Mojo provides a *standard* way of communicating over message pipes, | 13 That said, Mojo provides a *standard* way of communicating over message pipes, |
14 namely via a standardized protocol together with [Mojom IDL](mojom.md) files. | 14 namely via a standardized protocol together with [Mojom](mojom.md) IDL files. |
15 | 15 |
16 ## Messages | 16 ## Messages |
17 | 17 |
18 A *message* consists of two things: | 18 A *message* consists of two things: |
19 * a finite sequence of bytes, and | 19 * a finite sequence of bytes, and |
20 * a finite sequence of Mojo handles. | 20 * a finite sequence of [Mojo handles](handles.md). |
21 | 21 |
22 Both of these are determined when the message is sent (or *written*). Messages | 22 Both of these are determined when the message is sent (or *written*). Messages |
23 are *framed* in the sense that they are "atomic" units: they are sent and | 23 are *framed* in the sense that they are "atomic" units: they are sent and |
24 received (or *read*) as entire units, not just by Mojo programs themselves but | 24 received (or *read*) as entire units, not just by Mojo programs themselves but |
25 by the system, which is aware of and enforces the message boundaries. | 25 by the system, which is aware of and enforces the message boundaries. |
26 | 26 |
27 (Note on terminology: We'll use "send" and "write" interchangeably, and | 27 (Note on terminology: We'll use "send" and "write" interchangeably, and |
28 similarly for "receive" and "read". "Write" and "read" correspond more closely | 28 similarly for "receive" and "read". "Write" and "read" correspond more closely |
29 to the names usually given to the basic Mojo operations, e.g., | 29 to the names usually given to the basic Mojo operations, e.g., |
30 `MojoWriteMessage()` and `MojoReadMessage()`. | 30 `MojoWriteMessage()` and `MojoReadMessage()`. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 Thus we allow unlimited queueing. (**TODO(vtl)**: Probably we'll eventually | 68 Thus we allow unlimited queueing. (**TODO(vtl)**: Probably we'll eventually |
69 allow "hard" queue limits to be set for the purposes of preventing | 69 allow "hard" queue limits to be set for the purposes of preventing |
70 denial-of-service. However, the response to overruns will be hard failures, in | 70 denial-of-service. However, the response to overruns will be hard failures, in |
71 the sense that the message pipe may be destroyed, rather than soft, | 71 the sense that the message pipe may be destroyed, rather than soft, |
72 "recoverable" failures -- since those expose deadlock issues.) It is then up to | 72 "recoverable" failures -- since those expose deadlock issues.) It is then up to |
73 Mojo programs to implement flow control in some way. (**TODO(vtl)**: Write more | 73 Mojo programs to implement flow control in some way. (**TODO(vtl)**: Write more |
74 about this in the context of Mojom.) | 74 about this in the context of Mojom.) |
75 | 75 |
76 ## "Synchronous" operation | 76 ## "Synchronous" operation |
77 | 77 |
78 **TODO(vtl)** | 78 Though message pipes are asynchronous as discussed above, they may be used in a |
| 79 synchronous fashion: immediately after sending a *request* message, one can then |
| 80 just block and wait for the *response* message (and then read it and process |
| 81 it). Of course, this requires that the protocol support this: |
| 82 * Message pipes must be used in a "directional" way: there must be fixed request |
| 83 and response directions or, equivalently, one endpoint belongs to the *client* |
| 84 and the other to the *server* (or *impl*). (Historical note: This is the case |
| 85 for the current Mojom protocol, but not in previous versions.) The issue here |
| 86 is that without this, the sender of the request messages may have to process |
| 87 incoming request messages from its peer. |
| 88 * Request messages must have unique response messages. (In the Mojom protocol, |
| 89 request messages have optional unique responses. For messages without |
| 90 responses, one can just proceed immediately without waiting. However, without |
| 91 response messages there may be flow control issues; again, see above.) The |
| 92 important point is that for each request message, there is a well-defined |
| 93 number of response messages for each request and not arbitrary "callback" |
| 94 messages. |
| 95 * The sending of a response message must not depend on a future action of the |
| 96 client. (This is a higher-level semantic that is not enforced by the Mojom |
| 97 protocol. E.g., one may define a Mojom interface in which the response to a |
| 98 message *Foo* isn't sent until the client sends a request *Bar*.) |
| 99 |
| 100 That said, whether one wants to, or even can, use this synchronous mode of |
| 101 operation may depend on a number of things: |
| 102 * For message-loop-centric programming languages, this mode is at best |
| 103 undesirable (and possibly infeasible, depending on what facilities are exposed |
| 104 to user code). (E.g., this is the case for JavaScript and Dart.) |
| 105 * Similarly, on a message-loop programming model (in which threads -- if there |
| 106 are more than one -- are mostly coordinated by "message passing"), it is |
| 107 typically undesirable to block any thread (with a message loop). Indeed, if |
| 108 other message pipes are serviced by a message loop, blocking the thread may |
| 109 result in deadlock. (E.g., this is the usual programming model for the |
| 110 standard Mojom C++ bindings.) |
| 111 * Even when blocking is permissible, it may not be desirable to do so: |
| 112 advancement of the program then relies on trusting the server to be |
| 113 responsive and send responses in a timely fashion. |
| 114 * Mixing asynchronous and synchronous operation is problematic: one cannot send |
| 115 a request and synchronously wait for a response while responses to other |
| 116 messages are still pending. (Theoretically, one could buffer such other |
| 117 responses until the response to particular request is received, and process |
| 118 those other responses later, but this would be dubious at best.) |
OLD | NEW |