]> git.saurik.com Git - apple/libdispatch.git/blob - private/mach_private.h
libdispatch-913.30.4.tar.gz
[apple/libdispatch.git] / private / mach_private.h
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 #define DISPATCH_MACH_SPI_VERSION 20161026
40
41 #include <mach/mach.h>
42
43 DISPATCH_ASSUME_NONNULL_BEGIN
44
45 /*!
46 * @functiongroup Dispatch Mach Channel SPI
47 *
48 * IMPORTANT: This is Libsystem-internal SPI not intended for general use and
49 * is subject to change at any time without warning.
50 */
51
52 /*!
53 * @typedef dispatch_mach_t
54 * A dispatch mach channel asynchronously recevives and sends mach messages.
55 */
56 DISPATCH_DECL(dispatch_mach);
57
58 /*!
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.
62 *
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.
66 *
67 * @const DISPATCH_MACH_MESSAGE_RECEIVED
68 * A message was received, it is passed in the message parameter.
69 *
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).
73 *
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
77 * mach_msg().
78 *
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
82 * disposed of).
83 *
84 * @const DISPATCH_MACH_BARRIER_COMPLETED
85 * A barrier block has finished executing.
86 *
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).
96 *
97 * @const DISPATCH_MACH_CANCELED
98 * The channel has been canceled.
99 *
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.
106 *
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.
112 *
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.
120 *
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().
129 */
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 */
144 );
145
146 /*!
147 * @typedef dispatch_mach_send_flags_t
148 * Flags that can be passed to the *with_flags send functions.
149 */
150 DISPATCH_ENUM(dispatch_mach_send_flags, unsigned long,
151 DISPATCH_MACH_SEND_DEFAULT = 0,
152 );
153
154 /*!
155 * @typedef dispatch_mach_trailer_t
156 * Trailer type of mach message received by dispatch mach channels
157 */
158
159 typedef mach_msg_context_trailer_t dispatch_mach_trailer_t;
160
161 /*!
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
165 * the kernel.
166 */
167
168 #define DISPATCH_MACH_RECEIVE_MAX_INLINE_MESSAGE_SIZE \
169 (0x4000 - sizeof(dispatch_mach_trailer_t))
170
171 /*!
172 * @typedef dispatch_mach_msg_t
173 * A dispatch mach message encapsulates messages received or sent with dispatch
174 * mach channels.
175 */
176 DISPATCH_DECL(dispatch_mach_msg);
177
178 /*!
179 * @typedef dispatch_mach_msg_destructor_t
180 * Dispatch mach message object destructors.
181 *
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.
185 *
186 * @const DISPATCH_MACH_MSG_DESTRUCTOR_FREE
187 * Message buffer will be deallocated with free(3).
188 *
189 * @const DISPATCH_MACH_MSG_DESTRUCTOR_FREE
190 * Message buffer will be deallocated with vm_deallocate.
191 */
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,
196 );
197
198 /*!
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.
203 *
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.
206 *
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.
210 *
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
221 * buffer, or NULL.
222 * @result A newly created dispatch mach message object.
223 */
224 API_AVAILABLE(macos(10.9), ios(7.0))
225 DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
226 DISPATCH_NOTHROW
227 dispatch_mach_msg_t
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);
231
232 /*!
233 * @function dispatch_mach_msg_get_msg
234 * Returns the message buffer underlying a dispatch mach message object.
235 *
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.
240 */
241 API_AVAILABLE(macos(10.9), ios(7.0))
242 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
243 mach_msg_header_t*
244 dispatch_mach_msg_get_msg(dispatch_mach_msg_t message,
245 size_t *_Nullable size_ptr);
246
247 #ifdef __BLOCKS__
248 /*!
249 * @typedef dispatch_mach_handler_t
250 * Prototype of dispatch mach channel handler blocks.
251 *
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.
255 */
256 typedef void (^dispatch_mach_handler_t)(dispatch_mach_reason_t reason,
257 dispatch_mach_msg_t _Nullable message, mach_error_t error);
258
259 /*!
260 * @function dispatch_mach_create
261 * Create a dispatch mach channel to asynchronously receive and send mach
262 * messages.
263 *
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
268 * taken effect.
269 *
270 * Dispatch mach channels are created in a disconnected state, they must be
271 * connected via dispatch_mach_connect() to begin receiving and sending
272 * messages.
273 *
274 * @param label
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.
278 *
279 * @param queue
280 * The target queue of the channel, where the handler and barrier blocks will
281 * be submitted.
282 *
283 * @param handler
284 * The handler block to submit when a message has been sent or received.
285 *
286 * @result
287 * The newly created dispatch mach channel.
288 */
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
292 dispatch_mach_t
293 dispatch_mach_create(const char *_Nullable label,
294 dispatch_queue_t _Nullable queue, dispatch_mach_handler_t handler);
295 #endif
296
297 /*!
298 * @typedef dispatch_mach_handler_function_t
299 * Prototype of dispatch mach channel handler functions.
300 *
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.
305 */
306 typedef void (*dispatch_mach_handler_function_t)(void *_Nullable context,
307 dispatch_mach_reason_t reason, dispatch_mach_msg_t _Nullable message,
308 mach_error_t error);
309
310 /*!
311 * @function dispatch_mach_create_f
312 * Create a dispatch mach channel to asynchronously receive and send mach
313 * messages.
314 *
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
319 * taken effect.
320 *
321 * Dispatch mach channels are created in a disconnected state, they must be
322 * connected via dispatch_mach_connect() to begin receiving and sending
323 * messages.
324 *
325 * @param label
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.
329 *
330 * @param queue
331 * The target queue of the channel, where the handler and barrier blocks will
332 * be submitted.
333 *
334 * @param context
335 * The application-defined context to pass to the handler.
336 *
337 * @param handler
338 * The handler function to submit when a message has been sent or received.
339 *
340 * @result
341 * The newly created dispatch mach channel.
342 */
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
346 dispatch_mach_t
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);
350
351 /*!
352 * @function dispatch_mach_connect
353 * Connect a mach channel to the specified receive and send rights.
354 *
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.
358 *
359 * @param channel
360 * The mach channel to connect.
361 *
362 * @param receive
363 * The receive right to associate with the channel. May be MACH_PORT_NULL.
364 *
365 * @param send
366 * The send right to associate with the channel. May be MACH_PORT_NULL.
367 *
368 * @param checkin
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.
375 */
376 API_AVAILABLE(macos(10.9), ios(6.0))
377 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
378 void
379 dispatch_mach_connect(dispatch_mach_t channel, mach_port_t receive,
380 mach_port_t send, dispatch_mach_msg_t _Nullable checkin);
381
382 /*!
383 * @function dispatch_mach_reconnect
384 * Reconnect a mach channel to the specified send right.
385 *
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.
389 *
390 * The application must wait for the channel handler to be invoked with
391 * DISPATCH_MACH_DISCONNECTED before releasing the previous send right.
392 *
393 * @param channel
394 * The mach channel to reconnect.
395 *
396 * @param send
397 * The new send right to associate with the channel. May be MACH_PORT_NULL.
398 *
399 * @param checkin
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.
406 */
407 API_AVAILABLE(macos(10.9), ios(6.0))
408 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
409 void
410 dispatch_mach_reconnect(dispatch_mach_t channel, mach_port_t send,
411 dispatch_mach_msg_t _Nullable checkin);
412
413 /*!
414 * @function dispatch_mach_cancel
415 * Cancel a mach channel, preventing any further messages from being sent or
416 * received.
417 *
418 * The application must wait for the channel handler to be invoked with
419 * DISPATCH_MACH_DISCONNECTED before releasing the underlying send and receive
420 * rights.
421 *
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.
426 *
427 * @param channel
428 * The mach channel to cancel.
429 */
430 API_AVAILABLE(macos(10.9), ios(6.0))
431 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
432 void
433 dispatch_mach_cancel(dispatch_mach_t channel);
434
435 /*!
436 * @function dispatch_mach_send
437 * Asynchronously send a message encapsulated in a dispatch mach message object
438 * to the specified mach channel.
439 *
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.
444 *
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
451 * receive right.
452 *
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.
459 *
460 * @param channel
461 * The mach channel to which to send the message.
462 *
463 * @param 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
467 * send operation.
468 *
469 * @param options
470 * Additional send options to pass to mach_msg() when performing the send
471 * operation.
472 */
473 API_AVAILABLE(macos(10.9), ios(6.0))
474 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL2 DISPATCH_NOTHROW
475 void
476 dispatch_mach_send(dispatch_mach_t channel, dispatch_mach_msg_t message,
477 mach_msg_option_t options);
478
479 /*!
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.
484 *
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.
489 *
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
496 * receive right.
497 *
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.
504 *
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.
510 *
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.
515 *
516 * @param channel
517 * The mach channel to which to send the message.
518 *
519 * @param 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.
524 *
525 * @param options
526 * Additional send options to pass to mach_msg() when performing the send
527 * operation.
528 *
529 * @param send_flags
530 * Flags to configure the send operation. Must be 0 for now.
531 *
532 * @param send_result
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.
535 * Must not be NULL.
536 *
537 * @param send_error
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.
540 */
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
544 void
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);
549
550 /*!
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.
554 *
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.
559 *
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
566 * be returned.
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.
570 *
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).
577 *
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).
584 *
585 * @param channel
586 * The mach channel to which to send the message.
587 *
588 * @param 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
592 * send operation.
593 *
594 * @param options
595 * Additional send options to pass to mach_msg() when performing the send
596 * operation.
597 *
598 * @result
599 * The received reply message object, or NULL if the channel was canceled.
600 */
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);
607
608 /*!
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.
613 *
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.
618 *
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
625 * be returned.
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.
629 *
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).
636 *
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).
643 *
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.
649 *
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.
654 *
655 * @param channel
656 * The mach channel to which to send the message.
657 *
658 * @param 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.
663 *
664 * @param options
665 * Additional send options to pass to mach_msg() when performing the send
666 * operation.
667 *
668 * @param send_flags
669 * Flags to configure the send operation. Must be 0 for now.
670 *
671 * @param send_result
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.
674 * Must not be NULL.
675 *
676 * @param send_error
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.
679 *
680 * @result
681 * The received reply message object, or NULL if the channel was canceled.
682 */
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
686 DISPATCH_NOTHROW
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);
692
693 #ifdef __BLOCKS__
694 /*!
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.
701 *
702 * @param channel
703 * The mach channel to which to submit the barrier.
704 *
705 * @param barrier
706 * The barrier block to submit to the channel target queue.
707 */
708 API_AVAILABLE(macos(10.9), ios(6.0))
709 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
710 void
711 dispatch_mach_send_barrier(dispatch_mach_t channel, dispatch_block_t barrier);
712 #endif
713
714 /*!
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.
721 *
722 * @param channel
723 * The mach channel to which to submit the barrier.
724 *
725 * @param context
726 * The application-defined context parameter to pass to the function.
727 *
728 * @param barrier
729 * The barrier function to submit to the channel target queue.
730 */
731 API_AVAILABLE(macos(10.9), ios(6.0))
732 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
733 void
734 dispatch_mach_send_barrier_f(dispatch_mach_t channel, void *_Nullable context,
735 dispatch_function_t barrier);
736
737 #ifdef __BLOCKS__
738 /*!
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.
744 *
745 * @param channel
746 * The mach channel to which to submit the receive barrier.
747 *
748 * @param barrier
749 * The barrier block to submit to the channel target queue.
750 */
751 API_AVAILABLE(macos(10.9), ios(6.0))
752 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
753 void
754 dispatch_mach_receive_barrier(dispatch_mach_t channel,
755 dispatch_block_t barrier);
756 #endif
757
758 /*!
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.
764 *
765 * @param channel
766 * The mach channel to which to submit the receive barrier.
767 *
768 * @param context
769 * The application-defined context parameter to pass to the function.
770 *
771 * @param barrier
772 * The barrier function to submit to the channel target queue.
773 */
774 API_AVAILABLE(macos(10.9), ios(6.0))
775 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
776 void
777 dispatch_mach_receive_barrier_f(dispatch_mach_t channel, void *_Nullable context,
778 dispatch_function_t barrier);
779
780 /*!
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).
786 *
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.
790 *
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
793 * called.
794 *
795 * @param channel
796 * The mach channel to query.
797 *
798 * @result
799 * The most recently specified check-in port for the channel.
800 */
801 API_AVAILABLE(macos(10.9), ios(6.0))
802 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
803 mach_port_t
804 dispatch_mach_get_checkin_port(dispatch_mach_t channel);
805
806 // SPI for libxpc
807 /*
808 * Type for the callback for receipt of asynchronous replies to
809 * dispatch_mach_send_with_result_and_async_reply_4libxpc().
810 */
811 typedef void (*_Nonnull dispatch_mach_async_reply_callback_t)(void *context,
812 dispatch_mach_reason_t reason, dispatch_mach_msg_t message);
813
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;
818
819 /* Fields available in version 1. */
820
821 /*
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.
830 */
831 bool (* _Nonnull dmxh_direct_message_handler)(void *_Nullable context,
832 dispatch_mach_reason_t reason, dispatch_mach_msg_t message,
833 mach_error_t error);
834
835 /* Fields available in version 2. */
836
837 /*
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
846 * other code.
847 */
848 dispatch_queue_t _Nullable (*_Nonnull dmxh_msg_context_reply_queue)(
849 void *_Nonnull msg_context);
850
851 /*
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
863 * details.
864 */
865 dispatch_mach_async_reply_callback_t dmxh_async_reply_handler;
866
867 /* Fields available in version 3. */
868 /**
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.
872 */
873 bool (* _Nullable dmxh_enable_sigterm_notification)(
874 void *_Nullable context);
875 } *dispatch_mach_xpc_hooks_t;
876
877 #define DISPATCH_MACH_XPC_SUPPORTS_ASYNC_REPLIES(hooks) ((hooks)->version >= 2)
878
879 /*!
880 * @function dispatch_mach_hooks_install_4libxpc
881 *
882 * @abstract
883 * installs XPC callbacks for dispatch Mach channels.
884 *
885 * @discussion
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.
892 *
893 * @param hooks
894 * A pointer to the channel hooks structure. This must remain valid once set.
895 */
896 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
897 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
898 void
899 dispatch_mach_hooks_install_4libxpc(dispatch_mach_xpc_hooks_t hooks);
900
901 /*!
902 * @function dispatch_mach_create_4libxpc
903 * Create a dispatch mach channel to asynchronously receive and send mach
904 * messages, specifically for libxpc.
905 *
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.
913 *
914 * Dispatch mach channels are created in a disconnected state, they must be
915 * connected via dispatch_mach_connect() to begin receiving and sending
916 * messages.
917 *
918 * @param label
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.
922 *
923 * @param queue
924 * The target queue of the channel, where the handler and barrier blocks will
925 * be submitted.
926 *
927 * @param context
928 * The application-defined context to pass to the handler.
929 *
930 * @param handler
931 * The handler function to submit when a message has been sent or received.
932 *
933 * @result
934 * The newly created dispatch mach channel.
935 */
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
939 dispatch_mach_t
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);
943
944 /*!
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.
949 *
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.
956 *
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
959 * channel queue.
960 *
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.
965 *
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.
973 *
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.
980 *
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.
986 *
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.
991 *
992 * @param channel
993 * The mach channel to which to send the message.
994 *
995 * @param 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.
1000 *
1001 * @param options
1002 * Additional send options to pass to mach_msg() when performing the send
1003 * operation.
1004 *
1005 * @param send_flags
1006 * Flags to configure the send operation. Must be 0 for now.
1007 *
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.
1011 * Must not be NULL.
1012 *
1013 * @param send_error
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.
1016 */
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
1020 void
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);
1025
1026 DISPATCH_ASSUME_NONNULL_END
1027
1028 #endif // DISPATCH_MACH_SPI
1029
1030 __END_DECLS
1031
1032 #endif