NAME
dispatch_source_create
—
dispatch event sources
SYNOPSIS
#include
<dispatch/dispatch.h>
dispatch_source_t
dispatch_source_create
(dispatch_source_type_t
type, uintptr_t handle, unsigned
long mask, dispatch_queue_t queue);
void
dispatch_source_set_event_handler
(dispatch_source_t
source, void (^block)(void));
void
dispatch_source_set_event_handler_f
(dispatch_source_t
source, void (*function)(void *));
void
dispatch_source_set_registration_handler
(dispatch_source_t
source, void (^block)(void));
void
dispatch_source_set_registration_handler_f
(dispatch_source_t
source, void (*function)(void *));
void
dispatch_source_set_cancel_handler
(dispatch_source_t
source, void (^block)(void));
void
dispatch_source_set_cancel_handler_f
(dispatch_source_t
source, void (*function)(void *));
void
dispatch_source_cancel
(dispatch_source_t
source);
long
dispatch_source_testcancel
(dispatch_source_t
source);
uintptr_t
dispatch_source_get_handle
(dispatch_source_t
source);
unsigned long
dispatch_source_get_mask
(dispatch_source_t
source);
unsigned long
dispatch_source_get_data
(dispatch_source_t
source);
void
dispatch_source_merge_data
(dispatch_source_t
source, unsigned long data);
void
dispatch_source_set_timer
(dispatch_source_t
source, dispatch_time_t start,
uint64_t interval, uint64_t
leeway);
DESCRIPTION
Dispatch event sources may be used to monitor a variety of system objects and events including file descriptors, mach ports, processes, virtual filesystem nodes, signal delivery and timers.
When a state change occurs, the dispatch source will submit its event handler block to its target queue.
The
dispatch_source_create
()
function creates a new dispatch source object that may be retained and
released with calls to
dispatch_retain
()
and
dispatch_release
()
respectively. The queue parameter specifies the target
queue of the new source object, it will be retained by the source object.
Pass the DISPATCH_TARGET_QUEUE_DEFAULT
constant to
use the default target queue (the default priority global concurrent
queue).
Newly created sources are created in a
suspended state. After the source has been configured by setting an event
handler, cancellation handler, registration handler, context, etc., the
source must be activated by a call to
dispatch_resume
()
before any events will be delivered.
Dispatch sources may be one of the following types:
- DISPATCH_SOURCE_TYPE_DATA_ADD
- DISPATCH_SOURCE_TYPE_DATA_OR
- DISPATCH_SOURCE_TYPE_DATA_REPLACE
- DISPATCH_SOURCE_TYPE_MACH_SEND
- DISPATCH_SOURCE_TYPE_MACH_RECV
- DISPATCH_SOURCE_TYPE_MEMORYPRESSURE
- DISPATCH_SOURCE_TYPE_PROC
- DISPATCH_SOURCE_TYPE_READ
- DISPATCH_SOURCE_TYPE_SIGNAL
- DISPATCH_SOURCE_TYPE_TIMER
- DISPATCH_SOURCE_TYPE_VNODE
- DISPATCH_SOURCE_TYPE_WRITE
The handle and
mask arguments to
dispatch_source_create
()
and the return values of the
dispatch_source_get_handle
(),
dispatch_source_get_mask
(), and
dispatch_source_get_data
() functions should be
interpreted according to the type of the dispatch source.
The
dispatch_source_get_handle
()
function returns the underlying handle to the dispatch source (i.e. file
descriptor, mach port, process identifer, etc.). The result of this function
may be cast directly to the underlying type.
The
dispatch_source_get_mask
()
function returns the set of flags that were specified at source creation
time via the mask argument.
The
dispatch_source_get_data
()
function returns the currently pending data for the dispatch source. This
function should only be called from within the source's event handler. The
result of calling this function from any other context is undefined.
The
dispatch_source_merge_data
()
function is intended for use with the
DISPATCH_SOURCE_TYPE_DATA_ADD,
DISPATCH_SOURCE_TYPE_DATA_OR and
DISPATCH_SOURCE_TYPE_DATA_REPLACE source types. The
result of using this function with any other source type is undefined. Data
merging is performed according to the source type:
- • DISPATCH_SOURCE_TYPE_DATA_ADD
- data is atomically added to the source's data
- • DISPATCH_SOURCE_TYPE_DATA_OR
- data is atomically bitwise ORed into the source's data
- • DISPATCH_SOURCE_TYPE_DATA_REPLACE
- data atomically replaces the source's data.
If the source data value resulting from the merge operation is 0, the source handler will not be invoked. This can happen if:
- the atomic addition wraps for sources of type DISPATCH_SOURCE_TYPE_DATA_ADD,
- 0 is merged for sources of type DISPATCH_SOURCE_TYPE_DATA_REPLACE.
SOURCE EVENT HANDLERS
In order to receive events from the dispatch source, an event
handler should be specified via
dispatch_source_set_event_handler
().
The event handler block is submitted to the source's target queue when the
state of the underlying system handle changes, or when an event occurs. If a
source is resumed with no event handler block set, events will be quietly
ignored. If the event handler block is changed while the source is
suspended, or from a block running on a serial queue that is the source's
target queue, then the next event handler invocation will use the new
block.
Dispatch sources may be suspended or resumed
independently of their target queues using
dispatch_suspend
()
and dispatch_resume
() on the dispatch source
directly. The data describing events which occur while a source is suspended
are coalesced and delivered once the source is resumed.
The handler block need not
be reentrant safe, as it is not resubmitted to the target
queue until any prior invocation for that dispatch
source has completed. When the handler is set, the dispatch source will
perform a
Block_copy
()
on the handler block.
To unset the event
handler, call
dispatch_source_set_event_handler_f
()
and pass NULL as function. This unsets the event
handler regardless of whether the handler was a function pointer or a block.
Registration and cancellation handlers (see below) may be unset in the same
way, but as noted below, a cancellation handler may be required.
REGISTRATION
When dispatch_resume
() is called on a
suspended or newly created source, there may be a brief delay before the
source is ready to receive events from the underlying system handle. During
this delay, the event handler will not be invoked, and events will be
missed.
Once the dispatch
source is registered with the underlying system and is ready to process all
events its optional registration handler will be submitted to its target
queue. This registration handler may be specified via
dispatch_source_set_registration_handler
().
The event handler will not be called until the registration handler finishes. If the source is canceled (see below) before it is registered, its registration handler will not be called.
CANCELLATION
The
dispatch_source_cancel
()
function asynchronously cancels the dispatch source, preventing any further
invocation of its event handler block. Cancellation does not interrupt a
currently executing handler block (non-preemptive). If a source is canceled
before the first time it is resumed, its event handler will never be called.
(In this case, note that the source must be resumed before it can be
released.)
The
dispatch_source_testcancel
()
function may be used to determine whether the specified source has been
canceled. A non-zero value will be returned if the source is canceled.
When a dispatch source is
canceled its optional cancellation handler will be submitted to its target
queue. The cancellation handler may be specified via
dispatch_source_set_cancel_handler
().
This cancellation handler is invoked only once, and only as a direct
consequence of calling dispatch_source_cancel
().
Important: a cancellation handler is required for file descriptor and mach port based sources in order to safely close the descriptor or destroy the port. Closing the descriptor or port before the cancellation handler has run 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.
DISPATCH SOURCE TYPES
The following section contains a summary of supported dispatch event types and the interpretation of their parameters and returned data.
DISPATCH_SOURCE_TYPE_DATA_ADD, DISPATCH_SOURCE_TYPE_DATA_OR, DISPATCH_SOURCE_TYPE_DATA_REPLACE
Sources of this type allow
applications to manually trigger the source's event handler via a call to
dispatch_source_merge_data
().
The data will be merged with the source's pending data via an atomic add or
atomic bitwise OR, or direct replacement (based on the source's type), and
the event handler block will be submitted to the source's target queue. The
data is application defined. These sources have no
handle or mask and zero should
be used.
DISPATCH_SOURCE_TYPE_MACH_SEND
Sources of this type monitor a mach port with a send right for state changes. The handle is the mach port (mach_port_t) to monitor and the mask may be:
- • DISPATCH_MACH_SEND_DEAD
- The port's corresponding receive right has been destroyed
The data returned by
dispatch_source_get_data
()
is a bitmask that indicates which of the events in the
mask were observed. Note that because this source type
will request notifications on the provided port, it should not be mixed with
the use of
mach_port_request_notification
()
on the same port.
DISPATCH_SOURCE_TYPE_MACH_RECV
Sources of this type monitor a mach port with a receive right for state changes. The handle is the mach port (mach_port_t) to monitor and the mask is unused and should be zero. The event handler block will be submitted to the target queue when a message on the mach port is waiting to be received.
DISPATCH_SOURCE_TYPE_MEMORYPRESSURE
Sources of this type monitor the system memory pressure condition for state changes. The handle is unused and should be zero. The mask may be one or more of the following:
- • DISPATCH_MEMORYPRESSURE_NORMAL
- The system memory pressure condition has returned to normal.
- • DISPATCH_MEMORYPRESSURE_WARN
- The system memory pressure condition has changed to warning.
- • DISPATCH_MEMORYPRESSURE_CRITICAL
- The system memory pressure condition has changed to critical.
The data returned by
dispatch_source_get_data
()
indicates which of the events in the mask were
observed.
Elevated memory pressure is a system-wide condition that applications registered for this source should react to by changing their future memory use behavior, e.g. by reducing cache sizes of newly initiated operations until memory pressure returns back to normal.
However, applications should NOT traverse and discard existing caches for past operations when the system memory pressure enters an elevated state, as that is likely to trigger VM operations that will further aggravate system memory pressure.
DISPATCH_SOURCE_TYPE_PROC
Sources of this type monitor processes for state changes. The handle is the process identifier (pid_t) of the process to monitor and the mask may be one or more of the following:
- • DISPATCH_PROC_EXIT
- The process has exited and is available to wait(2).
- • DISPATCH_PROC_FORK
- The process has created one or more child processes.
- • DISPATCH_PROC_EXEC
- The process has become another executable image via a call to execve(2) or posix_spawn(2).
- • DISPATCH_PROC_SIGNAL
- A signal was delivered to the process.
The data returned by
dispatch_source_get_data
()
is a bitmask that indicates which of the events in the
mask were observed.
DISPATCH_SOURCE_TYPE_READ
Sources of this type monitor file descriptors for pending data. The handle is the file descriptor (int) to monitor and the mask is unused and should be zero.
The data returned by
dispatch_source_get_data
()
is an estimated number of bytes available to be read from the descriptor.
This estimate should be treated as a suggested
minimum
read buffer size. There are no guarantees that a complete read of this size
will be performed.
Users of this source type are strongly encouraged to perform non-blocking I/O and handle any truncated reads or error conditions that may occur. See fcntl(2) for additional information about setting the O_NONBLOCK flag on a file descriptor.
DISPATCH_SOURCE_TYPE_SIGNAL
Sources of this type monitor signals delivered to the current process. The handle is the signal number to monitor (int) and the mask is unused and should be zero.
The data returned by
dispatch_source_get_data
()
is the number of signals received since the last invocation of the event
handler block.
Unlike signal handlers specified via
sigaction
(),
the execution of the event handler block does not interrupt the current
thread of execution; therefore the handler block is not limited to the use
of signal safe interfaces defined in
sigaction(2). Furthermore, multiple observers of a given signal are
supported; thus allowing applications and libraries to cooperate safely.
However, a dispatch source
does not
install a signal handler or otherwise alter the behavior of signal delivery.
Therefore, applications must ignore or at least catch any signal that
terminates a process by default. For example, near the top of
main
():
signal(SIGTERM, SIG_IGN);
DISPATCH_SOURCE_TYPE_TIMER
Sources of this type periodically submit the event handler block to the target queue. The handle argument is unused and should be zero.
The data returned by
dispatch_source_get_data
()
is the number of times the timer has fired since the last invocation of the
event handler block.
The timer parameters are configured
with the
dispatch_source_set_timer
()
function. Once this function returns, any pending source data accumulated
for the previous timer parameters has been cleared; the next fire of the
timer will occur at start, and every
interval nanoseconds thereafter until the timer source
is canceled.
Any fire of the timer may be delayed by the system in order to improve power consumption and system performance. The upper limit to the allowable delay may be configured with the leeway argument, the lower limit is under the control of the system.
For the initial timer fire at start, the
upper limit to the allowable delay is set to leeway
nanoseconds. For the subsequent timer fires at start
+ N *
interval, the upper
limit is MIN(
leeway,
interval / 2 )
.
The lower limit to the allowable delay may vary with process state such as visibility of application UI. If the specified timer source was created with a mask of DISPATCH_TIMER_STRICT, the system will make a best effort to strictly observe the provided leeway value even if it is smaller than the current lower limit. Note that a minimal amount of delay is to be expected even if this flag is specified.
The start argument
also determines which clock will be used for the timer: If
start is DISPATCH_TIME_NOW or
was created with
dispatch_time(3), the timer is based on up time (which is obtained
from
mach_absolute_time
()
on Apple platforms). If start was created with
dispatch_walltime(3), the timer is based on
gettimeofday(3).
DISPATCH_SOURCE_TYPE_VNODE
Sources of this type monitor the virtual filesystem nodes for state changes. The handle is a file descriptor (int) referencing the node to monitor, and the mask may be one or more of the following:
- • DISPATCH_VNODE_DELETE
- The referenced node was removed from the filesystem namespace via unlink(2).
- • DISPATCH_VNODE_WRITE
- A write to the referenced file occurred.
- • DISPATCH_VNODE_EXTEND
- The referenced file was extended.
- • DISPATCH_VNODE_ATTRIB
- The metadata attributes of the referenced node have changed.
- • DISPATCH_VNODE_LINK
- The link count on the referenced node has changed.
- • DISPATCH_VNODE_RENAME
- The referenced node was renamed.
- • DISPATCH_VNODE_REVOKE
- Access to the referenced node was revoked via revoke(2) or the underlying fileystem was unmounted.
- • DISPATCH_VNODE_FUNLOCK
- The referenced file was unlocked by flock(2) or close(2).
The data returned by
dispatch_source_get_data
()
is a bitmask that indicates which of the events in the
mask were observed.
DISPATCH_SOURCE_TYPE_WRITE
Sources of this type monitor file descriptors for available write buffer space. The handle is the file descriptor (int) to monitor and the mask is unused and should be zero.
Users of this source type are strongly encouraged to perform non-blocking I/O and handle any truncated reads or error conditions that may occur. See fcntl(2) for additional information about setting the O_NONBLOCK flag on a file descriptor.