• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // This file contains types/constants and functions specific to message pipes.
6 //
7 // Note: This header should be compilable as C.
8 
9 #ifndef MOJO_PUBLIC_C_SYSTEM_MESSAGE_PIPE_H_
10 #define MOJO_PUBLIC_C_SYSTEM_MESSAGE_PIPE_H_
11 
12 #include <stdint.h>
13 
14 #include "mojo/public/c/system/macros.h"
15 #include "mojo/public/c/system/system_export.h"
16 #include "mojo/public/c/system/types.h"
17 
18 // |MojoMessageHandle|: Used to refer to message objects created by
19 //     |MojoAllocMessage()| and transferred by |MojoWriteMessageNew()| or
20 //     |MojoReadMessageNew()|.
21 
22 typedef uintptr_t MojoMessageHandle;
23 
24 #ifdef __cplusplus
25 const MojoMessageHandle MOJO_MESSAGE_HANDLE_INVALID = 0;
26 #else
27 #define MOJO_MESSAGE_HANDLE_INVALID ((MojoMessageHandle)0)
28 #endif
29 
30 // |MojoCreateMessagePipeOptions|: Used to specify creation parameters for a
31 // message pipe to |MojoCreateMessagePipe()|.
32 //   |uint32_t struct_size|: Set to the size of the
33 //       |MojoCreateMessagePipeOptions| struct. (Used to allow for future
34 //       extensions.)
35 //   |MojoCreateMessagePipeOptionsFlags flags|: Used to specify different modes
36 //       of operation.
37 //       |MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE|: No flags; default mode.
38 
39 typedef uint32_t MojoCreateMessagePipeOptionsFlags;
40 
41 #ifdef __cplusplus
42 const MojoCreateMessagePipeOptionsFlags
43     MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE = 0;
44 #else
45 #define MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE \
46   ((MojoCreateMessagePipeOptionsFlags)0)
47 #endif
48 
49 MOJO_STATIC_ASSERT(MOJO_ALIGNOF(int64_t) == 8, "int64_t has weird alignment");
50 struct MOJO_ALIGNAS(8) MojoCreateMessagePipeOptions {
51   uint32_t struct_size;
52   MojoCreateMessagePipeOptionsFlags flags;
53 };
54 MOJO_STATIC_ASSERT(sizeof(MojoCreateMessagePipeOptions) == 8,
55                    "MojoCreateMessagePipeOptions has wrong size");
56 
57 // |MojoWriteMessageFlags|: Used to specify different modes to
58 // |MojoWriteMessage()|.
59 //   |MOJO_WRITE_MESSAGE_FLAG_NONE| - No flags; default mode.
60 
61 typedef uint32_t MojoWriteMessageFlags;
62 
63 #ifdef __cplusplus
64 const MojoWriteMessageFlags MOJO_WRITE_MESSAGE_FLAG_NONE = 0;
65 #else
66 #define MOJO_WRITE_MESSAGE_FLAG_NONE ((MojoWriteMessageFlags)0)
67 #endif
68 
69 // |MojoReadMessageFlags|: Used to specify different modes to
70 // |MojoReadMessage()|.
71 //   |MOJO_READ_MESSAGE_FLAG_NONE| - No flags; default mode.
72 //   |MOJO_READ_MESSAGE_FLAG_MAY_DISCARD| - If the message is unable to be read
73 //       for whatever reason (e.g., the caller-supplied buffer is too small),
74 //       discard the message (i.e., simply dequeue it).
75 
76 typedef uint32_t MojoReadMessageFlags;
77 
78 #ifdef __cplusplus
79 const MojoReadMessageFlags MOJO_READ_MESSAGE_FLAG_NONE = 0;
80 const MojoReadMessageFlags MOJO_READ_MESSAGE_FLAG_MAY_DISCARD = 1 << 0;
81 #else
82 #define MOJO_READ_MESSAGE_FLAG_NONE ((MojoReadMessageFlags)0)
83 #define MOJO_READ_MESSAGE_FLAG_MAY_DISCARD ((MojoReadMessageFlags)1 << 0)
84 #endif
85 
86 // |MojoAllocMessageFlags|: Used to specify different options for
87 // |MojoAllocMessage()|.
88 //   |MOJO_ALLOC_MESSAGE_FLAG_NONE| - No flags; default mode.
89 
90 typedef uint32_t MojoAllocMessageFlags;
91 
92 #ifdef __cplusplus
93 const MojoAllocMessageFlags MOJO_ALLOC_MESSAGE_FLAG_NONE = 0;
94 #else
95 #define MOJO_ALLOC_MESSAGE_FLAG_NONE ((MojoAllocMessageFlags)0)
96 #endif
97 
98 #ifdef __cplusplus
99 extern "C" {
100 #endif
101 
102 // Note: See the comment in functions.h about the meaning of the "optional"
103 // label for pointer parameters.
104 
105 // Creates a message pipe, which is a bidirectional communication channel for
106 // framed data (i.e., messages). Messages can contain plain data and/or Mojo
107 // handles.
108 //
109 // |options| may be set to null for a message pipe with the default options.
110 //
111 // On success, |*message_pipe_handle0| and |*message_pipe_handle1| are set to
112 // handles for the two endpoints (ports) for the message pipe.
113 //
114 // Returns:
115 //   |MOJO_RESULT_OK| on success.
116 //   |MOJO_RESULT_INVALID_ARGUMENT| if some argument was invalid (e.g.,
117 //       |*options| is invalid).
118 //   |MOJO_RESULT_RESOURCE_EXHAUSTED| if a process/system/quota/etc. limit has
119 //       been reached.
120 MOJO_SYSTEM_EXPORT MojoResult MojoCreateMessagePipe(
121     const struct MojoCreateMessagePipeOptions* options,  // Optional.
122     MojoHandle* message_pipe_handle0,                    // Out.
123     MojoHandle* message_pipe_handle1);                   // Out.
124 
125 // Writes a message to the message pipe endpoint given by |message_pipe_handle|,
126 // with message data specified by |bytes| of size |num_bytes| and attached
127 // handles specified by |handles| of count |num_handles|, and options specified
128 // by |flags|. If there is no message data, |bytes| may be null, in which case
129 // |num_bytes| must be zero. If there are no attached handles, |handles| may be
130 // null, in which case |num_handles| must be zero.
131 //
132 // If handles are attached, the handles will no longer be valid (on success the
133 // receiver will receive equivalent, but logically different, handles). Handles
134 // to be sent should not be in simultaneous use (e.g., on another thread).
135 //
136 // Returns:
137 //   |MOJO_RESULT_OK| on success (i.e., the message was enqueued).
138 //   |MOJO_RESULT_INVALID_ARGUMENT| if some argument was invalid (e.g., if
139 //       |message_pipe_handle| is not a valid handle, or some of the
140 //       requirements above are not satisfied).
141 //   |MOJO_RESULT_RESOURCE_EXHAUSTED| if some system limit has been reached, or
142 //       the number of handles to send is too large (TODO(vtl): reconsider the
143 //       latter case).
144 //   |MOJO_RESULT_FAILED_PRECONDITION| if the other endpoint has been closed.
145 //       Note that closing an endpoint is not necessarily synchronous (e.g.,
146 //       across processes), so this function may succeed even if the other
147 //       endpoint has been closed (in which case the message would be dropped).
148 //   |MOJO_RESULT_UNIMPLEMENTED| if an unsupported flag was set in |*options|.
149 //   |MOJO_RESULT_BUSY| if some handle to be sent is currently in use.
150 //
151 // TODO(vtl): Add a notion of capacity for message pipes, and return
152 // |MOJO_RESULT_SHOULD_WAIT| if the message pipe is full.
153 MOJO_SYSTEM_EXPORT MojoResult
154     MojoWriteMessage(MojoHandle message_pipe_handle,
155                      const void* bytes,  // Optional.
156                      uint32_t num_bytes,
157                      const MojoHandle* handles,  // Optional.
158                      uint32_t num_handles,
159                      MojoWriteMessageFlags flags);
160 
161 // Writes a message to the message pipe endpoint given by |message_pipe_handle|.
162 //
163 // |message|: A message object allocated by |MojoAllocMessage()|. Ownership of
164 //     the message is passed into Mojo.
165 //
166 // Returns results corresponding to |MojoWriteMessage()| above.
167 MOJO_SYSTEM_EXPORT MojoResult
168     MojoWriteMessageNew(MojoHandle message_pipe_handle,
169                         MojoMessageHandle message,
170                         MojoWriteMessageFlags);
171 
172 // Reads the next message from a message pipe, or indicates the size of the
173 // message if it cannot fit in the provided buffers. The message will be read
174 // in its entirety or not at all; if it is not, it will remain enqueued unless
175 // the |MOJO_READ_MESSAGE_FLAG_MAY_DISCARD| flag was passed. At most one
176 // message will be consumed from the queue, and the return value will indicate
177 // whether a message was successfully read.
178 //
179 // |num_bytes| and |num_handles| are optional in/out parameters that on input
180 // must be set to the sizes of the |bytes| and |handles| arrays, and on output
181 // will be set to the actual number of bytes or handles contained in the
182 // message (even if the message was not retrieved due to being too large).
183 // Either |num_bytes| or |num_handles| may be null if the message is not
184 // expected to contain the corresponding type of data, but such a call would
185 // fail with |MOJO_RESULT_RESOURCE_EXHAUSTED| if the message in fact did
186 // contain that type of data.
187 //
188 // |bytes| and |handles| will receive the contents of the message, if it is
189 // retrieved. Either or both may be null, in which case the corresponding size
190 // parameter(s) must also be set to zero or passed as null.
191 //
192 // Returns:
193 //   |MOJO_RESULT_OK| on success (i.e., a message was actually read).
194 //   |MOJO_RESULT_INVALID_ARGUMENT| if some argument was invalid.
195 //   |MOJO_RESULT_FAILED_PRECONDITION| if the other endpoint has been closed.
196 //   |MOJO_RESULT_RESOURCE_EXHAUSTED| if the message was too large to fit in the
197 //       provided buffer(s). The message will have been left in the queue or
198 //       discarded, depending on flags.
199 //   |MOJO_RESULT_SHOULD_WAIT| if no message was available to be read.
200 //
201 // TODO(vtl): Reconsider the |MOJO_RESULT_RESOURCE_EXHAUSTED| error code; should
202 // distinguish this from the hitting-system-limits case.
203 MOJO_SYSTEM_EXPORT MojoResult
204     MojoReadMessage(MojoHandle message_pipe_handle,
205                     void* bytes,            // Optional out.
206                     uint32_t* num_bytes,    // Optional in/out.
207                     MojoHandle* handles,    // Optional out.
208                     uint32_t* num_handles,  // Optional in/out.
209                     MojoReadMessageFlags flags);
210 
211 // Reads the next message from a message pipe and returns a message containing
212 // the message bytes. The returned message must eventually be freed using
213 // |MojoFreeMessage()|.
214 //
215 // Message payload can be accessed using |MojoGetMessageBuffer()|.
216 //
217 //   |message_pipe_handle|, |num_bytes|, |handles|, |num_handles|, and |flags|
218 //       correspond to their use in |MojoReadMessage()| above, with the
219 //       exception that |num_bytes| is only an output argument.
220 //   |message| must be non-null unless |MOJO_READ_MESSAGE_FLAG_MAY_DISCARD| is
221 //       set in flags.
222 //
223 // Return values correspond to the return values for |MojoReadMessage()| above.
224 // On success (MOJO_RESULT_OK), |*message| will contain a handle to a message
225 // object which may be passed to |MojoGetMessageBuffer()|. The caller owns the
226 // message object and is responsible for freeing it via |MojoFreeMessage()|.
227 MOJO_SYSTEM_EXPORT MojoResult
228     MojoReadMessageNew(MojoHandle message_pipe_handle,
229                        MojoMessageHandle* message,  // Optional out.
230                        uint32_t* num_bytes,         // Optional out.
231                        MojoHandle* handles,         // Optional out.
232                        uint32_t* num_handles,       // Optional in/out.
233                        MojoReadMessageFlags flags);
234 
235 // Fuses two message pipe endpoints together. Given two pipes:
236 //
237 //     A <-> B    and    C <-> D
238 //
239 // Fusing handle B and handle C results in a single pipe:
240 //
241 //     A <-> D
242 //
243 // Handles B and C are ALWAYS closed. Any unread messages at C will eventually
244 // be delivered to A, and any unread messages at B will eventually be delivered
245 // to D.
246 //
247 // NOTE: A handle may only be fused if it is an open message pipe handle which
248 // has not been written to.
249 //
250 // Returns:
251 //   |MOJO_RESULT_OK| on success.
252 //   |MOJO_RESULT_FAILED_PRECONDITION| if both handles were valid message pipe
253 //       handles but could not be merged (e.g. one of them has been written to).
254 //   |MOJO_INVALID_ARGUMENT| if either handle is not a fusable message pipe
255 //       handle.
256 MOJO_SYSTEM_EXPORT MojoResult
257     MojoFuseMessagePipes(MojoHandle handle0, MojoHandle handle1);
258 
259 // Allocates a new message whose ownership may be passed to
260 // |MojoWriteMessageNew()|. Use |MojoGetMessageBuffer()| to retrieve the address
261 // of the mutable message payload.
262 //
263 // |num_bytes|: The size of the message payload in bytes.
264 // |handles|: An array of handles to transfer in the message. This takes
265 //     ownership of and invalidates all contained handles. Must be null if and
266 //     only if |num_handles| is 0.
267 // |num_handles|: The number of handles contained in |handles|.
268 // |flags|: Must be |MOJO_CREATE_MESSAGE_FLAG_NONE|.
269 // |message|: The address of a handle to be filled with the allocated message's
270 //     handle. Must be non-null.
271 //
272 // Returns:
273 //   |MOJO_RESULT_OK| if the message was successfully allocated. In this case
274 //       |*message| will be populated with a handle to an allocated message
275 //       with a buffer large enough to hold |num_bytes| contiguous bytes.
276 //   |MOJO_RESULT_INVALID_ARGUMENT| if one or more handles in |handles| was
277 //       invalid, or |handles| was null with a non-zero |num_handles|.
278 //   |MOJO_RESULT_RESOURCE_EXHAUSTED| if allocation failed because either
279 //       |num_bytes| or |num_handles| exceeds an implementation-defined maximum.
280 //   |MOJO_RESULT_BUSY| if one or more handles in |handles| cannot be sent at
281 //       the time of this call.
282 //
283 // Only upon successful message allocation will all handles in |handles| be
284 // transferred into the message and invalidated.
285 MOJO_SYSTEM_EXPORT MojoResult
286 MojoAllocMessage(uint32_t num_bytes,
287                  const MojoHandle* handles,
288                  uint32_t num_handles,
289                  MojoAllocMessageFlags flags,
290                  MojoMessageHandle* message);  // Out
291 
292 // Frees a message allocated by |MojoAllocMessage()| or |MojoReadMessageNew()|.
293 //
294 // |message|: The message to free. This must correspond to a message previously
295 //     allocated by |MojoAllocMessage()| or |MojoReadMessageNew()|. Note that if
296 //     the message has already been passed to |MojoWriteMessageNew()| it should
297 //     NOT also be freed with this API.
298 //
299 // Returns:
300 //   |MOJO_RESULT_OK| if |message| was valid and has been freed.
301 //   |MOJO_RESULT_INVALID_ARGUMENT| if |message| was not a valid message.
302 MOJO_SYSTEM_EXPORT MojoResult MojoFreeMessage(MojoMessageHandle message);
303 
304 // Retrieves the address of mutable message bytes for a message allocated by
305 // either |MojoAllocMessage()| or |MojoReadMessageNew()|.
306 //
307 // Returns:
308 //   |MOJO_RESULT_OK| if |message| is a valid message object. |*buffer| will
309 //       be updated to point to mutable message bytes.
310 //   |MOJO_RESULT_INVALID_ARGUMENT| if |message| is not a valid message object.
311 //
312 // NOTE: A returned buffer address is always guaranteed to be 8-byte aligned.
313 MOJO_SYSTEM_EXPORT MojoResult MojoGetMessageBuffer(MojoMessageHandle message,
314                                                    void** buffer);  // Out
315 
316 // Notifies the system that a bad message was received on a message pipe,
317 // according to whatever criteria the caller chooses. This ultimately tries to
318 // notify the embedder about the bad message, and the embedder may enforce some
319 // policy for dealing with the source of the message (e.g. close the pipe,
320 // terminate, a process, etc.) The embedder may not be notified if the calling
321 // process has lost its connection to the source process.
322 //
323 // |message|: The message to report as bad. This must have come from a call to
324 //     |MojoReadMessageNew()|.
325 // |error|: An error string which may provide the embedder with context when
326 //     notified of this error.
327 // |error_num_bytes|: The length of |error| in bytes.
328 //
329 // Returns:
330 //   |MOJO_RESULT_OK| if successful.
331 //   |MOJO_RESULT_INVALID_ARGUMENT| if |message| is not a valid message.
332 MOJO_SYSTEM_EXPORT MojoResult
333 MojoNotifyBadMessage(MojoMessageHandle message,
334                      const char* error,
335                      size_t error_num_bytes);
336 
337 #ifdef __cplusplus
338 }  // extern "C"
339 #endif
340 
341 #endif  // MOJO_PUBLIC_C_SYSTEM_MESSAGE_PIPE_H_
342