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 */ 52DISPATCH_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 */ 95DISPATCH_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 112typedef 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 ((PAGE_SIZE > 0x1000 ? 1 : 3) * PAGE_SIZE - \ 123 sizeof(dispatch_mach_trailer_t)) 124 125/*! 126 * @typedef dispatch_mach_msg_t 127 * A dispatch mach message encapsulates messages received or sent with dispatch 128 * mach channels. 129 */ 130DISPATCH_DECL(dispatch_mach_msg); 131 132/*! 133 * @typedef dispatch_mach_msg_destructor_t 134 * Dispatch mach message object destructors. 135 * 136 * @const DISPATCH_MACH_MSG_DESTRUCTOR_DEFAULT 137 * Message buffer storage is internal to the object, if a buffer is supplied 138 * during object creation, its contents are copied. 139 * 140 * @const DISPATCH_MACH_MSG_DESTRUCTOR_FREE 141 * Message buffer will be deallocated with free(3). 142 * 143 * @const DISPATCH_MACH_MSG_DESTRUCTOR_FREE 144 * Message buffer will be deallocated with vm_deallocate. 145 */ 146DISPATCH_ENUM(dispatch_mach_msg_destructor, unsigned int, 147 DISPATCH_MACH_MSG_DESTRUCTOR_DEFAULT = 0, 148 DISPATCH_MACH_MSG_DESTRUCTOR_FREE, 149 DISPATCH_MACH_MSG_DESTRUCTOR_VM_DEALLOCATE, 150); 151 152/*! 153 * @function dispatch_mach_msg_create 154 * Creates a dispatch mach message object, either with a newly allocated message 155 * buffer of given size, or from an existing message buffer that will be 156 * deallocated with the specified destructor when the object is released. 157 * 158 * If a non-NULL reference to a pointer is provided in 'msg_ptr', it is filled 159 * with the location of the (possibly newly allocated) message buffer. 160 * 161 * It is the responsibility of the application to ensure that it does not modify 162 * the underlying message buffer once the dispatch mach message object is passed 163 * to other dispatch mach API. 164 * 165 * @param msg The message buffer to create the message object from. 166 * If 'destructor' is DISPATCH_MACH_MSG_DESTRUCTOR_DEFAULT, 167 * this argument may be NULL to leave the newly allocated 168 * message buffer zero-initialized. 169 * @param size The size of the message buffer. 170 * Must be >= sizeof(mach_msg_header_t) 171 * @param destructor The destructor to use to deallocate the message buffer 172 * when the object is released. 173 * @param msg_ptr A pointer to a pointer variable to be filled with the 174 * location of the (possibly newly allocated) message 175 * buffer, or NULL. 176 * @result A newly created dispatch mach message object. 177 */ 178__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) 179DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT 180DISPATCH_NOTHROW 181dispatch_mach_msg_t 182dispatch_mach_msg_create(mach_msg_header_t *msg, size_t size, 183 dispatch_mach_msg_destructor_t destructor, mach_msg_header_t **msg_ptr); 184 185/*! 186 * @function dispatch_mach_msg_get_msg 187 * Returns the message buffer underlying a dispatch mach message object. 188 * 189 * @param message The dispatch mach message object to query. 190 * @param size_ptr A pointer to a size_t variable to be filled with the 191 * size of the message buffer, or NULL. 192 * @result Pointer to message buffer underlying the object. 193 */ 194__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) 195DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW 196mach_msg_header_t* 197dispatch_mach_msg_get_msg(dispatch_mach_msg_t message, size_t *size_ptr); 198 199#ifdef __BLOCKS__ 200/*! 201 * @typedef dispatch_mach_handler_t 202 * Prototype of dispatch mach channel handler blocks. 203 * 204 * @param reason Reason the handler was invoked. 205 * @param message Message object that was sent or received. 206 * @param error Mach error code for the send operation. 207 */ 208typedef void (^dispatch_mach_handler_t)(dispatch_mach_reason_t reason, 209 dispatch_mach_msg_t message, mach_error_t error); 210 211/*! 212 * @function dispatch_mach_create 213 * Create a dispatch mach channel to asynchronously receive and send mach 214 * messages. 215 * 216 * The specified handler will be called with the corresponding reason parameter 217 * for each message received and for each message that was successfully sent, 218 * that failed to be sent, or was not sent; as well as when a barrier block 219 * has completed, or when channel connection, reconnection or cancellation has 220 * taken effect. 221 * 222 * Dispatch mach channels are created in a disconnected state, they must be 223 * connected via dispatch_mach_connect() to begin receiving and sending 224 * messages. 225 * 226 * @param label 227 * An optional string label to attach to the channel. The string is not copied, 228 * if it is non-NULL it must point to storage that remains valid for the 229 * lifetime of the channel object. May be NULL. 230 * 231 * @param queue 232 * The target queue of the channel, where the handler and barrier blocks will 233 * be submitted. 234 * 235 * @param handler 236 * The handler block to submit when a message has been sent or received. 237 * 238 * @result 239 * The newly created dispatch mach channel. 240 */ 241__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 242DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT 243DISPATCH_NONNULL3 DISPATCH_NOTHROW 244dispatch_mach_t 245dispatch_mach_create(const char *label, dispatch_queue_t queue, 246 dispatch_mach_handler_t handler); 247#endif 248 249/*! 250 * @typedef dispatch_mach_handler_function_t 251 * Prototype of dispatch mach channel handler functions. 252 * 253 * @param context Application-defined context parameter. 254 * @param reason Reason the handler was invoked. 255 * @param message Message object that was sent or received. 256 * @param error Mach error code for the send operation. 257 */ 258typedef void (*dispatch_mach_handler_function_t)(void *context, 259 dispatch_mach_reason_t reason, dispatch_mach_msg_t message, 260 mach_error_t error); 261 262/*! 263 * @function dispatch_mach_create_f 264 * Create a dispatch mach channel to asynchronously receive and send mach 265 * messages. 266 * 267 * The specified handler will be called with the corresponding reason parameter 268 * for each message received and for each message that was successfully sent, 269 * that failed to be sent, or was not sent; as well as when a barrier block 270 * has completed, or when channel connection, reconnection or cancellation has 271 * taken effect. 272 * 273 * Dispatch mach channels are created in a disconnected state, they must be 274 * connected via dispatch_mach_connect() to begin receiving and sending 275 * messages. 276 * 277 * @param label 278 * An optional string label to attach to the channel. The string is not copied, 279 * if it is non-NULL it must point to storage that remains valid for the 280 * lifetime of the channel object. May be NULL. 281 * 282 * @param queue 283 * The target queue of the channel, where the handler and barrier blocks will 284 * be submitted. 285 * 286 * @param context 287 * The application-defined context to pass to the handler. 288 * 289 * @param handler 290 * The handler function to submit when a message has been sent or received. 291 * 292 * @result 293 * The newly created dispatch mach channel. 294 */ 295__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 296DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT 297DISPATCH_NONNULL4 DISPATCH_NOTHROW 298dispatch_mach_t 299dispatch_mach_create_f(const char *label, dispatch_queue_t queue, void *context, 300 dispatch_mach_handler_function_t handler); 301 302/*! 303 * @function dispatch_mach_connect 304 * Connect a mach channel to the specified receive and send rights. 305 * 306 * This function must only be called once during the lifetime of a channel, it 307 * will initiate message reception and perform any already submitted message 308 * sends or barrier operations. 309 * 310 * @param channel 311 * The mach channel to connect. 312 * 313 * @param receive 314 * The receive right to associate with the channel. May be MACH_PORT_NULL. 315 * 316 * @param send 317 * The send right to associate with the channel. May be MACH_PORT_NULL. 318 * 319 * @param checkin 320 * An optional message object encapsulating the initial check-in message to send 321 * upon channel connection. The check-in message is sent immediately before the 322 * first message submitted via dispatch_mach_send(). The message object will be 323 * retained until the initial send operation is complete (or not peformed due 324 * to channel cancellation or reconnection) and the channel handler has 325 * returned. May be NULL. 326 */ 327__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 328DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW 329void 330dispatch_mach_connect(dispatch_mach_t channel, mach_port_t receive, 331 mach_port_t send, dispatch_mach_msg_t checkin); 332 333/*! 334 * @function dispatch_mach_reconnect 335 * Reconnect a mach channel to the specified send right. 336 * 337 * Disconnects the channel from the current send right, interrupts any pending 338 * message sends (and returns the messages as unsent), and reconnects the 339 * channel to a new send right. 340 * 341 * The application must wait for the channel handler to be invoked with 342 * DISPATCH_MACH_DISCONNECTED before releasing the previous send right. 343 * 344 * @param channel 345 * The mach channel to reconnect. 346 * 347 * @param send 348 * The new send right to associate with the channel. May be MACH_PORT_NULL. 349 * 350 * @param checkin 351 * An optional message object encapsulating the initial check-in message to send 352 * upon channel reconnection. The check-in message is sent immediately before 353 * the first message submitted via dispatch_mach_send() after this function 354 * returns. The message object will be retained until the initial send operation 355 * is complete (or not peformed due to channel cancellation or reconnection) 356 * and the channel handler has returned. May be NULL. 357 */ 358__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 359DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW 360void 361dispatch_mach_reconnect(dispatch_mach_t channel, mach_port_t send, 362 dispatch_mach_msg_t checkin); 363 364/*! 365 * @function dispatch_mach_cancel 366 * Cancel a mach channel, preventing any further messages from being sent or 367 * received. 368 * 369 * The application must wait for the channel handler to be invoked with 370 * DISPATCH_MACH_DISCONNECTED before releasing the underlying send and receive 371 * rights. 372 * 373 * Note: explicit cancellation of mach channels is required, no implicit 374 * cancellation takes place on release of the last application reference 375 * to the channel object. Failure to cancel will cause the channel and 376 * its associated resources to be leaked. 377 * 378 * @param channel 379 * The mach channel to cancel. 380 */ 381__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 382DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 383void 384dispatch_mach_cancel(dispatch_mach_t channel); 385 386/*! 387 * @function dispatch_mach_send 388 * Asynchronously send a message encapsulated in a dispatch mach message object 389 * to the specified mach channel. 390 * 391 * Unless the message is being sent to a send-once right (as determined by the 392 * presence of MACH_MSG_TYPE_MOVE_SEND_ONCE in the message header remote bits), 393 * the message header remote port is set to the channel send right before the 394 * send operation is performed. 395 * 396 * If the message expects a direct reply (as determined by the presence of 397 * MACH_MSG_TYPE_MAKE_SEND_ONCE in the message header local bits) the receive 398 * right specified in the message header local port will be monitored until a 399 * reply message (or a send-once notification) is received, or the channel is 400 * canceled. Hence the application must wait for the channel handler to be 401 * invoked with a DISPATCH_MACH_DISCONNECTED message before releasing that 402 * receive right. 403 * 404 * If the message send operation is attempted but the channel is canceled 405 * before the send operation succesfully completes, the message returned to the 406 * channel handler with DISPATCH_MACH_MESSAGE_NOT_SENT may be the result of a 407 * pseudo-receive operation. If the message expected a direct reply, the 408 * receive right originally specified in the message header local port will 409 * returned in a DISPATCH_MACH_DISCONNECTED message. 410 * 411 * @param channel 412 * The mach channel to which to send the message. 413 * 414 * @param message 415 * The message object encapsulating the message to send. The object will be 416 * retained until the send operation is complete and the channel handler has 417 * returned. The storage underlying the message object may be modified by the 418 * send operation. 419 * 420 * @param options 421 * Additional send options to pass to mach_msg() when performing the send 422 * operation. 423 */ 424__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 425DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL2 DISPATCH_NOTHROW 426void 427dispatch_mach_send(dispatch_mach_t channel, dispatch_mach_msg_t message, 428 mach_msg_option_t options); 429 430#ifdef __BLOCKS__ 431/*! 432 * @function dispatch_mach_send_barrier 433 * Submit a send barrier to the specified mach channel. Messages submitted to 434 * the channel before the barrier will be sent before the barrier block is 435 * executed, and messages submitted to the channel after the barrier will only 436 * be sent once the barrier block has completed and the channel handler 437 * invocation for the barrier has returned. 438 * 439 * @param channel 440 * The mach channel to which to submit the barrier. 441 * 442 * @param barrier 443 * The barrier block to submit to the channel target queue. 444 */ 445__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 446DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 447void 448dispatch_mach_send_barrier(dispatch_mach_t channel, dispatch_block_t barrier); 449#endif 450 451/*! 452 * @function dispatch_mach_send_barrier_f 453 * Submit a send barrier to the specified mach channel. Messages submitted to 454 * the channel before the barrier will be sent before the barrier block is 455 * executed, and messages submitted to the channel after the barrier will only 456 * be sent once the barrier block has completed and the channel handler 457 * invocation for the barrier has returned. 458 * 459 * @param channel 460 * The mach channel to which to submit the barrier. 461 * 462 * @param context 463 * The application-defined context parameter to pass to the function. 464 * 465 * @param barrier 466 * The barrier function to submit to the channel target queue. 467 */ 468__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 469DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW 470void 471dispatch_mach_send_barrier_f(dispatch_mach_t channel, void *context, 472 dispatch_function_t barrier); 473 474#ifdef __BLOCKS__ 475/*! 476 * @function dispatch_mach_receive_barrier 477 * Submit a receive barrier to the specified mach channel. Channel handlers for 478 * messages received by the channel after the receive barrier has been 479 * submitted will only be invoked once the barrier block has completed and the 480 * channel handler invocation for the barrier has returned. 481 * 482 * @param channel 483 * The mach channel to which to submit the receive barrier. 484 * 485 * @param barrier 486 * The barrier block to submit to the channel target queue. 487 */ 488__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 489DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 490void 491dispatch_mach_receive_barrier(dispatch_mach_t channel, 492 dispatch_block_t barrier); 493#endif 494 495/*! 496 * @function dispatch_mach_receive_barrier_f 497 * Submit a receive barrier to the specified mach channel. Channel handlers for 498 * messages received by the channel after the receive barrier has been 499 * submitted will only be invoked once the barrier block has completed and the 500 * channel handler invocation for the barrier has returned. 501 * 502 * @param channel 503 * The mach channel to which to submit the receive barrier. 504 * 505 * @param context 506 * The application-defined context parameter to pass to the function. 507 * 508 * @param barrier 509 * The barrier function to submit to the channel target queue. 510 */ 511__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 512DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW 513void 514dispatch_mach_receive_barrier_f(dispatch_mach_t channel, void *context, 515 dispatch_function_t barrier); 516 517/*! 518 * @function dispatch_mach_get_checkin_port 519 * Returns the port specified in the message header remote port of the check-in 520 * message passed to the most recent invocation of dispatch_mach_connect() or 521 * dispatch_mach_reconnect() for the provided mach channel (irrespective of the 522 * completion of the (re)connect or check-in operations in question). 523 * 524 * Returns MACH_PORT_NULL if dispatch_mach_connect() has not yet been called or 525 * if the most recently specified check-in message was NULL, and MACH_PORT_DEAD 526 * if the channel has been canceled. 527 * 528 * It is the responsibility of the application to ensure that the port 529 * specified in a check-in message remains valid at the time this function is 530 * called. 531 * 532 * @param channel 533 * The mach channel to query. 534 * 535 * @result 536 * The most recently specified check-in port for the channel. 537 */ 538__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_6_0) 539DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 540mach_port_t 541dispatch_mach_get_checkin_port(dispatch_mach_t channel); 542 543#endif // DISPATCH_MACH_SPI 544 545__END_DECLS 546 547#endif 548