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