1 /* 2 * Copyright (c) 2012-2013 Apple Inc. All rights reserved. 3 * 4 * @APPLE_APACHE_LICENSE_HEADER_START@ 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * @APPLE_APACHE_LICENSE_HEADER_END@ 19 */ 20 21 /* 22 * IMPORTANT: This header file describes INTERNAL interfaces to libdispatch 23 * which are subject to change in future releases of Mac OS X. Any applications 24 * relying on these interfaces WILL break. 25 */ 26 27 #ifndef __DISPATCH_MACH_PRIVATE__ 28 #define __DISPATCH_MACH_PRIVATE__ 29 30 #ifndef __DISPATCH_INDIRECT__ 31 #error "Please #include <dispatch/dispatch.h> instead of this file directly." 32 #include <dispatch/base.h> // for HeaderDoc 33 #endif 34 35 __BEGIN_DECLS 36 37 #if DISPATCH_MACH_SPI 38 39 #include <mach/mach.h> 40 41 /*! 42 * @functiongroup Dispatch Mach Channel SPI 43 * 44 * IMPORTANT: This is Libsystem-internal SPI not intended for general use and 45 * is subject to change at any time without warning. 46 */ 47 48 /*! 49 * @typedef dispatch_mach_t 50 * A dispatch mach channel asynchronously recevives and sends mach messages. 51 */ 52 DISPATCH_DECL(dispatch_mach); 53 54 /*! 55 * @typedef dispatch_mach_reason_t 56 * Reasons for a mach channel handler to be invoked. 57 * 58 * @const DISPATCH_MACH_CONNECTED 59 * The channel has been connected. The first handler invocation on a channel 60 * after calling dispatch_mach_connect() will have this reason. 61 * 62 * @const DISPATCH_MACH_MESSAGE_RECEIVED 63 * A message was received, it is passed in the message parameter. 64 * 65 * @const DISPATCH_MACH_MESSAGE_SENT 66 * A message was sent, it is passed in the message parameter (so that associated 67 * resources can be disposed of). 68 * 69 * @const DISPATCH_MACH_MESSAGE_SEND_FAILED 70 * A message failed to be sent, it is passed in the message parameter (so that 71 * associated resources can be disposed of), along with the error code from 72 * mach_msg(). 73 * 74 * @const DISPATCH_MACH_MESSAGE_NOT_SENT 75 * A message was not sent due to the channel being canceled or reconnected, it 76 * is passed in the message parameter (so that associated resources can be 77 * disposed of). 78 * 79 * @const DISPATCH_MACH_BARRIER_COMPLETED 80 * A barrier block has finished executing. 81 * 82 * @const DISPATCH_MACH_DISCONNECTED 83 * The channel has been disconnected by a call to dispatch_mach_reconnect() or 84 * dispatch_mach_cancel(), an empty message is passed in the message parameter 85 * (so that associated port rights can be disposed of). 86 * The message header will contain either a remote port with a previously 87 * connected send right, or a local port with a previously connected receive 88 * right (if the channel was canceled), or a local port with a receive right 89 * that was being monitored for a direct reply to a message previously sent to 90 * the channel (if no reply was received). 91 * 92 * @const DISPATCH_MACH_CANCELED 93 * The channel has been canceled. 94 */ 95 DISPATCH_ENUM(dispatch_mach_reason, unsigned long, 96 DISPATCH_MACH_CONNECTED = 1, 97 DISPATCH_MACH_MESSAGE_RECEIVED, 98 DISPATCH_MACH_MESSAGE_SENT, 99 DISPATCH_MACH_MESSAGE_SEND_FAILED, 100 DISPATCH_MACH_MESSAGE_NOT_SENT, 101 DISPATCH_MACH_BARRIER_COMPLETED, 102 DISPATCH_MACH_DISCONNECTED, 103 DISPATCH_MACH_CANCELED, 104 DISPATCH_MACH_REASON_LAST, /* unused */ 105 ); 106 107 /*! 108 * @typedef dispatch_mach_trailer_t 109 * Trailer type of mach message received by dispatch mach channels 110 */ 111 112 typedef mach_msg_context_trailer_t dispatch_mach_trailer_t; 113 114 /*! 115 * @constant DISPATCH_MACH_RECEIVE_MAX_INLINE_MESSAGE_SIZE 116 * Maximum size of a message that can be received inline by a dispatch mach 117 * channel, reception of larger messages requires an extra roundtrip through 118 * the kernel. 119 */ 120 121 #define DISPATCH_MACH_RECEIVE_MAX_INLINE_MESSAGE_SIZE \ 122 (0x4000 - sizeof(dispatch_mach_trailer_t)) 123 124 /*! 125 * @typedef dispatch_mach_msg_t 126 * A dispatch mach message encapsulates messages received or sent with dispatch 127 * mach channels. 128 */ 129 DISPATCH_DECL(dispatch_mach_msg); 130 131 /*! 132 * @typedef dispatch_mach_msg_destructor_t 133 * Dispatch mach message object destructors. 134 * 135 * @const DISPATCH_MACH_MSG_DESTRUCTOR_DEFAULT 136 * Message buffer storage is internal to the object, if a buffer is supplied 137 * during object creation, its contents are copied. 138 * 139 * @const DISPATCH_MACH_MSG_DESTRUCTOR_FREE 140 * Message buffer will be deallocated with free(3). 141 * 142 * @const DISPATCH_MACH_MSG_DESTRUCTOR_FREE 143 * Message buffer will be deallocated with vm_deallocate. 144 */ 145 DISPATCH_ENUM(dispatch_mach_msg_destructor, unsigned int, 146 DISPATCH_MACH_MSG_DESTRUCTOR_DEFAULT = 0, 147 DISPATCH_MACH_MSG_DESTRUCTOR_FREE, 148 DISPATCH_MACH_MSG_DESTRUCTOR_VM_DEALLOCATE, 149 ); 150 151 /*! 152 * @function dispatch_mach_msg_create 153 * Creates a dispatch mach message object, either with a newly allocated message 154 * buffer of given size, or from an existing message buffer that will be 155 * deallocated with the specified destructor when the object is released. 156 * 157 * If a non-NULL reference to a pointer is provided in 'msg_ptr', it is filled 158 * with the location of the (possibly newly allocated) message buffer. 159 * 160 * It is the responsibility of the application to ensure that it does not modify 161 * the underlying message buffer once the dispatch mach message object is passed 162 * to other dispatch mach API. 163 * 164 * @param msg The message buffer to create the message object from. 165 * If 'destructor' is DISPATCH_MACH_MSG_DESTRUCTOR_DEFAULT, 166 * this argument may be NULL to leave the newly allocated 167 * message buffer zero-initialized. 168 * @param size The size of the message buffer. 169 * Must be >= sizeof(mach_msg_header_t) 170 * @param destructor The destructor to use to deallocate the message buffer 171 * when the object is released. 172 * @param msg_ptr A pointer to a pointer variable to be filled with the 173 * location of the (possibly newly allocated) message 174 * buffer, or NULL. 175 * @result A newly created dispatch mach message object. 176 */ 177 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) 178 DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT 179 DISPATCH_NOTHROW 180 dispatch_mach_msg_t 181 dispatch_mach_msg_create(mach_msg_header_t *msg, size_t size, 182 dispatch_mach_msg_destructor_t destructor, mach_msg_header_t **msg_ptr); 183 184 /*! 185 * @function dispatch_mach_msg_get_msg 186 * Returns the message buffer underlying a dispatch mach message object. 187 * 188 * @param message The dispatch mach message object to query. 189 * @param size_ptr A pointer to a size_t variable to be filled with the 190 * size of the message buffer, or NULL. 191 * @result Pointer to message buffer underlying the object. 192 */ 193 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) 194 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW 195 mach_msg_header_t* 196 dispatch_mach_msg_get_msg(dispatch_mach_msg_t message, size_t *size_ptr); 197 198 #ifdef __BLOCKS__ 199 /*! 200 * @typedef dispatch_mach_handler_t 201 * Prototype of dispatch mach channel handler blocks. 202 * 203 * @param reason Reason the handler was invoked. 204 * @param message Message object that was sent or received. 205 * @param error Mach error code for the send operation. 206 */ 207 typedef void (^dispatch_mach_handler_t)(dispatch_mach_reason_t reason, 208 dispatch_mach_msg_t message, mach_error_t error); 209 210 /*! 211 * @function dispatch_mach_create 212 * Create a dispatch mach channel to asynchronously receive and send mach 213 * messages. 214 * 215 * The specified handler will be called with the corresponding reason parameter 216 * for each message received and for each message that was successfully sent, 217 * that failed to be sent, or was not sent; as well as when a barrier block 218 * has completed, or when channel connection, reconnection or cancellation has 219 * taken effect. 220 * 221 * Dispatch mach channels are created in a disconnected state, they must be 222 * connected via dispatch_mach_connect() to begin receiving and sending 223 * messages. 224 * 225 * @param label 226 * An optional string label to attach to the channel. The string is not copied, 227 * if it is non-NULL it must point to storage that remains valid for the 228 * lifetime of the channel object. May be NULL. 229 * 230 * @param queue 231 * The target queue of the channel, where the handler and barrier blocks will 232 * be submitted. 233 * 234 * @param handler 235 * The handler block to submit when a message has been sent or received. 236 * 237 * @result 238 * The newly created dispatch mach channel. 239 */ 240 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 241 DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT 242 DISPATCH_NONNULL3 DISPATCH_NOTHROW 243 dispatch_mach_t 244 dispatch_mach_create(const char *label, dispatch_queue_t queue, 245 dispatch_mach_handler_t handler); 246 #endif 247 248 /*! 249 * @typedef dispatch_mach_handler_function_t 250 * Prototype of dispatch mach channel handler functions. 251 * 252 * @param context Application-defined context parameter. 253 * @param reason Reason the handler was invoked. 254 * @param message Message object that was sent or received. 255 * @param error Mach error code for the send operation. 256 */ 257 typedef void (*dispatch_mach_handler_function_t)(void *context, 258 dispatch_mach_reason_t reason, dispatch_mach_msg_t message, 259 mach_error_t error); 260 261 /*! 262 * @function dispatch_mach_create_f 263 * Create a dispatch mach channel to asynchronously receive and send mach 264 * messages. 265 * 266 * The specified handler will be called with the corresponding reason parameter 267 * for each message received and for each message that was successfully sent, 268 * that failed to be sent, or was not sent; as well as when a barrier block 269 * has completed, or when channel connection, reconnection or cancellation has 270 * taken effect. 271 * 272 * Dispatch mach channels are created in a disconnected state, they must be 273 * connected via dispatch_mach_connect() to begin receiving and sending 274 * messages. 275 * 276 * @param label 277 * An optional string label to attach to the channel. The string is not copied, 278 * if it is non-NULL it must point to storage that remains valid for the 279 * lifetime of the channel object. May be NULL. 280 * 281 * @param queue 282 * The target queue of the channel, where the handler and barrier blocks will 283 * be submitted. 284 * 285 * @param context 286 * The application-defined context to pass to the handler. 287 * 288 * @param handler 289 * The handler function to submit when a message has been sent or received. 290 * 291 * @result 292 * The newly created dispatch mach channel. 293 */ 294 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 295 DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT 296 DISPATCH_NONNULL4 DISPATCH_NOTHROW 297 dispatch_mach_t 298 dispatch_mach_create_f(const char *label, dispatch_queue_t queue, void *context, 299 dispatch_mach_handler_function_t handler); 300 301 /*! 302 * @function dispatch_mach_connect 303 * Connect a mach channel to the specified receive and send rights. 304 * 305 * This function must only be called once during the lifetime of a channel, it 306 * will initiate message reception and perform any already submitted message 307 * sends or barrier operations. 308 * 309 * @param channel 310 * The mach channel to connect. 311 * 312 * @param receive 313 * The receive right to associate with the channel. May be MACH_PORT_NULL. 314 * 315 * @param send 316 * The send right to associate with the channel. May be MACH_PORT_NULL. 317 * 318 * @param checkin 319 * An optional message object encapsulating the initial check-in message to send 320 * upon channel connection. The check-in message is sent immediately before the 321 * first message submitted via dispatch_mach_send(). The message object will be 322 * retained until the initial send operation is complete (or not peformed due 323 * to channel cancellation or reconnection) and the channel handler has 324 * returned. May be NULL. 325 */ 326 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 327 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW 328 void 329 dispatch_mach_connect(dispatch_mach_t channel, mach_port_t receive, 330 mach_port_t send, dispatch_mach_msg_t checkin); 331 332 /*! 333 * @function dispatch_mach_reconnect 334 * Reconnect a mach channel to the specified send right. 335 * 336 * Disconnects the channel from the current send right, interrupts any pending 337 * message sends (and returns the messages as unsent), and reconnects the 338 * channel to a new send right. 339 * 340 * The application must wait for the channel handler to be invoked with 341 * DISPATCH_MACH_DISCONNECTED before releasing the previous send right. 342 * 343 * @param channel 344 * The mach channel to reconnect. 345 * 346 * @param send 347 * The new send right to associate with the channel. May be MACH_PORT_NULL. 348 * 349 * @param checkin 350 * An optional message object encapsulating the initial check-in message to send 351 * upon channel reconnection. The check-in message is sent immediately before 352 * the first message submitted via dispatch_mach_send() after this function 353 * returns. The message object will be retained until the initial send operation 354 * is complete (or not peformed due to channel cancellation or reconnection) 355 * and the channel handler has returned. May be NULL. 356 */ 357 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 358 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW 359 void 360 dispatch_mach_reconnect(dispatch_mach_t channel, mach_port_t send, 361 dispatch_mach_msg_t checkin); 362 363 /*! 364 * @function dispatch_mach_cancel 365 * Cancel a mach channel, preventing any further messages from being sent or 366 * received. 367 * 368 * The application must wait for the channel handler to be invoked with 369 * DISPATCH_MACH_DISCONNECTED before releasing the underlying send and receive 370 * rights. 371 * 372 * Note: explicit cancellation of mach channels is required, no implicit 373 * cancellation takes place on release of the last application reference 374 * to the channel object. Failure to cancel will cause the channel and 375 * its associated resources to be leaked. 376 * 377 * @param channel 378 * The mach channel to cancel. 379 */ 380 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 381 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 382 void 383 dispatch_mach_cancel(dispatch_mach_t channel); 384 385 /*! 386 * @function dispatch_mach_send 387 * Asynchronously send a message encapsulated in a dispatch mach message object 388 * to the specified mach channel. 389 * 390 * Unless the message is being sent to a send-once right (as determined by the 391 * presence of MACH_MSG_TYPE_MOVE_SEND_ONCE in the message header remote bits), 392 * the message header remote port is set to the channel send right before the 393 * send operation is performed. 394 * 395 * If the message expects a direct reply (as determined by the presence of 396 * MACH_MSG_TYPE_MAKE_SEND_ONCE in the message header local bits) the receive 397 * right specified in the message header local port will be monitored until a 398 * reply message (or a send-once notification) is received, or the channel is 399 * canceled. Hence the application must wait for the channel handler to be 400 * invoked with a DISPATCH_MACH_DISCONNECTED message before releasing that 401 * receive right. 402 * 403 * If the message send operation is attempted but the channel is canceled 404 * before the send operation succesfully completes, the message returned to the 405 * channel handler with DISPATCH_MACH_MESSAGE_NOT_SENT may be the result of a 406 * pseudo-receive operation. If the message expected a direct reply, the 407 * receive right originally specified in the message header local port will 408 * returned in a DISPATCH_MACH_DISCONNECTED message. 409 * 410 * @param channel 411 * The mach channel to which to send the message. 412 * 413 * @param message 414 * The message object encapsulating the message to send. The object will be 415 * retained until the send operation is complete and the channel handler has 416 * returned. The storage underlying the message object may be modified by the 417 * send operation. 418 * 419 * @param options 420 * Additional send options to pass to mach_msg() when performing the send 421 * operation. 422 */ 423 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 424 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL2 DISPATCH_NOTHROW 425 void 426 dispatch_mach_send(dispatch_mach_t channel, dispatch_mach_msg_t message, 427 mach_msg_option_t options); 428 429 #ifdef __BLOCKS__ 430 /*! 431 * @function dispatch_mach_send_barrier 432 * Submit a send barrier to the specified mach channel. Messages submitted to 433 * the channel before the barrier will be sent before the barrier block is 434 * executed, and messages submitted to the channel after the barrier will only 435 * be sent once the barrier block has completed and the channel handler 436 * invocation for the barrier has returned. 437 * 438 * @param channel 439 * The mach channel to which to submit the barrier. 440 * 441 * @param barrier 442 * The barrier block to submit to the channel target queue. 443 */ 444 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 445 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 446 void 447 dispatch_mach_send_barrier(dispatch_mach_t channel, dispatch_block_t barrier); 448 #endif 449 450 /*! 451 * @function dispatch_mach_send_barrier_f 452 * Submit a send barrier to the specified mach channel. Messages submitted to 453 * the channel before the barrier will be sent before the barrier block is 454 * executed, and messages submitted to the channel after the barrier will only 455 * be sent once the barrier block has completed and the channel handler 456 * invocation for the barrier has returned. 457 * 458 * @param channel 459 * The mach channel to which to submit the barrier. 460 * 461 * @param context 462 * The application-defined context parameter to pass to the function. 463 * 464 * @param barrier 465 * The barrier function to submit to the channel target queue. 466 */ 467 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 468 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW 469 void 470 dispatch_mach_send_barrier_f(dispatch_mach_t channel, void *context, 471 dispatch_function_t barrier); 472 473 #ifdef __BLOCKS__ 474 /*! 475 * @function dispatch_mach_receive_barrier 476 * Submit a receive barrier to the specified mach channel. Channel handlers for 477 * messages received by the channel after the receive barrier has been 478 * submitted will only be invoked once the barrier block has completed and the 479 * channel handler invocation for the barrier has returned. 480 * 481 * @param channel 482 * The mach channel to which to submit the receive barrier. 483 * 484 * @param barrier 485 * The barrier block to submit to the channel target queue. 486 */ 487 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 488 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 489 void 490 dispatch_mach_receive_barrier(dispatch_mach_t channel, 491 dispatch_block_t barrier); 492 #endif 493 494 /*! 495 * @function dispatch_mach_receive_barrier_f 496 * Submit a receive barrier to the specified mach channel. Channel handlers for 497 * messages received by the channel after the receive barrier has been 498 * submitted will only be invoked once the barrier block has completed and the 499 * channel handler invocation for the barrier has returned. 500 * 501 * @param channel 502 * The mach channel to which to submit the receive barrier. 503 * 504 * @param context 505 * The application-defined context parameter to pass to the function. 506 * 507 * @param barrier 508 * The barrier function to submit to the channel target queue. 509 */ 510 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 511 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW 512 void 513 dispatch_mach_receive_barrier_f(dispatch_mach_t channel, void *context, 514 dispatch_function_t barrier); 515 516 /*! 517 * @function dispatch_mach_get_checkin_port 518 * Returns the port specified in the message header remote port of the check-in 519 * message passed to the most recent invocation of dispatch_mach_connect() or 520 * dispatch_mach_reconnect() for the provided mach channel (irrespective of the 521 * completion of the (re)connect or check-in operations in question). 522 * 523 * Returns MACH_PORT_NULL if dispatch_mach_connect() has not yet been called or 524 * if the most recently specified check-in message was NULL, and MACH_PORT_DEAD 525 * if the channel has been canceled. 526 * 527 * It is the responsibility of the application to ensure that the port 528 * specified in a check-in message remains valid at the time this function is 529 * called. 530 * 531 * @param channel 532 * The mach channel to query. 533 * 534 * @result 535 * The most recently specified check-in port for the channel. 536 */ 537 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 538 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 539 mach_port_t 540 dispatch_mach_get_checkin_port(dispatch_mach_t channel); 541 542 #endif // DISPATCH_MACH_SPI 543 544 __END_DECLS 545 546 #endif 547