2 * Copyright (c) 2012-2013 Apple Inc. All rights reserved.
4 * @APPLE_APACHE_LICENSE_HEADER_START@
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @APPLE_APACHE_LICENSE_HEADER_END@
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.
27 #ifndef __DISPATCH_MACH_PRIVATE__
28 #define __DISPATCH_MACH_PRIVATE__
30 #ifndef __DISPATCH_INDIRECT__
31 #error "Please #include <dispatch/dispatch.h> instead of this file directly."
32 #include <dispatch/base.h> // for HeaderDoc
39 #define DISPATCH_MACH_SPI_VERSION 20161026
41 #include <mach/mach.h>
43 DISPATCH_ASSUME_NONNULL_BEGIN
46 * @functiongroup Dispatch Mach Channel SPI
48 * IMPORTANT: This is Libsystem-internal SPI not intended for general use and
49 * is subject to change at any time without warning.
53 * @typedef dispatch_mach_t
54 * A dispatch mach channel asynchronously recevives and sends mach messages.
56 DISPATCH_DECL(dispatch_mach
);
59 * @typedef dispatch_mach_reason_t
60 * Reasons for a mach channel handler to be invoked, or the result of an
61 * immediate send attempt.
63 * @const DISPATCH_MACH_CONNECTED
64 * The channel has been connected. The first handler invocation on a channel
65 * after calling dispatch_mach_connect() will have this reason.
67 * @const DISPATCH_MACH_MESSAGE_RECEIVED
68 * A message was received, it is passed in the message parameter.
70 * @const DISPATCH_MACH_MESSAGE_SENT
71 * A message was sent, it is passed in the message parameter (so that associated
72 * resources can be disposed of).
74 * @const DISPATCH_MACH_MESSAGE_SEND_FAILED
75 * A message failed to be sent, it is passed in the message parameter (so that
76 * associated resources can be disposed of), along with the error code from
79 * @const DISPATCH_MACH_MESSAGE_NOT_SENT
80 * A message was not sent due to the channel being canceled or reconnected, it
81 * is passed in the message parameter (so that associated resources can be
84 * @const DISPATCH_MACH_BARRIER_COMPLETED
85 * A barrier block has finished executing.
87 * @const DISPATCH_MACH_DISCONNECTED
88 * The channel has been disconnected by a call to dispatch_mach_reconnect() or
89 * dispatch_mach_cancel(), an empty message is passed in the message parameter
90 * (so that associated port rights can be disposed of).
91 * The message header will contain either a remote port with a previously
92 * connected send right, or a local port with a previously connected receive
93 * right (if the channel was canceled), or a local port with a receive right
94 * that was being monitored for a direct reply to a message previously sent to
95 * the channel (if no reply was received).
97 * @const DISPATCH_MACH_CANCELED
98 * The channel has been canceled.
100 * @const DISPATCH_MACH_REPLY_RECEIVED
101 * A synchronous reply to a call to dispatch_mach_send_and_wait_for_reply() has
102 * been received on another thread, an empty message is passed in the message
103 * parameter (so that associated port rights can be disposed of).
104 * The message header will contain a local port with a receive right associated
105 * with the reply to the message that was synchronously sent to the channel.
107 * @const DISPATCH_MACH_NEEDS_DEFERRED_SEND
108 * The message could not be sent synchronously. Only returned from a send with
109 * result operation and never passed to a channel handler. Indicates that the
110 * message passed to the send operation must not be disposed of until it is
111 * returned via the channel handler.
113 * @const DISPATCH_MACH_SIGTERM_RECEIVED
114 * A SIGTERM signal has been received. This notification is delivered at most
115 * once during the lifetime of the channel. This event is sent only for XPC
116 * channels (i.e. channels that were created by calling
117 * dispatch_mach_create_4libxpc()) and only if the
118 * dmxh_enable_sigterm_notification function in the XPC hooks structure is not
119 * set or it returned true when it was called at channel activation time.
121 * @const DISPATCH_MACH_ASYNC_WAITER_DISCONNECTED
122 * The channel has been disconnected by a call to dispatch_mach_reconnect() or
123 * dispatch_mach_cancel(), an empty message is passed in the message parameter
124 * (so that associated port rights can be disposed of). The message header will
125 * contain a local port with the receive right previously allocated to receive
126 * an asynchronous reply to a message previously sent to the channel. Used
127 * only if the channel is disconnected while waiting for a reply to a message
128 * sent with dispatch_mach_send_with_result_and_async_reply_4libxpc().
130 DISPATCH_ENUM(dispatch_mach_reason
, unsigned long,
131 DISPATCH_MACH_CONNECTED
= 1,
132 DISPATCH_MACH_MESSAGE_RECEIVED
,
133 DISPATCH_MACH_MESSAGE_SENT
,
134 DISPATCH_MACH_MESSAGE_SEND_FAILED
,
135 DISPATCH_MACH_MESSAGE_NOT_SENT
,
136 DISPATCH_MACH_BARRIER_COMPLETED
,
137 DISPATCH_MACH_DISCONNECTED
,
138 DISPATCH_MACH_CANCELED
,
139 DISPATCH_MACH_REPLY_RECEIVED
,
140 DISPATCH_MACH_NEEDS_DEFERRED_SEND
,
141 DISPATCH_MACH_SIGTERM_RECEIVED
,
142 DISPATCH_MACH_ASYNC_WAITER_DISCONNECTED
,
143 DISPATCH_MACH_REASON_LAST
, /* unused */
147 * @typedef dispatch_mach_send_flags_t
148 * Flags that can be passed to the *with_flags send functions.
150 DISPATCH_ENUM(dispatch_mach_send_flags
, unsigned long,
151 DISPATCH_MACH_SEND_DEFAULT
= 0,
155 * @typedef dispatch_mach_trailer_t
156 * Trailer type of mach message received by dispatch mach channels
159 typedef mach_msg_context_trailer_t dispatch_mach_trailer_t
;
162 * @constant DISPATCH_MACH_RECEIVE_MAX_INLINE_MESSAGE_SIZE
163 * Maximum size of a message that can be received inline by a dispatch mach
164 * channel, reception of larger messages requires an extra roundtrip through
168 #define DISPATCH_MACH_RECEIVE_MAX_INLINE_MESSAGE_SIZE \
169 (0x4000 - sizeof(dispatch_mach_trailer_t))
172 * @typedef dispatch_mach_msg_t
173 * A dispatch mach message encapsulates messages received or sent with dispatch
176 DISPATCH_DECL(dispatch_mach_msg
);
179 * @typedef dispatch_mach_msg_destructor_t
180 * Dispatch mach message object destructors.
182 * @const DISPATCH_MACH_MSG_DESTRUCTOR_DEFAULT
183 * Message buffer storage is internal to the object, if a buffer is supplied
184 * during object creation, its contents are copied.
186 * @const DISPATCH_MACH_MSG_DESTRUCTOR_FREE
187 * Message buffer will be deallocated with free(3).
189 * @const DISPATCH_MACH_MSG_DESTRUCTOR_FREE
190 * Message buffer will be deallocated with vm_deallocate.
192 DISPATCH_ENUM(dispatch_mach_msg_destructor
, unsigned int,
193 DISPATCH_MACH_MSG_DESTRUCTOR_DEFAULT
= 0,
194 DISPATCH_MACH_MSG_DESTRUCTOR_FREE
,
195 DISPATCH_MACH_MSG_DESTRUCTOR_VM_DEALLOCATE
,
199 * @function dispatch_mach_msg_create
200 * Creates a dispatch mach message object, either with a newly allocated message
201 * buffer of given size, or from an existing message buffer that will be
202 * deallocated with the specified destructor when the object is released.
204 * If a non-NULL reference to a pointer is provided in 'msg_ptr', it is filled
205 * with the location of the (possibly newly allocated) message buffer.
207 * It is the responsibility of the application to ensure that it does not modify
208 * the underlying message buffer once the dispatch mach message object is passed
209 * to other dispatch mach API.
211 * @param msg The message buffer to create the message object from.
212 * If 'destructor' is DISPATCH_MACH_MSG_DESTRUCTOR_DEFAULT,
213 * this argument may be NULL to leave the newly allocated
214 * message buffer zero-initialized.
215 * @param size The size of the message buffer.
216 * Must be >= sizeof(mach_msg_header_t)
217 * @param destructor The destructor to use to deallocate the message buffer
218 * when the object is released.
219 * @param msg_ptr A pointer to a pointer variable to be filled with the
220 * location of the (possibly newly allocated) message
222 * @result A newly created dispatch mach message object.
224 API_AVAILABLE(macos(10.9), ios(7.0))
225 DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
228 dispatch_mach_msg_create(mach_msg_header_t
*_Nullable msg
, size_t size
,
229 dispatch_mach_msg_destructor_t destructor
,
230 mach_msg_header_t
*_Nonnull
*_Nullable msg_ptr
);
233 * @function dispatch_mach_msg_get_msg
234 * Returns the message buffer underlying a dispatch mach message object.
236 * @param message The dispatch mach message object to query.
237 * @param size_ptr A pointer to a size_t variable to be filled with the
238 * size of the message buffer, or NULL.
239 * @result Pointer to message buffer underlying the object.
241 API_AVAILABLE(macos(10.9), ios(7.0))
242 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
244 dispatch_mach_msg_get_msg(dispatch_mach_msg_t message
,
245 size_t *_Nullable size_ptr
);
249 * @typedef dispatch_mach_handler_t
250 * Prototype of dispatch mach channel handler blocks.
252 * @param reason Reason the handler was invoked.
253 * @param message Message object that was sent or received.
254 * @param error Mach error code for the send operation.
256 typedef void (^dispatch_mach_handler_t
)(dispatch_mach_reason_t reason
,
257 dispatch_mach_msg_t _Nullable message
, mach_error_t error
);
260 * @function dispatch_mach_create
261 * Create a dispatch mach channel to asynchronously receive and send mach
264 * The specified handler will be called with the corresponding reason parameter
265 * for each message received and for each message that was successfully sent,
266 * that failed to be sent, or was not sent; as well as when a barrier block
267 * has completed, or when channel connection, reconnection or cancellation has
270 * Dispatch mach channels are created in a disconnected state, they must be
271 * connected via dispatch_mach_connect() to begin receiving and sending
275 * An optional string label to attach to the channel. The string is not copied,
276 * if it is non-NULL it must point to storage that remains valid for the
277 * lifetime of the channel object. May be NULL.
280 * The target queue of the channel, where the handler and barrier blocks will
284 * The handler block to submit when a message has been sent or received.
287 * The newly created dispatch mach channel.
289 API_AVAILABLE(macos(10.9), ios(6.0))
290 DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
291 DISPATCH_NONNULL3 DISPATCH_NOTHROW
293 dispatch_mach_create(const char *_Nullable label
,
294 dispatch_queue_t _Nullable queue
, dispatch_mach_handler_t handler
);
298 * @typedef dispatch_mach_handler_function_t
299 * Prototype of dispatch mach channel handler functions.
301 * @param context Application-defined context parameter.
302 * @param reason Reason the handler was invoked.
303 * @param message Message object that was sent or received.
304 * @param error Mach error code for the send operation.
306 typedef void (*dispatch_mach_handler_function_t
)(void *_Nullable context
,
307 dispatch_mach_reason_t reason
, dispatch_mach_msg_t _Nullable message
,
311 * @function dispatch_mach_create_f
312 * Create a dispatch mach channel to asynchronously receive and send mach
315 * The specified handler will be called with the corresponding reason parameter
316 * for each message received and for each message that was successfully sent,
317 * that failed to be sent, or was not sent; as well as when a barrier block
318 * has completed, or when channel connection, reconnection or cancellation has
321 * Dispatch mach channels are created in a disconnected state, they must be
322 * connected via dispatch_mach_connect() to begin receiving and sending
326 * An optional string label to attach to the channel. The string is not copied,
327 * if it is non-NULL it must point to storage that remains valid for the
328 * lifetime of the channel object. May be NULL.
331 * The target queue of the channel, where the handler and barrier blocks will
335 * The application-defined context to pass to the handler.
338 * The handler function to submit when a message has been sent or received.
341 * The newly created dispatch mach channel.
343 API_AVAILABLE(macos(10.9), ios(6.0))
344 DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
345 DISPATCH_NONNULL4 DISPATCH_NOTHROW
347 dispatch_mach_create_f(const char *_Nullable label
,
348 dispatch_queue_t _Nullable queue
, void *_Nullable context
,
349 dispatch_mach_handler_function_t handler
);
352 * @function dispatch_mach_connect
353 * Connect a mach channel to the specified receive and send rights.
355 * This function must only be called once during the lifetime of a channel, it
356 * will initiate message reception and perform any already submitted message
357 * sends or barrier operations.
360 * The mach channel to connect.
363 * The receive right to associate with the channel. May be MACH_PORT_NULL.
366 * The send right to associate with the channel. May be MACH_PORT_NULL.
369 * An optional message object encapsulating the initial check-in message to send
370 * upon channel connection. The check-in message is sent immediately before the
371 * first message submitted via dispatch_mach_send(). The message object will be
372 * retained until the initial send operation is complete (or not peformed due
373 * to channel cancellation or reconnection) and the channel handler has
374 * returned. May be NULL.
376 API_AVAILABLE(macos(10.9), ios(6.0))
377 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
379 dispatch_mach_connect(dispatch_mach_t channel
, mach_port_t receive
,
380 mach_port_t send
, dispatch_mach_msg_t _Nullable checkin
);
383 * @function dispatch_mach_reconnect
384 * Reconnect a mach channel to the specified send right.
386 * Disconnects the channel from the current send right, interrupts any pending
387 * message sends (and returns the messages as unsent), and reconnects the
388 * channel to a new send right.
390 * The application must wait for the channel handler to be invoked with
391 * DISPATCH_MACH_DISCONNECTED before releasing the previous send right.
394 * The mach channel to reconnect.
397 * The new send right to associate with the channel. May be MACH_PORT_NULL.
400 * An optional message object encapsulating the initial check-in message to send
401 * upon channel reconnection. The check-in message is sent immediately before
402 * the first message submitted via dispatch_mach_send() after this function
403 * returns. The message object will be retained until the initial send operation
404 * is complete (or not peformed due to channel cancellation or reconnection)
405 * and the channel handler has returned. May be NULL.
407 API_AVAILABLE(macos(10.9), ios(6.0))
408 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
410 dispatch_mach_reconnect(dispatch_mach_t channel
, mach_port_t send
,
411 dispatch_mach_msg_t _Nullable checkin
);
414 * @function dispatch_mach_cancel
415 * Cancel a mach channel, preventing any further messages from being sent or
418 * The application must wait for the channel handler to be invoked with
419 * DISPATCH_MACH_DISCONNECTED before releasing the underlying send and receive
422 * Note: explicit cancellation of mach channels is required, no implicit
423 * cancellation takes place on release of the last application reference
424 * to the channel object. Failure to cancel will cause the channel and
425 * its associated resources to be leaked.
428 * The mach channel to cancel.
430 API_AVAILABLE(macos(10.9), ios(6.0))
431 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
433 dispatch_mach_cancel(dispatch_mach_t channel
);
436 * @function dispatch_mach_send
437 * Asynchronously send a message encapsulated in a dispatch mach message object
438 * to the specified mach channel.
440 * Unless the message is being sent to a send-once right (as determined by the
441 * presence of MACH_MSG_TYPE_MOVE_SEND_ONCE in the message header remote bits),
442 * the message header remote port is set to the channel send right before the
443 * send operation is performed.
445 * If the message expects a direct reply (as determined by the presence of
446 * MACH_MSG_TYPE_MAKE_SEND_ONCE in the message header local bits) the receive
447 * right specified in the message header local port will be monitored until a
448 * reply message (or a send-once notification) is received, or the channel is
449 * canceled. Hence the application must wait for the channel handler to be
450 * invoked with a DISPATCH_MACH_DISCONNECTED message before releasing that
453 * If the message send operation is attempted but the channel is canceled
454 * before the send operation succesfully completes, the message returned to the
455 * channel handler with DISPATCH_MACH_MESSAGE_NOT_SENT may be the result of a
456 * pseudo-receive operation. If the message expected a direct reply, the
457 * receive right originally specified in the message header local port will
458 * returned in a DISPATCH_MACH_DISCONNECTED message.
461 * The mach channel to which to send the message.
464 * The message object encapsulating the message to send. The object will be
465 * retained until the send operation is complete and the channel handler has
466 * returned. The storage underlying the message object may be modified by the
470 * Additional send options to pass to mach_msg() when performing the send
473 API_AVAILABLE(macos(10.9), ios(6.0))
474 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL2 DISPATCH_NOTHROW
476 dispatch_mach_send(dispatch_mach_t channel
, dispatch_mach_msg_t message
,
477 mach_msg_option_t options
);
480 * @function dispatch_mach_send_with_result
481 * Asynchronously send a message encapsulated in a dispatch mach message object
482 * to the specified mach channel. If an immediate send can be performed, return
483 * its result via out parameters.
485 * Unless the message is being sent to a send-once right (as determined by the
486 * presence of MACH_MSG_TYPE_MOVE_SEND_ONCE in the message header remote bits),
487 * the message header remote port is set to the channel send right before the
488 * send operation is performed.
490 * If the message expects a direct reply (as determined by the presence of
491 * MACH_MSG_TYPE_MAKE_SEND_ONCE in the message header local bits) the receive
492 * right specified in the message header local port will be monitored until a
493 * reply message (or a send-once notification) is received, or the channel is
494 * canceled. Hence the application must wait for the channel handler to be
495 * invoked with a DISPATCH_MACH_DISCONNECTED message before releasing that
498 * If the message send operation is attempted but the channel is canceled
499 * before the send operation succesfully completes, the message returned to the
500 * channel handler with DISPATCH_MACH_MESSAGE_NOT_SENT may be the result of a
501 * pseudo-receive operation. If the message expected a direct reply, the
502 * receive right originally specified in the message header local port will
503 * returned in a DISPATCH_MACH_DISCONNECTED message.
505 * If an immediate send could be performed, returns the resulting reason
506 * (e.g. DISPATCH_MACH_MESSAGE_SENT) and possible error to the caller in the
507 * send_result and send_error out parameters (instead of via the channel
508 * handler), in which case the passed-in message and associated resources
509 * can be disposed of synchronously.
511 * If a deferred send is required, returns DISPATCH_MACH_NEEDS_DEFERRED_SEND
512 * in the send_result out parameter to indicate that the passed-in message has
513 * been retained and associated resources must not be disposed of until the
514 * message is returned asynchronusly via the channel handler.
517 * The mach channel to which to send the message.
520 * The message object encapsulating the message to send. Unless an immediate
521 * send could be performed, the object will be retained until the asynchronous
522 * send operation is complete and the channel handler has returned. The storage
523 * underlying the message object may be modified by the send operation.
526 * Additional send options to pass to mach_msg() when performing the send
530 * Flags to configure the send operation. Must be 0 for now.
533 * Out parameter to return the result of the immediate send attempt.
534 * If a deferred send is required, returns DISPATCH_MACH_NEEDS_DEFERRED_SEND.
538 * Out parameter to return the error from the immediate send attempt.
539 * If a deferred send is required, returns 0. Must not be NULL.
541 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
542 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL2 DISPATCH_NONNULL5
543 DISPATCH_NONNULL6 DISPATCH_NOTHROW
545 dispatch_mach_send_with_result(dispatch_mach_t channel
,
546 dispatch_mach_msg_t message
, mach_msg_option_t options
,
547 dispatch_mach_send_flags_t send_flags
,
548 dispatch_mach_reason_t
*send_result
, mach_error_t
*send_error
);
551 * @function dispatch_mach_send_and_wait_for_reply
552 * Synchronously send a message encapsulated in a dispatch mach message object
553 * to the specified mach channel and wait for a reply.
555 * Unless the message is being sent to a send-once right (as determined by the
556 * presence of MACH_MSG_TYPE_MOVE_SEND_ONCE in the message header remote bits),
557 * the message header remote port is set to the channel send right before the
558 * send operation is performed.
560 * The message is required to expect a direct reply (as determined by the
561 * presence of MACH_MSG_TYPE_MAKE_SEND_ONCE in the message header local bits)
562 * and this function will not complete until the receive right specified in the
563 * message header local port receives a reply message (or a send-once
564 * notification) which will be returned, or until that receive right is
565 * destroyed in response to the channel being canceled, in which case NULL will
567 * In all these cases the application must wait for the channel handler to
568 * be invoked with a DISPATCH_MACH_REPLY_RECEIVED or DISPATCH_MACH_DISCONNECTED
569 * message before releasing that receive right.
571 * Alternatively, the application may specify MACH_PORT_NULL in the header local
572 * port to indicate that the channel should create and manage the reply receive
573 * right internally, including destroying it upon channel cancellation.
574 * This is a more efficient mode of operation as no asynchronous operations are
575 * required to return the receive right (i.e. the channel handler will not be
576 * called as described above).
578 * If the message send operation is attempted but the channel is canceled
579 * before the send operation succesfully completes, the message returned to the
580 * channel handler with DISPATCH_MACH_MESSAGE_NOT_SENT may be the result of a
581 * pseudo-receive operation. The receive right originally specified in the
582 * message header local port will returned in a DISPATCH_MACH_DISCONNECTED
583 * message (unless it was MACH_PORT_NULL).
586 * The mach channel to which to send the message.
589 * The message object encapsulating the message to send. The object will be
590 * retained until the send operation is complete and the channel handler has
591 * returned. The storage underlying the message object may be modified by the
595 * Additional send options to pass to mach_msg() when performing the send
599 * The received reply message object, or NULL if the channel was canceled.
601 API_AVAILABLE(macos(10.11), ios(9.0))
602 DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
603 DISPATCH_NONNULL1 DISPATCH_NONNULL2 DISPATCH_NOTHROW
604 dispatch_mach_msg_t _Nullable
605 dispatch_mach_send_and_wait_for_reply(dispatch_mach_t channel
,
606 dispatch_mach_msg_t message
, mach_msg_option_t options
);
609 * @function dispatch_mach_send_with_result_and_wait_for_reply
610 * Synchronously send a message encapsulated in a dispatch mach message object
611 * to the specified mach channel and wait for a reply. If an immediate send can
612 * be performed, return its result via out parameters.
614 * Unless the message is being sent to a send-once right (as determined by the
615 * presence of MACH_MSG_TYPE_MOVE_SEND_ONCE in the message header remote bits),
616 * the message header remote port is set to the channel send right before the
617 * send operation is performed.
619 * The message is required to expect a direct reply (as determined by the
620 * presence of MACH_MSG_TYPE_MAKE_SEND_ONCE in the message header local bits)
621 * and this function will not complete until the receive right specified in the
622 * message header local port receives a reply message (or a send-once
623 * notification) which will be returned, or until that receive right is
624 * destroyed in response to the channel being canceled, in which case NULL will
626 * In all these cases the application must wait for the channel handler to
627 * be invoked with a DISPATCH_MACH_REPLY_RECEIVED or DISPATCH_MACH_DISCONNECTED
628 * message before releasing that receive right.
630 * Alternatively, the application may specify MACH_PORT_NULL in the header local
631 * port to indicate that the channel should create and manage the reply receive
632 * right internally, including destroying it upon channel cancellation.
633 * This is a more efficient mode of operation as no asynchronous operations are
634 * required to return the receive right (i.e. the channel handler will not be
635 * called as described above).
637 * If the message send operation is attempted but the channel is canceled
638 * before the send operation succesfully completes, the message returned to the
639 * channel handler with DISPATCH_MACH_MESSAGE_NOT_SENT may be the result of a
640 * pseudo-receive operation. The receive right originally specified in the
641 * message header local port will returned in a DISPATCH_MACH_DISCONNECTED
642 * message (unless it was MACH_PORT_NULL).
644 * If an immediate send could be performed, returns the resulting reason
645 * (e.g. DISPATCH_MACH_MESSAGE_SENT) and possible error to the caller in the
646 * send_result and send_error out parameters (instead of via the channel
647 * handler), in which case the passed-in message and associated resources
648 * can be disposed of synchronously.
650 * If a deferred send is required, returns DISPATCH_MACH_NEEDS_DEFERRED_SEND
651 * in the send_result out parameter to indicate that the passed-in message has
652 * been retained and associated resources must not be disposed of until the
653 * message is returned asynchronusly via the channel handler.
656 * The mach channel to which to send the message.
659 * The message object encapsulating the message to send. Unless an immediate
660 * send could be performed, the object will be retained until the asynchronous
661 * send operation is complete and the channel handler has returned. The storage
662 * underlying the message object may be modified by the send operation.
665 * Additional send options to pass to mach_msg() when performing the send
669 * Flags to configure the send operation. Must be 0 for now.
672 * Out parameter to return the result of the immediate send attempt.
673 * If a deferred send is required, returns DISPATCH_MACH_NEEDS_DEFERRED_SEND.
677 * Out parameter to return the error from the immediate send attempt.
678 * If a deferred send is required, returns 0. Must not be NULL.
681 * The received reply message object, or NULL if the channel was canceled.
683 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
684 DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
685 DISPATCH_NONNULL1 DISPATCH_NONNULL2 DISPATCH_NONNULL5 DISPATCH_NONNULL6
687 dispatch_mach_msg_t _Nullable
688 dispatch_mach_send_with_result_and_wait_for_reply(dispatch_mach_t channel
,
689 dispatch_mach_msg_t message
, mach_msg_option_t options
,
690 dispatch_mach_send_flags_t send_flags
,
691 dispatch_mach_reason_t
*send_result
, mach_error_t
*send_error
);
695 * @function dispatch_mach_send_barrier
696 * Submit a send barrier to the specified mach channel. Messages submitted to
697 * the channel before the barrier will be sent before the barrier block is
698 * executed, and messages submitted to the channel after the barrier will only
699 * be sent once the barrier block has completed and the channel handler
700 * invocation for the barrier has returned.
703 * The mach channel to which to submit the barrier.
706 * The barrier block to submit to the channel target queue.
708 API_AVAILABLE(macos(10.9), ios(6.0))
709 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
711 dispatch_mach_send_barrier(dispatch_mach_t channel
, dispatch_block_t barrier
);
715 * @function dispatch_mach_send_barrier_f
716 * Submit a send barrier to the specified mach channel. Messages submitted to
717 * the channel before the barrier will be sent before the barrier block is
718 * executed, and messages submitted to the channel after the barrier will only
719 * be sent once the barrier block has completed and the channel handler
720 * invocation for the barrier has returned.
723 * The mach channel to which to submit the barrier.
726 * The application-defined context parameter to pass to the function.
729 * The barrier function to submit to the channel target queue.
731 API_AVAILABLE(macos(10.9), ios(6.0))
732 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
734 dispatch_mach_send_barrier_f(dispatch_mach_t channel
, void *_Nullable context
,
735 dispatch_function_t barrier
);
739 * @function dispatch_mach_receive_barrier
740 * Submit a receive barrier to the specified mach channel. Channel handlers for
741 * messages received by the channel after the receive barrier has been
742 * submitted will only be invoked once the barrier block has completed and the
743 * channel handler invocation for the barrier has returned.
746 * The mach channel to which to submit the receive barrier.
749 * The barrier block to submit to the channel target queue.
751 API_AVAILABLE(macos(10.9), ios(6.0))
752 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
754 dispatch_mach_receive_barrier(dispatch_mach_t channel
,
755 dispatch_block_t barrier
);
759 * @function dispatch_mach_receive_barrier_f
760 * Submit a receive barrier to the specified mach channel. Channel handlers for
761 * messages received by the channel after the receive barrier has been
762 * submitted will only be invoked once the barrier block has completed and the
763 * channel handler invocation for the barrier has returned.
766 * The mach channel to which to submit the receive barrier.
769 * The application-defined context parameter to pass to the function.
772 * The barrier function to submit to the channel target queue.
774 API_AVAILABLE(macos(10.9), ios(6.0))
775 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
777 dispatch_mach_receive_barrier_f(dispatch_mach_t channel
, void *_Nullable context
,
778 dispatch_function_t barrier
);
781 * @function dispatch_mach_get_checkin_port
782 * Returns the port specified in the message header remote port of the check-in
783 * message passed to the most recent invocation of dispatch_mach_connect() or
784 * dispatch_mach_reconnect() for the provided mach channel (irrespective of the
785 * completion of the (re)connect or check-in operations in question).
787 * Returns MACH_PORT_NULL if dispatch_mach_connect() has not yet been called or
788 * if the most recently specified check-in message was NULL, and MACH_PORT_DEAD
789 * if the channel has been canceled.
791 * It is the responsibility of the application to ensure that the port
792 * specified in a check-in message remains valid at the time this function is
796 * The mach channel to query.
799 * The most recently specified check-in port for the channel.
801 API_AVAILABLE(macos(10.9), ios(6.0))
802 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
804 dispatch_mach_get_checkin_port(dispatch_mach_t channel
);
808 * Type for the callback for receipt of asynchronous replies to
809 * dispatch_mach_send_with_result_and_async_reply_4libxpc().
811 typedef void (*_Nonnull dispatch_mach_async_reply_callback_t
)(void *context
,
812 dispatch_mach_reason_t reason
, dispatch_mach_msg_t message
);
814 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
815 typedef const struct dispatch_mach_xpc_hooks_s
{
816 #define DISPATCH_MACH_XPC_HOOKS_VERSION 3
817 unsigned long version
;
819 /* Fields available in version 1. */
822 * Called to handle a Mach message event inline if possible. Returns true
823 * if the event was handled, false if the event should be delivered to the
824 * channel event handler. The implementation should not make any assumptions
825 * about the thread in which the function is called and cannot assume that
826 * invocations of this function are serialized relative to each other or
827 * relative to the channel's event handler function. In addition, the
828 * handler must not throw an exception or call out to any code that might
829 * throw an exception.
831 bool (* _Nonnull dmxh_direct_message_handler
)(void *_Nullable context
,
832 dispatch_mach_reason_t reason
, dispatch_mach_msg_t message
,
835 /* Fields available in version 2. */
838 * Gets the queue to which a reply to a message sent using
839 * dispatch_mach_send_with_result_and_async_reply_4libxpc() should be
840 * delivered. The msg_context argument is the value of the do_ctxt field
841 * of the outgoing message, as returned by dispatch_get_context(). If this
842 * function returns NULL, the reply will be delivered to the channel queue.
843 * This function should not make any assumptions about the thread on which
844 * it is called and, since it may be called more than once per message, it
845 * should execute as quickly as possible and not attempt to synchronize with
848 dispatch_queue_t
_Nullable (*_Nonnull dmxh_msg_context_reply_queue
)(
849 void *_Nonnull msg_context
);
852 * Called when a reply to a message sent by
853 * dispatch_mach_send_with_result_and_async_reply_4libxpc() is received. The
854 * message argument points to the reply message and the context argument is
855 * the context value passed to dispatch_mach_create_4libxpc() when creating
856 * the Mach channel. The handler is called on the queue that is returned by
857 * dmxh_msg_context_reply_queue() when the reply is received or if the
858 * channel is disconnected. The reason argument is
859 * DISPATCH_MACH_MESSAGE_RECEIVED if a reply has been received or
860 * DISPATCH_MACH_ASYNC_WAITER_DISCONNECTED if the channel has been
861 * disconnected. Refer to the documentation for
862 * dispatch_mach_send_with_result_and_async_reply_4libxpc() for more
865 dispatch_mach_async_reply_callback_t dmxh_async_reply_handler
;
867 /* Fields available in version 3. */
869 * Called once when the Mach channel has been activated. If this function
870 * returns true, a DISPATCH_MACH_SIGTERM_RECEIVED notification will be
871 * delivered to the channel's event handler when a SIGTERM is received.
873 bool (* _Nullable dmxh_enable_sigterm_notification
)(
874 void *_Nullable context
);
875 } *dispatch_mach_xpc_hooks_t
;
877 #define DISPATCH_MACH_XPC_SUPPORTS_ASYNC_REPLIES(hooks) ((hooks)->version >= 2)
880 * @function dispatch_mach_hooks_install_4libxpc
883 * installs XPC callbacks for dispatch Mach channels.
886 * In order to improve the performance of the XPC/dispatch interface, it is
887 * sometimes useful for dispatch to be able to call directly into XPC. The
888 * channel hooks structure should be initialized with pointers to XPC callback
889 * functions, or NULL for callbacks that XPC does not support. The version
890 * number in the structure must be set to reflect the fields that have been
891 * initialized. This function may be called only once.
894 * A pointer to the channel hooks structure. This must remain valid once set.
896 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
897 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
899 dispatch_mach_hooks_install_4libxpc(dispatch_mach_xpc_hooks_t hooks
);
902 * @function dispatch_mach_create_4libxpc
903 * Create a dispatch mach channel to asynchronously receive and send mach
904 * messages, specifically for libxpc.
906 * The specified handler will be called with the corresponding reason parameter
907 * for each message received and for each message that was successfully sent,
908 * that failed to be sent, or was not sent; as well as when a barrier block
909 * has completed, or when channel connection, reconnection or cancellation has
910 * taken effect. However, the handler will not be called for messages that
911 * were passed to the XPC hooks dmxh_direct_message_handler function if that
912 * function returned true.
914 * Dispatch mach channels are created in a disconnected state, they must be
915 * connected via dispatch_mach_connect() to begin receiving and sending
919 * An optional string label to attach to the channel. The string is not copied,
920 * if it is non-NULL it must point to storage that remains valid for the
921 * lifetime of the channel object. May be NULL.
924 * The target queue of the channel, where the handler and barrier blocks will
928 * The application-defined context to pass to the handler.
931 * The handler function to submit when a message has been sent or received.
934 * The newly created dispatch mach channel.
936 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
937 DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
938 DISPATCH_NONNULL4 DISPATCH_NOTHROW
940 dispatch_mach_create_4libxpc(const char *_Nullable label
,
941 dispatch_queue_t _Nullable queue
, void *_Nullable context
,
942 dispatch_mach_handler_function_t handler
);
945 * @function dispatch_mach_send_with_result_and_async_reply_4libxpc
946 * SPI for XPC that asynchronously sends a message encapsulated in a dispatch
947 * mach message object to the specified mach channel. If an immediate send can
948 * be performed, returns its result via out parameters.
950 * The reply message is processed on the queue returned by the
951 * dmxh_msg_context_reply_queue function in the dispatch_mach_xpc_hooks_s
952 * structure, which is called with a single argument whose value is the
953 * do_ctxt field of the message argument to this function. The reply message is
954 * delivered to the dmxh_async_reply_handler hook function instead of being
955 * passed to the channel event handler.
957 * If the dmxh_msg_context_reply_queue function is not implemented or returns
958 * NULL, the reply message is delivered to the channel event handler on the
961 * Unless the message is being sent to a send-once right (as determined by the
962 * presence of MACH_MSG_TYPE_MOVE_SEND_ONCE in the message header remote bits),
963 * the message header remote port is set to the channel send right before the
964 * send operation is performed.
966 * The message is required to expect a direct reply (as determined by the
967 * presence of MACH_MSG_TYPE_MAKE_SEND_ONCE in the message header local bits).
968 * The receive right specified in the message header local port will be
969 * monitored until a reply message (or a send-once notification) is received, or
970 * the channel is canceled. Hence the application must wait for the reply
971 * to be received or for a DISPATCH_MACH_ASYNC_WAITER_DISCONNECTED message
972 * before releasing that receive right.
974 * If the message send operation is attempted but the channel is canceled
975 * before the send operation succesfully completes, the message returned to the
976 * channel handler with DISPATCH_MACH_MESSAGE_NOT_SENT may be the result of a
977 * pseudo-receive operation and the receive right originally specified in the
978 * message header local port will be returned in a
979 * DISPATCH_MACH_ASYNC_WAITER_DISCONNECTED message.
981 * If an immediate send could be performed, returns the resulting reason
982 * (e.g. DISPATCH_MACH_MESSAGE_SENT) and possible error to the caller in the
983 * send_result and send_error out parameters (instead of via the channel
984 * handler), in which case the passed-in message and associated resources
985 * can be disposed of synchronously.
987 * If a deferred send is required, returns DISPATCH_MACH_NEEDS_DEFERRED_SEND
988 * in the send_result out parameter to indicate that the passed-in message has
989 * been retained and associated resources must not be disposed of until the
990 * message is returned asynchronusly via the channel handler.
993 * The mach channel to which to send the message.
996 * The message object encapsulating the message to send. Unless an immediate
997 * send could be performed, the object will be retained until the asynchronous
998 * send operation is complete and the channel handler has returned. The storage
999 * underlying the message object may be modified by the send operation.
1002 * Additional send options to pass to mach_msg() when performing the send
1006 * Flags to configure the send operation. Must be 0 for now.
1008 * @param send_result
1009 * Out parameter to return the result of the immediate send attempt.
1010 * If a deferred send is required, returns DISPATCH_MACH_NEEDS_DEFERRED_SEND.
1014 * Out parameter to return the error from the immediate send attempt.
1015 * If a deferred send is required, returns 0. Must not be NULL.
1017 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
1018 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL2 DISPATCH_NONNULL5
1019 DISPATCH_NONNULL6 DISPATCH_NOTHROW
1021 dispatch_mach_send_with_result_and_async_reply_4libxpc(dispatch_mach_t channel
,
1022 dispatch_mach_msg_t message
, mach_msg_option_t options
,
1023 dispatch_mach_send_flags_t send_flags
,
1024 dispatch_mach_reason_t
*send_result
, mach_error_t
*send_error
);
1026 DISPATCH_ASSUME_NONNULL_END
1028 #endif // DISPATCH_MACH_SPI