blob: bc5322332937150f393f80535dd27097f7032676 [file] [log] [blame]
/*
* Copyright (c) 2012-2013 Apple Inc. All rights reserved.
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @APPLE_APACHE_LICENSE_HEADER_END@
*/
/*
* IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
* which are subject to change in future releases of Mac OS X. Any applications
* relying on these interfaces WILL break.
*/
#ifndef __DISPATCH_MACH_PRIVATE__
#define __DISPATCH_MACH_PRIVATE__
#ifndef __DISPATCH_INDIRECT__
#error "Please #include <dispatch/dispatch.h> instead of this file directly."
#include <dispatch/base.h> // for HeaderDoc
#endif
__BEGIN_DECLS
#if DISPATCH_MACH_SPI
#define DISPATCH_MACH_SPI_VERSION 20161026
#include <mach/mach.h>
DISPATCH_ASSUME_NONNULL_BEGIN
/*!
* @functiongroup Dispatch Mach Channel SPI
*
* IMPORTANT: This is Libsystem-internal SPI not intended for general use and
* is subject to change at any time without warning.
*/
/*!
* @typedef dispatch_mach_t
* A dispatch mach channel asynchronously recevives and sends mach messages.
*/
DISPATCH_DECL(dispatch_mach);
/*!
* @typedef dispatch_mach_reason_t
* Reasons for a mach channel handler to be invoked, or the result of an
* immediate send attempt.
*
* @const DISPATCH_MACH_CONNECTED
* The channel has been connected. The first handler invocation on a channel
* after calling dispatch_mach_connect() will have this reason.
*
* @const DISPATCH_MACH_MESSAGE_RECEIVED
* A message was received, it is passed in the message parameter.
*
* @const DISPATCH_MACH_MESSAGE_SENT
* A message was sent, it is passed in the message parameter (so that associated
* resources can be disposed of).
*
* @const DISPATCH_MACH_MESSAGE_SEND_FAILED
* A message failed to be sent, it is passed in the message parameter (so that
* associated resources can be disposed of), along with the error code from
* mach_msg().
*
* @const DISPATCH_MACH_MESSAGE_NOT_SENT
* A message was not sent due to the channel being canceled or reconnected, it
* is passed in the message parameter (so that associated resources can be
* disposed of).
*
* @const DISPATCH_MACH_BARRIER_COMPLETED
* A barrier block has finished executing.
*
* @const DISPATCH_MACH_DISCONNECTED
* The channel has been disconnected by a call to dispatch_mach_reconnect() or
* dispatch_mach_cancel(), an empty message is passed in the message parameter
* (so that associated port rights can be disposed of).
* The message header will contain either a remote port with a previously
* connected send right, or a local port with a previously connected receive
* right (if the channel was canceled), or a local port with a receive right
* that was being monitored for a direct reply to a message previously sent to
* the channel (if no reply was received).
*
* @const DISPATCH_MACH_CANCELED
* The channel has been canceled.
*
* @const DISPATCH_MACH_REPLY_RECEIVED
* A synchronous reply to a call to dispatch_mach_send_and_wait_for_reply() has
* been received on another thread, an empty message is passed in the message
* parameter (so that associated port rights can be disposed of).
* The message header will contain a local port with a receive right associated
* with the reply to the message that was synchronously sent to the channel.
*
* @const DISPATCH_MACH_NEEDS_DEFERRED_SEND
* The message could not be sent synchronously. Only returned from a send with
* result operation and never passed to a channel handler. Indicates that the
* message passed to the send operation must not be disposed of until it is
* returned via the channel handler.
*
* @const DISPATCH_MACH_SIGTERM_RECEIVED
* A SIGTERM signal has been received. This notification is delivered at most
* once during the lifetime of the channel. This event is sent only for XPC
* channels (i.e. channels that were created by calling
* dispatch_mach_create_4libxpc()) and only if the
* dmxh_enable_sigterm_notification function in the XPC hooks structure is not
* set or it returned true when it was called at channel activation time.
*
* @const DISPATCH_MACH_ASYNC_WAITER_DISCONNECTED
* The channel has been disconnected by a call to dispatch_mach_reconnect() or
* dispatch_mach_cancel(), an empty message is passed in the message parameter
* (so that associated port rights can be disposed of). The message header will
* contain a local port with the receive right previously allocated to receive
* an asynchronous reply to a message previously sent to the channel. Used
* only if the channel is disconnected while waiting for a reply to a message
* sent with dispatch_mach_send_with_result_and_async_reply_4libxpc().
*/
DISPATCH_ENUM(dispatch_mach_reason, unsigned long,
DISPATCH_MACH_CONNECTED = 1,
DISPATCH_MACH_MESSAGE_RECEIVED,
DISPATCH_MACH_MESSAGE_SENT,
DISPATCH_MACH_MESSAGE_SEND_FAILED,
DISPATCH_MACH_MESSAGE_NOT_SENT,
DISPATCH_MACH_BARRIER_COMPLETED,
DISPATCH_MACH_DISCONNECTED,
DISPATCH_MACH_CANCELED,
DISPATCH_MACH_REPLY_RECEIVED,
DISPATCH_MACH_NEEDS_DEFERRED_SEND,
DISPATCH_MACH_SIGTERM_RECEIVED,
DISPATCH_MACH_ASYNC_WAITER_DISCONNECTED,
DISPATCH_MACH_REASON_LAST, /* unused */
);
/*!
* @typedef dispatch_mach_send_flags_t
* Flags that can be passed to the *with_flags send functions.
*/
DISPATCH_ENUM(dispatch_mach_send_flags, unsigned long,
DISPATCH_MACH_SEND_DEFAULT = 0,
);
/*!
* @typedef dispatch_mach_trailer_t
* Trailer type of mach message received by dispatch mach channels
*/
typedef mach_msg_context_trailer_t dispatch_mach_trailer_t;
/*!
* @constant DISPATCH_MACH_RECEIVE_MAX_INLINE_MESSAGE_SIZE
* Maximum size of a message that can be received inline by a dispatch mach
* channel, reception of larger messages requires an extra roundtrip through
* the kernel.
*/
#define DISPATCH_MACH_RECEIVE_MAX_INLINE_MESSAGE_SIZE \
(0x4000 - sizeof(dispatch_mach_trailer_t))
/*!
* @typedef dispatch_mach_msg_t
* A dispatch mach message encapsulates messages received or sent with dispatch
* mach channels.
*/
DISPATCH_DECL(dispatch_mach_msg);
/*!
* @typedef dispatch_mach_msg_destructor_t
* Dispatch mach message object destructors.
*
* @const DISPATCH_MACH_MSG_DESTRUCTOR_DEFAULT
* Message buffer storage is internal to the object, if a buffer is supplied
* during object creation, its contents are copied.
*
* @const DISPATCH_MACH_MSG_DESTRUCTOR_FREE
* Message buffer will be deallocated with free(3).
*
* @const DISPATCH_MACH_MSG_DESTRUCTOR_FREE
* Message buffer will be deallocated with vm_deallocate.
*/
DISPATCH_ENUM(dispatch_mach_msg_destructor, unsigned int,
DISPATCH_MACH_MSG_DESTRUCTOR_DEFAULT = 0,
DISPATCH_MACH_MSG_DESTRUCTOR_FREE,
DISPATCH_MACH_MSG_DESTRUCTOR_VM_DEALLOCATE,
);
/*!
* @function dispatch_mach_msg_create
* Creates a dispatch mach message object, either with a newly allocated message
* buffer of given size, or from an existing message buffer that will be
* deallocated with the specified destructor when the object is released.
*
* If a non-NULL reference to a pointer is provided in 'msg_ptr', it is filled
* with the location of the (possibly newly allocated) message buffer.
*
* It is the responsibility of the application to ensure that it does not modify
* the underlying message buffer once the dispatch mach message object is passed
* to other dispatch mach API.
*
* @param msg The message buffer to create the message object from.
* If 'destructor' is DISPATCH_MACH_MSG_DESTRUCTOR_DEFAULT,
* this argument may be NULL to leave the newly allocated
* message buffer zero-initialized.
* @param size The size of the message buffer.
* Must be >= sizeof(mach_msg_header_t)
* @param destructor The destructor to use to deallocate the message buffer
* when the object is released.
* @param msg_ptr A pointer to a pointer variable to be filled with the
* location of the (possibly newly allocated) message
* buffer, or NULL.
* @result A newly created dispatch mach message object.
*/
API_AVAILABLE(macos(10.9), ios(7.0))
DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
DISPATCH_NOTHROW
dispatch_mach_msg_t
dispatch_mach_msg_create(mach_msg_header_t *_Nullable msg, size_t size,
dispatch_mach_msg_destructor_t destructor,
mach_msg_header_t *_Nonnull *_Nullable msg_ptr);
/*!
* @function dispatch_mach_msg_get_msg
* Returns the message buffer underlying a dispatch mach message object.
*
* @param message The dispatch mach message object to query.
* @param size_ptr A pointer to a size_t variable to be filled with the
* size of the message buffer, or NULL.
* @result Pointer to message buffer underlying the object.
*/
API_AVAILABLE(macos(10.9), ios(7.0))
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
mach_msg_header_t*
dispatch_mach_msg_get_msg(dispatch_mach_msg_t message,
size_t *_Nullable size_ptr);
#ifdef __BLOCKS__
/*!
* @typedef dispatch_mach_handler_t
* Prototype of dispatch mach channel handler blocks.
*
* @param reason Reason the handler was invoked.
* @param message Message object that was sent or received.
* @param error Mach error code for the send operation.
*/
typedef void (^dispatch_mach_handler_t)(dispatch_mach_reason_t reason,
dispatch_mach_msg_t _Nullable message, mach_error_t error);
/*!
* @function dispatch_mach_create
* Create a dispatch mach channel to asynchronously receive and send mach
* messages.
*
* The specified handler will be called with the corresponding reason parameter
* for each message received and for each message that was successfully sent,
* that failed to be sent, or was not sent; as well as when a barrier block
* has completed, or when channel connection, reconnection or cancellation has
* taken effect.
*
* Dispatch mach channels are created in a disconnected state, they must be
* connected via dispatch_mach_connect() to begin receiving and sending
* messages.
*
* @param label
* An optional string label to attach to the channel. The string is not copied,
* if it is non-NULL it must point to storage that remains valid for the
* lifetime of the channel object. May be NULL.
*
* @param queue
* The target queue of the channel, where the handler and barrier blocks will
* be submitted.
*
* @param handler
* The handler block to submit when a message has been sent or received.
*
* @result
* The newly created dispatch mach channel.
*/
API_AVAILABLE(macos(10.9), ios(6.0))
DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
DISPATCH_NONNULL3 DISPATCH_NOTHROW
dispatch_mach_t
dispatch_mach_create(const char *_Nullable label,
dispatch_queue_t _Nullable queue, dispatch_mach_handler_t handler);
#endif
/*!
* @typedef dispatch_mach_handler_function_t
* Prototype of dispatch mach channel handler functions.
*
* @param context Application-defined context parameter.
* @param reason Reason the handler was invoked.
* @param message Message object that was sent or received.
* @param error Mach error code for the send operation.
*/
typedef void (*dispatch_mach_handler_function_t)(void *_Nullable context,
dispatch_mach_reason_t reason, dispatch_mach_msg_t _Nullable message,
mach_error_t error);
/*!
* @function dispatch_mach_create_f
* Create a dispatch mach channel to asynchronously receive and send mach
* messages.
*
* The specified handler will be called with the corresponding reason parameter
* for each message received and for each message that was successfully sent,
* that failed to be sent, or was not sent; as well as when a barrier block
* has completed, or when channel connection, reconnection or cancellation has
* taken effect.
*
* Dispatch mach channels are created in a disconnected state, they must be
* connected via dispatch_mach_connect() to begin receiving and sending
* messages.
*
* @param label
* An optional string label to attach to the channel. The string is not copied,
* if it is non-NULL it must point to storage that remains valid for the
* lifetime of the channel object. May be NULL.
*
* @param queue
* The target queue of the channel, where the handler and barrier blocks will
* be submitted.
*
* @param context
* The application-defined context to pass to the handler.
*
* @param handler
* The handler function to submit when a message has been sent or received.
*
* @result
* The newly created dispatch mach channel.
*/
API_AVAILABLE(macos(10.9), ios(6.0))
DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
DISPATCH_NONNULL4 DISPATCH_NOTHROW
dispatch_mach_t
dispatch_mach_create_f(const char *_Nullable label,
dispatch_queue_t _Nullable queue, void *_Nullable context,
dispatch_mach_handler_function_t handler);
/*!
* @function dispatch_mach_connect
* Connect a mach channel to the specified receive and send rights.
*
* This function must only be called once during the lifetime of a channel, it
* will initiate message reception and perform any already submitted message
* sends or barrier operations.
*
* @param channel
* The mach channel to connect.
*
* @param receive
* The receive right to associate with the channel. May be MACH_PORT_NULL.
*
* @param send
* The send right to associate with the channel. May be MACH_PORT_NULL.
*
* @param checkin
* An optional message object encapsulating the initial check-in message to send
* upon channel connection. The check-in message is sent immediately before the
* first message submitted via dispatch_mach_send(). The message object will be
* retained until the initial send operation is complete (or not peformed due
* to channel cancellation or reconnection) and the channel handler has
* returned. May be NULL.
*/
API_AVAILABLE(macos(10.9), ios(6.0))
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
void
dispatch_mach_connect(dispatch_mach_t channel, mach_port_t receive,
mach_port_t send, dispatch_mach_msg_t _Nullable checkin);
/*!
* @function dispatch_mach_reconnect
* Reconnect a mach channel to the specified send right.
*
* Disconnects the channel from the current send right, interrupts any pending
* message sends (and returns the messages as unsent), and reconnects the
* channel to a new send right.
*
* The application must wait for the channel handler to be invoked with
* DISPATCH_MACH_DISCONNECTED before releasing the previous send right.
*
* @param channel
* The mach channel to reconnect.
*
* @param send
* The new send right to associate with the channel. May be MACH_PORT_NULL.
*
* @param checkin
* An optional message object encapsulating the initial check-in message to send
* upon channel reconnection. The check-in message is sent immediately before
* the first message submitted via dispatch_mach_send() after this function
* returns. The message object will be retained until the initial send operation
* is complete (or not peformed due to channel cancellation or reconnection)
* and the channel handler has returned. May be NULL.
*/
API_AVAILABLE(macos(10.9), ios(6.0))
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
void
dispatch_mach_reconnect(dispatch_mach_t channel, mach_port_t send,
dispatch_mach_msg_t _Nullable checkin);
/*!
* @function dispatch_mach_cancel
* Cancel a mach channel, preventing any further messages from being sent or
* received.
*
* The application must wait for the channel handler to be invoked with
* DISPATCH_MACH_DISCONNECTED before releasing the underlying send and receive
* rights.
*
* Note: explicit cancellation of mach channels is required, no implicit
* cancellation takes place on release of the last application reference
* to the channel object. Failure to cancel will cause the channel and
* its associated resources to be leaked.
*
* @param channel
* The mach channel to cancel.
*/
API_AVAILABLE(macos(10.9), ios(6.0))
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
void
dispatch_mach_cancel(dispatch_mach_t channel);
/*!
* @function dispatch_mach_send
* Asynchronously send a message encapsulated in a dispatch mach message object
* to the specified mach channel.
*
* Unless the message is being sent to a send-once right (as determined by the
* presence of MACH_MSG_TYPE_MOVE_SEND_ONCE in the message header remote bits),
* the message header remote port is set to the channel send right before the
* send operation is performed.
*
* If the message expects a direct reply (as determined by the presence of
* MACH_MSG_TYPE_MAKE_SEND_ONCE in the message header local bits) the receive
* right specified in the message header local port will be monitored until a
* reply message (or a send-once notification) is received, or the channel is
* canceled. Hence the application must wait for the channel handler to be
* invoked with a DISPATCH_MACH_DISCONNECTED message before releasing that
* receive right.
*
* If the message send operation is attempted but the channel is canceled
* before the send operation succesfully completes, the message returned to the
* channel handler with DISPATCH_MACH_MESSAGE_NOT_SENT may be the result of a
* pseudo-receive operation. If the message expected a direct reply, the
* receive right originally specified in the message header local port will
* returned in a DISPATCH_MACH_DISCONNECTED message.
*
* @param channel
* The mach channel to which to send the message.
*
* @param message
* The message object encapsulating the message to send. The object will be
* retained until the send operation is complete and the channel handler has
* returned. The storage underlying the message object may be modified by the
* send operation.
*
* @param options
* Additional send options to pass to mach_msg() when performing the send
* operation.
*/
API_AVAILABLE(macos(10.9), ios(6.0))
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL2 DISPATCH_NOTHROW
void
dispatch_mach_send(dispatch_mach_t channel, dispatch_mach_msg_t message,
mach_msg_option_t options);
/*!
* @function dispatch_mach_send_with_result
* Asynchronously send a message encapsulated in a dispatch mach message object
* to the specified mach channel. If an immediate send can be performed, return
* its result via out parameters.
*
* Unless the message is being sent to a send-once right (as determined by the
* presence of MACH_MSG_TYPE_MOVE_SEND_ONCE in the message header remote bits),
* the message header remote port is set to the channel send right before the
* send operation is performed.
*
* If the message expects a direct reply (as determined by the presence of
* MACH_MSG_TYPE_MAKE_SEND_ONCE in the message header local bits) the receive
* right specified in the message header local port will be monitored until a
* reply message (or a send-once notification) is received, or the channel is
* canceled. Hence the application must wait for the channel handler to be
* invoked with a DISPATCH_MACH_DISCONNECTED message before releasing that
* receive right.
*
* If the message send operation is attempted but the channel is canceled
* before the send operation succesfully completes, the message returned to the
* channel handler with DISPATCH_MACH_MESSAGE_NOT_SENT may be the result of a
* pseudo-receive operation. If the message expected a direct reply, the
* receive right originally specified in the message header local port will
* returned in a DISPATCH_MACH_DISCONNECTED message.
*
* If an immediate send could be performed, returns the resulting reason
* (e.g. DISPATCH_MACH_MESSAGE_SENT) and possible error to the caller in the
* send_result and send_error out parameters (instead of via the channel
* handler), in which case the passed-in message and associated resources
* can be disposed of synchronously.
*
* If a deferred send is required, returns DISPATCH_MACH_NEEDS_DEFERRED_SEND
* in the send_result out parameter to indicate that the passed-in message has
* been retained and associated resources must not be disposed of until the
* message is returned asynchronusly via the channel handler.
*
* @param channel
* The mach channel to which to send the message.
*
* @param message
* The message object encapsulating the message to send. Unless an immediate
* send could be performed, the object will be retained until the asynchronous
* send operation is complete and the channel handler has returned. The storage
* underlying the message object may be modified by the send operation.
*
* @param options
* Additional send options to pass to mach_msg() when performing the send
* operation.
*
* @param send_flags
* Flags to configure the send operation. Must be 0 for now.
*
* @param send_result
* Out parameter to return the result of the immediate send attempt.
* If a deferred send is required, returns DISPATCH_MACH_NEEDS_DEFERRED_SEND.
* Must not be NULL.
*
* @param send_error
* Out parameter to return the error from the immediate send attempt.
* If a deferred send is required, returns 0. Must not be NULL.
*/
API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL2 DISPATCH_NONNULL5
DISPATCH_NONNULL6 DISPATCH_NOTHROW
void
dispatch_mach_send_with_result(dispatch_mach_t channel,
dispatch_mach_msg_t message, mach_msg_option_t options,
dispatch_mach_send_flags_t send_flags,
dispatch_mach_reason_t *send_result, mach_error_t *send_error);
/*!
* @function dispatch_mach_send_and_wait_for_reply
* Synchronously send a message encapsulated in a dispatch mach message object
* to the specified mach channel and wait for a reply.
*
* Unless the message is being sent to a send-once right (as determined by the
* presence of MACH_MSG_TYPE_MOVE_SEND_ONCE in the message header remote bits),
* the message header remote port is set to the channel send right before the
* send operation is performed.
*
* The message is required to expect a direct reply (as determined by the
* presence of MACH_MSG_TYPE_MAKE_SEND_ONCE in the message header local bits)
* and this function will not complete until the receive right specified in the
* message header local port receives a reply message (or a send-once
* notification) which will be returned, or until that receive right is
* destroyed in response to the channel being canceled, in which case NULL will
* be returned.
* In all these cases the application must wait for the channel handler to
* be invoked with a DISPATCH_MACH_REPLY_RECEIVED or DISPATCH_MACH_DISCONNECTED
* message before releasing that receive right.
*
* Alternatively, the application may specify MACH_PORT_NULL in the header local
* port to indicate that the channel should create and manage the reply receive
* right internally, including destroying it upon channel cancellation.
* This is a more efficient mode of operation as no asynchronous operations are
* required to return the receive right (i.e. the channel handler will not be
* called as described above).
*
* If the message send operation is attempted but the channel is canceled
* before the send operation succesfully completes, the message returned to the
* channel handler with DISPATCH_MACH_MESSAGE_NOT_SENT may be the result of a
* pseudo-receive operation. The receive right originally specified in the
* message header local port will returned in a DISPATCH_MACH_DISCONNECTED
* message (unless it was MACH_PORT_NULL).
*
* @param channel
* The mach channel to which to send the message.
*
* @param message
* The message object encapsulating the message to send. The object will be
* retained until the send operation is complete and the channel handler has
* returned. The storage underlying the message object may be modified by the
* send operation.
*
* @param options
* Additional send options to pass to mach_msg() when performing the send
* operation.
*
* @result
* The received reply message object, or NULL if the channel was canceled.
*/
API_AVAILABLE(macos(10.11), ios(9.0))
DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
DISPATCH_NONNULL1 DISPATCH_NONNULL2 DISPATCH_NOTHROW
dispatch_mach_msg_t _Nullable
dispatch_mach_send_and_wait_for_reply(dispatch_mach_t channel,
dispatch_mach_msg_t message, mach_msg_option_t options);
/*!
* @function dispatch_mach_send_with_result_and_wait_for_reply
* Synchronously send a message encapsulated in a dispatch mach message object
* to the specified mach channel and wait for a reply. If an immediate send can
* be performed, return its result via out parameters.
*
* Unless the message is being sent to a send-once right (as determined by the
* presence of MACH_MSG_TYPE_MOVE_SEND_ONCE in the message header remote bits),
* the message header remote port is set to the channel send right before the
* send operation is performed.
*
* The message is required to expect a direct reply (as determined by the
* presence of MACH_MSG_TYPE_MAKE_SEND_ONCE in the message header local bits)
* and this function will not complete until the receive right specified in the
* message header local port receives a reply message (or a send-once
* notification) which will be returned, or until that receive right is
* destroyed in response to the channel being canceled, in which case NULL will
* be returned.
* In all these cases the application must wait for the channel handler to
* be invoked with a DISPATCH_MACH_REPLY_RECEIVED or DISPATCH_MACH_DISCONNECTED
* message before releasing that receive right.
*
* Alternatively, the application may specify MACH_PORT_NULL in the header local
* port to indicate that the channel should create and manage the reply receive
* right internally, including destroying it upon channel cancellation.
* This is a more efficient mode of operation as no asynchronous operations are
* required to return the receive right (i.e. the channel handler will not be
* called as described above).
*
* If the message send operation is attempted but the channel is canceled
* before the send operation succesfully completes, the message returned to the
* channel handler with DISPATCH_MACH_MESSAGE_NOT_SENT may be the result of a
* pseudo-receive operation. The receive right originally specified in the
* message header local port will returned in a DISPATCH_MACH_DISCONNECTED
* message (unless it was MACH_PORT_NULL).
*
* If an immediate send could be performed, returns the resulting reason
* (e.g. DISPATCH_MACH_MESSAGE_SENT) and possible error to the caller in the
* send_result and send_error out parameters (instead of via the channel
* handler), in which case the passed-in message and associated resources
* can be disposed of synchronously.
*
* If a deferred send is required, returns DISPATCH_MACH_NEEDS_DEFERRED_SEND
* in the send_result out parameter to indicate that the passed-in message has
* been retained and associated resources must not be disposed of until the
* message is returned asynchronusly via the channel handler.
*
* @param channel
* The mach channel to which to send the message.
*
* @param message
* The message object encapsulating the message to send. Unless an immediate
* send could be performed, the object will be retained until the asynchronous
* send operation is complete and the channel handler has returned. The storage
* underlying the message object may be modified by the send operation.
*
* @param options
* Additional send options to pass to mach_msg() when performing the send
* operation.
*
* @param send_flags
* Flags to configure the send operation. Must be 0 for now.
*
* @param send_result
* Out parameter to return the result of the immediate send attempt.
* If a deferred send is required, returns DISPATCH_MACH_NEEDS_DEFERRED_SEND.
* Must not be NULL.
*
* @param send_error
* Out parameter to return the error from the immediate send attempt.
* If a deferred send is required, returns 0. Must not be NULL.
*
* @result
* The received reply message object, or NULL if the channel was canceled.
*/
API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
DISPATCH_NONNULL1 DISPATCH_NONNULL2 DISPATCH_NONNULL5 DISPATCH_NONNULL6
DISPATCH_NOTHROW
dispatch_mach_msg_t _Nullable
dispatch_mach_send_with_result_and_wait_for_reply(dispatch_mach_t channel,
dispatch_mach_msg_t message, mach_msg_option_t options,
dispatch_mach_send_flags_t send_flags,
dispatch_mach_reason_t *send_result, mach_error_t *send_error);
#ifdef __BLOCKS__
/*!
* @function dispatch_mach_send_barrier
* Submit a send barrier to the specified mach channel. Messages submitted to
* the channel before the barrier will be sent before the barrier block is
* executed, and messages submitted to the channel after the barrier will only
* be sent once the barrier block has completed and the channel handler
* invocation for the barrier has returned.
*
* @param channel
* The mach channel to which to submit the barrier.
*
* @param barrier
* The barrier block to submit to the channel target queue.
*/
API_AVAILABLE(macos(10.9), ios(6.0))
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
void
dispatch_mach_send_barrier(dispatch_mach_t channel, dispatch_block_t barrier);
#endif
/*!
* @function dispatch_mach_send_barrier_f
* Submit a send barrier to the specified mach channel. Messages submitted to
* the channel before the barrier will be sent before the barrier block is
* executed, and messages submitted to the channel after the barrier will only
* be sent once the barrier block has completed and the channel handler
* invocation for the barrier has returned.
*
* @param channel
* The mach channel to which to submit the barrier.
*
* @param context
* The application-defined context parameter to pass to the function.
*
* @param barrier
* The barrier function to submit to the channel target queue.
*/
API_AVAILABLE(macos(10.9), ios(6.0))
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
void
dispatch_mach_send_barrier_f(dispatch_mach_t channel, void *_Nullable context,
dispatch_function_t barrier);
#ifdef __BLOCKS__
/*!
* @function dispatch_mach_receive_barrier
* Submit a receive barrier to the specified mach channel. Channel handlers for
* messages received by the channel after the receive barrier has been
* submitted will only be invoked once the barrier block has completed and the
* channel handler invocation for the barrier has returned.
*
* @param channel
* The mach channel to which to submit the receive barrier.
*
* @param barrier
* The barrier block to submit to the channel target queue.
*/
API_AVAILABLE(macos(10.9), ios(6.0))
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
void
dispatch_mach_receive_barrier(dispatch_mach_t channel,
dispatch_block_t barrier);
#endif
/*!
* @function dispatch_mach_receive_barrier_f
* Submit a receive barrier to the specified mach channel. Channel handlers for
* messages received by the channel after the receive barrier has been
* submitted will only be invoked once the barrier block has completed and the
* channel handler invocation for the barrier has returned.
*
* @param channel
* The mach channel to which to submit the receive barrier.
*
* @param context
* The application-defined context parameter to pass to the function.
*
* @param barrier
* The barrier function to submit to the channel target queue.
*/
API_AVAILABLE(macos(10.9), ios(6.0))
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
void
dispatch_mach_receive_barrier_f(dispatch_mach_t channel, void *_Nullable context,
dispatch_function_t barrier);
/*!
* @function dispatch_mach_get_checkin_port
* Returns the port specified in the message header remote port of the check-in
* message passed to the most recent invocation of dispatch_mach_connect() or
* dispatch_mach_reconnect() for the provided mach channel (irrespective of the
* completion of the (re)connect or check-in operations in question).
*
* Returns MACH_PORT_NULL if dispatch_mach_connect() has not yet been called or
* if the most recently specified check-in message was NULL, and MACH_PORT_DEAD
* if the channel has been canceled.
*
* It is the responsibility of the application to ensure that the port
* specified in a check-in message remains valid at the time this function is
* called.
*
* @param channel
* The mach channel to query.
*
* @result
* The most recently specified check-in port for the channel.
*/
API_AVAILABLE(macos(10.9), ios(6.0))
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
mach_port_t
dispatch_mach_get_checkin_port(dispatch_mach_t channel);
// SPI for libxpc
/*
* Type for the callback for receipt of asynchronous replies to
* dispatch_mach_send_with_result_and_async_reply_4libxpc().
*/
typedef void (*_Nonnull dispatch_mach_async_reply_callback_t)(void *context,
dispatch_mach_reason_t reason, dispatch_mach_msg_t message);
API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
typedef const struct dispatch_mach_xpc_hooks_s {
#define DISPATCH_MACH_XPC_HOOKS_VERSION 3
unsigned long version;
/* Fields available in version 1. */
/*
* Called to handle a Mach message event inline if possible. Returns true
* if the event was handled, false if the event should be delivered to the
* channel event handler. The implementation should not make any assumptions
* about the thread in which the function is called and cannot assume that
* invocations of this function are serialized relative to each other or
* relative to the channel's event handler function. In addition, the
* handler must not throw an exception or call out to any code that might
* throw an exception.
*/
bool (* _Nonnull dmxh_direct_message_handler)(void *_Nullable context,
dispatch_mach_reason_t reason, dispatch_mach_msg_t message,
mach_error_t error);
/* Fields available in version 2. */
/*
* Gets the queue to which a reply to a message sent using
* dispatch_mach_send_with_result_and_async_reply_4libxpc() should be
* delivered. The msg_context argument is the value of the do_ctxt field
* of the outgoing message, as returned by dispatch_get_context(). If this
* function returns NULL, the reply will be delivered to the channel queue.
* This function should not make any assumptions about the thread on which
* it is called and, since it may be called more than once per message, it
* should execute as quickly as possible and not attempt to synchronize with
* other code.
*/
dispatch_queue_t _Nullable (*_Nonnull dmxh_msg_context_reply_queue)(
void *_Nonnull msg_context);
/*
* Called when a reply to a message sent by
* dispatch_mach_send_with_result_and_async_reply_4libxpc() is received. The
* message argument points to the reply message and the context argument is
* the context value passed to dispatch_mach_create_4libxpc() when creating
* the Mach channel. The handler is called on the queue that is returned by
* dmxh_msg_context_reply_queue() when the reply is received or if the
* channel is disconnected. The reason argument is
* DISPATCH_MACH_MESSAGE_RECEIVED if a reply has been received or
* DISPATCH_MACH_ASYNC_WAITER_DISCONNECTED if the channel has been
* disconnected. Refer to the documentation for
* dispatch_mach_send_with_result_and_async_reply_4libxpc() for more
* details.
*/
dispatch_mach_async_reply_callback_t dmxh_async_reply_handler;
/* Fields available in version 3. */
/**
* Called once when the Mach channel has been activated. If this function
* returns true, a DISPATCH_MACH_SIGTERM_RECEIVED notification will be
* delivered to the channel's event handler when a SIGTERM is received.
*/
bool (* _Nullable dmxh_enable_sigterm_notification)(
void *_Nullable context);
} *dispatch_mach_xpc_hooks_t;
#define DISPATCH_MACH_XPC_SUPPORTS_ASYNC_REPLIES(hooks) ((hooks)->version >= 2)
/*!
* @function dispatch_mach_hooks_install_4libxpc
*
* @abstract
* installs XPC callbacks for dispatch Mach channels.
*
* @discussion
* In order to improve the performance of the XPC/dispatch interface, it is
* sometimes useful for dispatch to be able to call directly into XPC. The
* channel hooks structure should be initialized with pointers to XPC callback
* functions, or NULL for callbacks that XPC does not support. The version
* number in the structure must be set to reflect the fields that have been
* initialized. This function may be called only once.
*
* @param hooks
* A pointer to the channel hooks structure. This must remain valid once set.
*/
API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
void
dispatch_mach_hooks_install_4libxpc(dispatch_mach_xpc_hooks_t hooks);
/*!
* @function dispatch_mach_create_4libxpc
* Create a dispatch mach channel to asynchronously receive and send mach
* messages, specifically for libxpc.
*
* The specified handler will be called with the corresponding reason parameter
* for each message received and for each message that was successfully sent,
* that failed to be sent, or was not sent; as well as when a barrier block
* has completed, or when channel connection, reconnection or cancellation has
* taken effect. However, the handler will not be called for messages that
* were passed to the XPC hooks dmxh_direct_message_handler function if that
* function returned true.
*
* Dispatch mach channels are created in a disconnected state, they must be
* connected via dispatch_mach_connect() to begin receiving and sending
* messages.
*
* @param label
* An optional string label to attach to the channel. The string is not copied,
* if it is non-NULL it must point to storage that remains valid for the
* lifetime of the channel object. May be NULL.
*
* @param queue
* The target queue of the channel, where the handler and barrier blocks will
* be submitted.
*
* @param context
* The application-defined context to pass to the handler.
*
* @param handler
* The handler function to submit when a message has been sent or received.
*
* @result
* The newly created dispatch mach channel.
*/
API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
DISPATCH_NONNULL4 DISPATCH_NOTHROW
dispatch_mach_t
dispatch_mach_create_4libxpc(const char *_Nullable label,
dispatch_queue_t _Nullable queue, void *_Nullable context,
dispatch_mach_handler_function_t handler);
/*!
* @function dispatch_mach_send_with_result_and_async_reply_4libxpc
* SPI for XPC that asynchronously sends a message encapsulated in a dispatch
* mach message object to the specified mach channel. If an immediate send can
* be performed, returns its result via out parameters.
*
* The reply message is processed on the queue returned by the
* dmxh_msg_context_reply_queue function in the dispatch_mach_xpc_hooks_s
* structure, which is called with a single argument whose value is the
* do_ctxt field of the message argument to this function. The reply message is
* delivered to the dmxh_async_reply_handler hook function instead of being
* passed to the channel event handler.
*
* If the dmxh_msg_context_reply_queue function is not implemented or returns
* NULL, the reply message is delivered to the channel event handler on the
* channel queue.
*
* Unless the message is being sent to a send-once right (as determined by the
* presence of MACH_MSG_TYPE_MOVE_SEND_ONCE in the message header remote bits),
* the message header remote port is set to the channel send right before the
* send operation is performed.
*
* The message is required to expect a direct reply (as determined by the
* presence of MACH_MSG_TYPE_MAKE_SEND_ONCE in the message header local bits).
* The receive right specified in the message header local port will be
* monitored until a reply message (or a send-once notification) is received, or
* the channel is canceled. Hence the application must wait for the reply
* to be received or for a DISPATCH_MACH_ASYNC_WAITER_DISCONNECTED message
* before releasing that receive right.
*
* If the message send operation is attempted but the channel is canceled
* before the send operation succesfully completes, the message returned to the
* channel handler with DISPATCH_MACH_MESSAGE_NOT_SENT may be the result of a
* pseudo-receive operation and the receive right originally specified in the
* message header local port will be returned in a
* DISPATCH_MACH_ASYNC_WAITER_DISCONNECTED message.
*
* If an immediate send could be performed, returns the resulting reason
* (e.g. DISPATCH_MACH_MESSAGE_SENT) and possible error to the caller in the
* send_result and send_error out parameters (instead of via the channel
* handler), in which case the passed-in message and associated resources
* can be disposed of synchronously.
*
* If a deferred send is required, returns DISPATCH_MACH_NEEDS_DEFERRED_SEND
* in the send_result out parameter to indicate that the passed-in message has
* been retained and associated resources must not be disposed of until the
* message is returned asynchronusly via the channel handler.
*
* @param channel
* The mach channel to which to send the message.
*
* @param message
* The message object encapsulating the message to send. Unless an immediate
* send could be performed, the object will be retained until the asynchronous
* send operation is complete and the channel handler has returned. The storage
* underlying the message object may be modified by the send operation.
*
* @param options
* Additional send options to pass to mach_msg() when performing the send
* operation.
*
* @param send_flags
* Flags to configure the send operation. Must be 0 for now.
*
* @param send_result
* Out parameter to return the result of the immediate send attempt.
* If a deferred send is required, returns DISPATCH_MACH_NEEDS_DEFERRED_SEND.
* Must not be NULL.
*
* @param send_error
* Out parameter to return the error from the immediate send attempt.
* If a deferred send is required, returns 0. Must not be NULL.
*/
API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL2 DISPATCH_NONNULL5
DISPATCH_NONNULL6 DISPATCH_NOTHROW
void
dispatch_mach_send_with_result_and_async_reply_4libxpc(dispatch_mach_t channel,
dispatch_mach_msg_t message, mach_msg_option_t options,
dispatch_mach_send_flags_t send_flags,
dispatch_mach_reason_t *send_result, mach_error_t *send_error);
DISPATCH_ASSUME_NONNULL_END
#endif // DISPATCH_MACH_SPI
__END_DECLS
#endif