/* * Copyright (c) 2008-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_SOURCE_PRIVATE__ #define __DISPATCH_SOURCE_PRIVATE__ #ifndef __DISPATCH_INDIRECT__ #error "Please #include <dispatch/private.h> instead of this file directly." #include <dispatch/base.h> // for HeaderDoc #endif DISPATCH_ASSUME_NONNULL_BEGIN __BEGIN_DECLS /*! * @const DISPATCH_SOURCE_TYPE_INTERVAL * @discussion A dispatch source that submits the event handler block at a * specified time interval, phase-aligned with all other interval sources on * the system that have the same interval value. * * The initial submission of the event handler will occur at some point during * the first time interval after the source is created (assuming the source is * resumed at that time). * * By default, the unit for the interval value is milliseconds and the leeway * (maximum amount of time any individual handler submission may be deferred to * align with other system activity) for the source is fixed at interval/2. * * If the DISPATCH_INTERVAL_UI_ANIMATION flag is specified, the unit for the * interval value is animation frames (1/60th of a second) and the leeway is * fixed at one frame. * * The handle is the interval value in milliseconds or frames. * The mask specifies which flags from dispatch_source_timer_flags_t to apply. */ #define DISPATCH_SOURCE_TYPE_INTERVAL (&_dispatch_source_type_interval) API_AVAILABLE(macos(10.9), ios(7.0)) DISPATCH_SOURCE_TYPE_DECL(interval); /*! * @const DISPATCH_SOURCE_TYPE_VFS * @discussion Apple-internal dispatch source that monitors for vfs events * defined by dispatch_vfs_flags_t. * The handle is a process identifier (pid_t). */ #define DISPATCH_SOURCE_TYPE_VFS (&_dispatch_source_type_vfs) API_AVAILABLE(macos(10.6), ios(4.0)) DISPATCH_LINUX_UNAVAILABLE() DISPATCH_SOURCE_TYPE_DECL(vfs); /*! * @const DISPATCH_SOURCE_TYPE_VM * @discussion A dispatch source that monitors virtual memory * The mask is a mask of desired events from dispatch_source_vm_flags_t. * This type is deprecated, use DISPATCH_SOURCE_TYPE_MEMORYPRESSURE instead. */ #define DISPATCH_SOURCE_TYPE_VM (&_dispatch_source_type_vm) API_DEPRECATED_WITH_REPLACEMENT("DISPATCH_SOURCE_TYPE_MEMORYPRESSURE", macos(10.7,10.10), ios(4.3,8.0)) DISPATCH_LINUX_UNAVAILABLE() DISPATCH_SOURCE_TYPE_DECL(vm); /*! * @const DISPATCH_SOURCE_TYPE_MEMORYSTATUS * @discussion A dispatch source that monitors memory status * The mask is a mask of desired events from * dispatch_source_memorystatus_flags_t. */ #define DISPATCH_SOURCE_TYPE_MEMORYSTATUS (&_dispatch_source_type_memorystatus) API_DEPRECATED_WITH_REPLACEMENT("DISPATCH_SOURCE_TYPE_MEMORYPRESSURE", macos(10.9, 10.12), ios(6.0, 10.0), tvos(6.0, 10.0), watchos(1.0, 3.0)) DISPATCH_LINUX_UNAVAILABLE() DISPATCH_SOURCE_TYPE_DECL(memorystatus); /*! * @const DISPATCH_SOURCE_TYPE_SOCK * @discussion A dispatch source that monitors events on socket state changes. */ #define DISPATCH_SOURCE_TYPE_SOCK (&_dispatch_source_type_sock) API_AVAILABLE(macos(10.8), ios(6.0)) DISPATCH_LINUX_UNAVAILABLE() DISPATCH_SOURCE_TYPE_DECL(sock); /*! * @const DISPATCH_SOURCE_TYPE_NW_CHANNEL * @discussion A dispatch source that monitors events on a network channel. */ #define DISPATCH_SOURCE_TYPE_NW_CHANNEL (&_dispatch_source_type_nw_channel) API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) DISPATCH_LINUX_UNAVAILABLE() DISPATCH_SOURCE_TYPE_DECL(nw_channel); __END_DECLS /*! * @enum dispatch_source_sock_flags_t * * @constant DISPATCH_SOCK_CONNRESET * Received RST * * @constant DISPATCH_SOCK_READCLOSED * Read side is shutdown * * @constant DISPATCH_SOCK_WRITECLOSED * Write side is shutdown * * @constant DISPATCH_SOCK_TIMEOUT * Timeout: rexmt, keep-alive or persist * * @constant DISPATCH_SOCK_NOSRCADDR * Source address not available * * @constant DISPATCH_SOCK_IFDENIED * Interface denied connection * * @constant DISPATCH_SOCK_SUSPEND * Output queue suspended * * @constant DISPATCH_SOCK_RESUME * Output queue resumed * * @constant DISPATCH_SOCK_KEEPALIVE * TCP Keepalive received * * @constant DISPATCH_SOCK_CONNECTED * Socket is connected * * @constant DISPATCH_SOCK_DISCONNECTED * Socket is disconnected * * @constant DISPATCH_SOCK_CONNINFO_UPDATED * Connection info was updated * * @constant DISPATCH_SOCK_NOTIFY_ACK * Notify acknowledgement */ enum { DISPATCH_SOCK_CONNRESET = 0x00000001, DISPATCH_SOCK_READCLOSED = 0x00000002, DISPATCH_SOCK_WRITECLOSED = 0x00000004, DISPATCH_SOCK_TIMEOUT = 0x00000008, DISPATCH_SOCK_NOSRCADDR = 0x00000010, DISPATCH_SOCK_IFDENIED = 0x00000020, DISPATCH_SOCK_SUSPEND = 0x00000040, DISPATCH_SOCK_RESUME = 0x00000080, DISPATCH_SOCK_KEEPALIVE = 0x00000100, DISPATCH_SOCK_ADAPTIVE_WTIMO = 0x00000200, DISPATCH_SOCK_ADAPTIVE_RTIMO = 0x00000400, DISPATCH_SOCK_CONNECTED = 0x00000800, DISPATCH_SOCK_DISCONNECTED = 0x00001000, DISPATCH_SOCK_CONNINFO_UPDATED = 0x00002000, DISPATCH_SOCK_NOTIFY_ACK = 0x00004000, }; /*! * @enum dispatch_source_nw_channel_flags_t * * @constant DISPATCH_NW_CHANNEL_FLOW_ADV_UPDATE * Received network channel flow advisory. */ enum { DISPATCH_NW_CHANNEL_FLOW_ADV_UPDATE = 0x00000001, }; /*! * @enum dispatch_source_vfs_flags_t * * @constant DISPATCH_VFS_NOTRESP * Server down. * * @constant DISPATCH_VFS_NEEDAUTH * Server bad auth. * * @constant DISPATCH_VFS_LOWDISK * We're low on space. * * @constant DISPATCH_VFS_MOUNT * New filesystem arrived. * * @constant DISPATCH_VFS_UNMOUNT * Filesystem has left. * * @constant DISPATCH_VFS_DEAD * Filesystem is dead, needs force unmount. * * @constant DISPATCH_VFS_ASSIST * Filesystem needs assistance from external program. * * @constant DISPATCH_VFS_NOTRESPLOCK * Server lockd down. * * @constant DISPATCH_VFS_UPDATE * Filesystem information has changed. * * @constant DISPATCH_VFS_VERYLOWDISK * File system has *very* little disk space left. * * @constant DISPATCH_VFS_QUOTA * We hit a user quota (quotactl) for this filesystem. * * @constant DISPATCH_VFS_NEARLOWDISK * Filesystem is nearly full (below NEARLOWDISK level). * * @constant DISPATCH_VFS_DESIREDDISK * Filesystem has exceeded the DESIREDDISK level */ enum { DISPATCH_VFS_NOTRESP = 0x0001, DISPATCH_VFS_NEEDAUTH = 0x0002, DISPATCH_VFS_LOWDISK = 0x0004, DISPATCH_VFS_MOUNT = 0x0008, DISPATCH_VFS_UNMOUNT = 0x0010, DISPATCH_VFS_DEAD = 0x0020, DISPATCH_VFS_ASSIST = 0x0040, DISPATCH_VFS_NOTRESPLOCK = 0x0080, DISPATCH_VFS_UPDATE = 0x0100, DISPATCH_VFS_VERYLOWDISK = 0x0200, DISPATCH_VFS_QUOTA = 0x1000, DISPATCH_VFS_NEARLOWDISK = 0x2000, DISPATCH_VFS_DESIREDDISK = 0x4000, }; /*! * @enum dispatch_source_timer_flags_t * * @constant DISPATCH_TIMER_BACKGROUND * Specifies that the timer is used to trigger low priority maintenance-level * activity and that the system may apply larger minimum leeway values to the * timer in order to align it with other system activity. * * @constant DISPATCH_INTERVAL_UI_ANIMATION * Specifies that the interval source is used for UI animation. The unit for * the interval value of such sources is frames (1/60th of a second) and the * leeway is fixed at one frame. */ enum { DISPATCH_TIMER_BACKGROUND = 0x2, DISPATCH_INTERVAL_UI_ANIMATION = 0x20, }; /*! * @enum dispatch_source_mach_send_flags_t * * @constant DISPATCH_MACH_SEND_POSSIBLE * The mach port corresponding to the given send right has space available * for messages. Delivered only once a mach_msg() to that send right with * options MACH_SEND_MSG|MACH_SEND_TIMEOUT|MACH_SEND_NOTIFY has returned * MACH_SEND_TIMED_OUT (and not again until the next such mach_msg() timeout). * NOTE: The source must have registered the send right for monitoring with the * system for such a mach_msg() to arm the send-possible notifcation, so * the initial send attempt must occur from a source registration handler. */ enum { DISPATCH_MACH_SEND_POSSIBLE = 0x8, }; /*! * @enum dispatch_source_proc_flags_t * * @constant DISPATCH_PROC_REAP * The process has been reaped by the parent process via wait*(). * This flag is deprecated and will be removed in a future release. * * @constant DISPATCH_PROC_EXIT_STATUS * The process has exited. Specifying this flag allows the process exit status * to be retrieved from the source's status value, as returned by the * dispatch_source_get_extended_data() function. The macros * DISPATCH_PROC_EXIT_STATUS_EXITED(), DISPATCH_PROC_EXIT_STATUS_CODE(), * DISPATCH_PROC_EXIT_STATUS_SIGNALED(), DISPATCH_PROC_EXIT_STATUS_TERMSIG() and * DISPATCH_PROC_EXIT_STATUS_CORE_DUMPED() can be used to examine the status * value. */ enum { DISPATCH_PROC_REAP DISPATCH_ENUM_API_DEPRECATED("unsupported flag", macos(10.6,10.9), ios(4.0,7.0)) = 0x10000000, DISPATCH_PROC_EXIT_STATUS DISPATCH_ENUM_API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(2.0)) = 0x04000000, }; /*! * @enum dispatch_source_vm_flags_t * * @constant DISPATCH_VM_PRESSURE * The VM has experienced memory pressure. */ enum { DISPATCH_VM_PRESSURE DISPATCH_ENUM_API_DEPRECATED_WITH_REPLACEMENT("DISPATCH_MEMORYPRESSURE_WARN", macos(10.7, 10.10), ios(4.3, 8.0)) = 0x80000000, }; /*! * @typedef dispatch_source_memorypressure_flags_t * Type of dispatch_source_memorypressure flags * * @constant DISPATCH_MEMORYPRESSURE_LOW_SWAP * The system's memory pressure state has entered the "low swap" condition. * Restricted to the root user. */ enum { DISPATCH_MEMORYPRESSURE_LOW_SWAP DISPATCH_ENUM_API_AVAILABLE(macos(10.10), ios(8.0)) = 0x08, }; /*! * @enum dispatch_source_memorystatus_flags_t * @warning Deprecated, see DISPATCH_MEMORYPRESSURE_* */ enum { DISPATCH_MEMORYSTATUS_PRESSURE_NORMAL DISPATCH_ENUM_API_DEPRECATED_WITH_REPLACEMENT("DISPATCH_MEMORYPRESSURE_NORMAL", macos(10.9, 10.12), ios(6.0, 10.0), tvos(6.0, 10.0), watchos(1.0, 3.0)) = 0x01, DISPATCH_MEMORYSTATUS_PRESSURE_WARN DISPATCH_ENUM_API_DEPRECATED_WITH_REPLACEMENT("DISPATCH_MEMORYPRESSURE_WARN", macos(10.9, 10.12), ios(6.0, 10.0), tvos(6.0, 10.0), watchos(1.0, 3.0)) = 0x02, DISPATCH_MEMORYSTATUS_PRESSURE_CRITICAL DISPATCH_ENUM_API_DEPRECATED_WITH_REPLACEMENT("DISPATCH_MEMORYPRESSURE_CRITICAL", macos(10.9, 10.12), ios(6.0, 10.0), tvos(6.0, 10.0), watchos(1.0, 3.0)) = 0x04, DISPATCH_MEMORYSTATUS_LOW_SWAP DISPATCH_ENUM_API_DEPRECATED_WITH_REPLACEMENT("DISPATCH_MEMORYPRESSURE_LOW_SWAP", macos(10.9, 10.12), ios(6.0, 10.0), tvos(6.0, 10.0), watchos(1.0, 3.0)) = 0x08, }; /*! * @typedef dispatch_source_memorypressure_flags_t * Type of dispatch_source_memorypressure flags * * @constant DISPATCH_MEMORYPRESSURE_PROC_LIMIT_WARN * The memory of the process has crossed 80% of its high watermark limit. * * @constant DISPATCH_MEMORYPRESSURE_PROC_LIMIT_CRITICAL * The memory of the process has reached 100% of its high watermark limit. * * @constant DISPATCH_MEMORYPRESSURE_MSL_STATUS * Mask for enabling/disabling malloc stack logging. */ enum { DISPATCH_MEMORYPRESSURE_PROC_LIMIT_WARN DISPATCH_ENUM_API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) = 0x10, DISPATCH_MEMORYPRESSURE_PROC_LIMIT_CRITICAL DISPATCH_ENUM_API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) = 0x20, DISPATCH_MEMORYPRESSURE_MSL_STATUS DISPATCH_ENUM_API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) = 0xf0000000, }; /*! * Macros to check the exit status obtained from the status field of the * structure returned by the dispatch_source_get_extended_data() function for a * source of type DISPATCH_SOURCE_TYPE_PROC when DISPATCH_PROC_EXIT_STATUS has * been requested. * * DISPATCH_PROC_EXIT_STATUS_EXITED returns whether the process exited. If this * is true, the exit status can be obtained from DISPATCH_PROC_EXIT_STATUS_CODE. * * DISPATCH_PROC_EXIT_STATUS_SIGNALED returns whether the process was terminated * by a signal. * * DISPATCH_PROC_EXIT_STATUS_TERMSIG returns the signal that caused the process * to terminate, or 0 if the process was not terminated by a signal. * * DISPATCH_PROC_EXIT_STATUS_CORE_DUMPED returns whether a core dump of the * process was created. */ #define DISPATCH_PROC_EXIT_STATUS_EXITED(status) ((bool)WIFEXITED(status)) #define DISPATCH_PROC_EXIT_STATUS_CODE(status) ((int)WEXITSTATUS(status)) #define DISPATCH_PROC_EXIT_STATUS_SIGNALED(status) ((bool)WIFSIGNALED(status)) #define DISPATCH_PROC_EXIT_STATUS_TERMSIG(status) ((int)WTERMSIG(status)) #define DISPATCH_PROC_EXIT_STATUS_CORE_DUMPED(status) ((bool)WCOREDUMP(status)) __BEGIN_DECLS /*! * @function dispatch_source_set_mandatory_cancel_handler * * @abstract * Sets the event handler block for the given dispatch source, and indicates * that calling dispatch_source_cancel() is mandatory for this source object. * * @discussion * The cancellation handler (if specified) will be submitted to the source's * target queue in response to a call to dispatch_source_cancel() once the * system has released all references to the source's underlying handle and * the source's event handler block has returned. * * When this function has been used used to set a cancellation handler, then * the following result in an assertion and the process being terminated: * - releasing the last reference on the dispatch source without having * cancelled it by calling dispatch_source_cancel(); * - changing any handler after the source has been activated; * - changing the target queue of the source after it has been activated. * * IMPORTANT: * Source cancellation and a cancellation handler are required for file * descriptor and mach port based sources in order to safely close the * descriptor or destroy the port. Making the cancellation handler of such * sources mandatory is strongly recommended. * Closing the descriptor or port before the cancellation handler is invoked may * result in a race condition. If a new descriptor is allocated with the same * value as the recently closed descriptor while the source's event handler is * still running, the event handler may read/write data to the wrong descriptor. * * @param source * The dispatch source to modify. * The result of passing NULL in this parameter is undefined. * * @param handler * The cancellation handler block to submit to the source's target queue. * The result of passing NULL in this parameter is undefined. */ #ifdef __BLOCKS__ API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW void dispatch_source_set_mandatory_cancel_handler(dispatch_source_t source, dispatch_block_t handler); #endif /* __BLOCKS__ */ /*! * @function dispatch_source_set_mandatory_cancel_handler_f * * @abstract * Sets the event handler function for the given dispatch source, and causes an * assertion if this source is released before having been explicitly canceled. * * @discussion * See dispatch_source_set_mandatory_cancel_handler() for more details. * * @param source * The dispatch source to modify. * The result of passing NULL in this parameter is undefined. * * @param handler * The cancellation handler function to submit to the source's target queue. * The context parameter passed to the event handler function is the current * context of the dispatch source at the time the handler call is made. * The result of passing NULL in this parameter is undefined. */ API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW void dispatch_source_set_mandatory_cancel_handler_f(dispatch_source_t source, dispatch_function_t handler); /*! * @function dispatch_source_cancel_and_wait * * @abstract * Synchronously cancel the dispatch source, preventing any further invocation * of its event handler block. * * @discussion * Cancellation prevents any further invocation of handler blocks for the * specified dispatch source, but does not interrupt a handler block that is * already in progress. * * When this function returns, any handler block that may have been in progress * has returned, the specified source has been unregistered and it is safe to * reclaim any system resource (such as file descriptors or mach ports) that * the specified source was monitoring. * * If the specified dispatch source is inactive, it will be activated as a side * effect of calling this function. * * It is possible to call this function from several threads concurrently, * and it is the responsibility of the callers to synchronize reclaiming the * associated system resources. * * This function is not subject to priority inversion when it is waiting on * a handler block still in progress, unlike patterns based on waiting on * a dispatch semaphore or a dispatch group signaled (or left) from the source * cancel handler. * * This function must not be called if the specified source has a cancel * handler set, or from the context of its handler blocks. * * This function must not be called from the context of the target queue of * the specified source or from any queue that synchronizes with it. Note that * calling dispatch_source_cancel() from such a context already guarantees * that no handler is in progress, and that no new event will be delivered. * * This function must not be called on sources suspended with an explicit * call to dispatch_suspend(), or being concurrently activated on another * thread. * * @param source * The dispatch source to be canceled. * The result of passing NULL in this parameter is undefined. */ API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) DISPATCH_EXPORT DISPATCH_NOTHROW void dispatch_source_cancel_and_wait(dispatch_source_t source); #if __has_include(<mach/mach.h>) /*! * @typedef dispatch_mig_callback_t * * @abstract * The signature of a function that handles Mach message delivery and response. */ typedef boolean_t (*dispatch_mig_callback_t)(mach_msg_header_t *message, mach_msg_header_t *reply); API_AVAILABLE(macos(10.6), ios(4.0)) DISPATCH_LINUX_UNAVAILABLE() DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW mach_msg_return_t dispatch_mig_server(dispatch_source_t ds, size_t maxmsgsz, dispatch_mig_callback_t callback); /*! * @function dispatch_mach_msg_get_context * * @abstract * Extract the context pointer from a mach message trailer. */ API_AVAILABLE(macos(10.6), ios(4.0)) DISPATCH_LINUX_UNAVAILABLE() DISPATCH_EXPORT DISPATCH_PURE DISPATCH_WARN_RESULT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW void *_Nullable dispatch_mach_msg_get_context(mach_msg_header_t *msg); #endif /*! * @typedef dispatch_source_extended_data_t * * @abstract * Type used by dispatch_source_get_extended_data() to return a consistent * snapshot of the data and status of a dispatch source. */ typedef struct dispatch_source_extended_data_s { unsigned long data; unsigned long status; } *dispatch_source_extended_data_t; /*! * @function dispatch_source_get_extended_data * * @abstract * Returns the current data and status values for a dispatch source. * * @discussion * This function is intended to be called from within the event handler block. * The result of calling this function outside of the event handler callback is * undefined. * * @param source * The result of passing NULL in this parameter is undefined. * * @param data * A pointer to a dispatch_source_extended_data_s in which the data and status * will be returned. The data field is populated with the value that would be * returned by dispatch_source_get_data(). The value of the status field should * be interpreted according to the type of the dispatch source: * * DISPATCH_SOURCE_TYPE_PROC: dispatch_source_proc_exit_flags_t * * If called from the event handler of a data source type not listed above, the * status value is undefined. * * @param size * The size of the specified structure. Should be set to * sizeof(dispatch_source_extended_data_s). * * @result * The size of the structure returned in *data, which will never be greater than * the value of the size argument. If this is less than the value of the size * argument, the remaining space in data will have been populated with zeroes. */ API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE DISPATCH_NOTHROW size_t dispatch_source_get_extended_data(dispatch_source_t source, dispatch_source_extended_data_t data, size_t size); __END_DECLS DISPATCH_ASSUME_NONNULL_END #endif