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_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);
void
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. Newly
created sources are created in a suspended state. After the source has been
configured by setting an event handler, cancellation 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_MACH_SEND
- DISPATCH_SOURCE_TYPE_MACH_RECV
- 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 and
DISPATCH_SOURCE_TYPE_DATA_OR source types.
The result of using this function with any other source type is undefined.
Calling this function will atomically add or logical OR the data into the
source's data, and trigger the delivery of the source's event handler.
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.
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.
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).
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
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 logic OR (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
() indicates which
of the events in the
mask were observed.
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_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_REAP
- The process status has been collected by its parent process via
wait(2).
- • DISPATCH_PROC_SIGNAL
- A signal was delivered to the process.
The data returned by
dispatch_source_get_data
() 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 on an interval specified by
dispatch_source_set_timer
(). The
handle and
mask arguments are unused and should be zero.
A best effort attempt is made to submit the event handler block to the target
queue at the specified time; however, actual invocation may occur at a later
time.
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 function
dispatch_source_set_timer
()
takes as an argument the
start time of the
timer (initial fire time) represented as a
dispatch_time_t. The timer dispatch source
will use the same clock as the function used to create this value. (See
dispatch_time(3) for more information.) The
interval, in nanoseconds, specifies the
period at which the timer should repeat. All timers will repeat indefinitely
until
dispatch_source_cancel
() is called.
The
leeway, in nanoseconds, is a hint to the
system that it may defer the timer in order to align with other system
activity for improved system performance or reduced power consumption. (For
example, an application might perform a periodic task every 5 minutes with a
leeway of up to 30 seconds.) Note that some latency is to be expected for all
timers even when a value of zero is used.
Note: Under the C language, untyped numbers default
to the
int type. This can lead to truncation
bugs when arithmetic operations with other numbers are expected to generate a
uint64_t sized result. When in doubt, use
ull as a suffix. For example:
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.
The data returned by
dispatch_source_get_data
() 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.
SEE ALSO¶
dispatch(3),
dispatch_object(3),
dispatch_queue_create(3)