init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled

This commit is contained in:
allhaileris
2026-02-16 15:50:16 +03:00
commit afb81b8278
13816 changed files with 3689732 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
# TODO(compnerd) add symlinks
if(NOT ENABLE_SWIFT)
install(FILES
dispatch.3
dispatch_after.3
dispatch_api.3
dispatch_apply.3
dispatch_async.3
dispatch_data_create.3
dispatch_group_create.3
dispatch_io_create.3
dispatch_io_read.3
dispatch_object.3
dispatch_once.3
dispatch_queue_create.3
dispatch_read.3
dispatch_semaphore_create.3
dispatch_source_create.3
dispatch_time.3
DESTINATION
"${CMAKE_INSTALL_FULL_MANDIR}/man3")
endif()

View File

@@ -0,0 +1,43 @@
.\" Copyright (c) 2008-2012 Apple Inc. All rights reserved.
.Dd May 1, 2009
.Dt dispatch 3
.Os Darwin
.Sh NAME
.Nm dispatch
.Nd the dispatch framework
.Sh SYNOPSIS
.Fd #include <dispatch/dispatch.h>
.Sh DESCRIPTION
The dispatch framework allows blocks to be scheduled for asynchronous and
concurrent execution via the core functions described in
.Xr dispatch_async 3 and
.Xr dispatch_apply 3 .
.Pp
Dispatch queues are the basic units of organization of blocks. Several queues
are created by default, and applications may create additional queues for their
own use. See
.Xr dispatch_queue_create 3
for more information.
.Pp
Dispatch groups allow applications to track the progress of blocks submitted to
queues and take action when the blocks complete. See
.Xr dispatch_group_create 3
for more information.
.Pp
The dispatch framework also provides functions to monitor underlying system
events and automatically submit event handler blocks to dispatch queues.
.Sh SEE ALSO
.Xr dispatch_after 3 ,
.Xr dispatch_api 3 ,
.Xr dispatch_apply 3 ,
.Xr dispatch_async 3 ,
.Xr dispatch_data_create 3 ,
.Xr dispatch_group_create 3 ,
.Xr dispatch_io_create 3 ,
.Xr dispatch_io_read 3 ,
.Xr dispatch_object 3 ,
.Xr dispatch_once 3 ,
.Xr dispatch_queue_create 3 ,
.Xr dispatch_semaphore_create 3 ,
.Xr dispatch_source_create 3 ,
.Xr dispatch_time 3

View File

@@ -0,0 +1,69 @@
.\" Copyright (c) 2008-2010 Apple Inc. All rights reserved.
.Dd May 1, 2009
.Dt dispatch_after 3
.Os Darwin
.Sh NAME
.Nm dispatch_after
.Nd schedule blocks for deferred execution
.Sh SYNOPSIS
.Fd #include <dispatch/dispatch.h>
.Ft void
.Fo dispatch_after
.Fa "dispatch_time_t when" "dispatch_queue_t queue" "void (^block)(void)"
.Fc
.Ft void
.Fo dispatch_after_f
.Fa "dispatch_time_t when" "dispatch_queue_t queue" "void *context" "void (*function)(void *)"
.Fc
.Sh DESCRIPTION
The
.Fn dispatch_after
function submits the
.Fa block
to the given
.Fa queue
at the time specified by the
.Fa when
parameter.
The
.Fa when
parameter is a value created by
.Fn dispatch_time
or
.Fn dispatch_walltime .
Submission of the block may be delayed by the system in order to improve power consumption and system performance.
The system applies a leeway (see
.Xr dispatch_source_set_timer 3 )
that is equal to one tenth of the interval between
.Fa when
and the time at which the function is called, with the leeway capped to at least one millisecond and at most one minute.
.Pp
For a more detailed description about submitting blocks to queues, see
.Xr dispatch_async 3 .
.Sh CAVEATS
.Fn dispatch_after
retains the passed queue.
.Pp
Specifying
.Vt DISPATCH_TIME_NOW
as the
.Fa when
parameter
is supported, but is not as efficient as calling
.Fn dispatch_async .
.Pp
The result of passing
.Vt DISPATCH_TIME_FOREVER
as the
.Fa when
parameter is undefined.
.Pp
.Sh FUNDAMENTALS
The
.Fn dispatch_after
function is a wrapper around
.Fn dispatch_after_f .
.Sh SEE ALSO
.Xr dispatch 3 ,
.Xr dispatch_async 3 ,
.Xr dispatch_time 3

View File

@@ -0,0 +1,44 @@
.\" Copyright (c) 2008-2009 Apple Inc. All rights reserved.
.Dd May 1, 2009
.Dt dispatch_api 3
.Os Darwin
.Sh NAME
.Nm dispatch_api
.Nd Designing API using dispatch
.Sh DESCRIPTION
The following is a brief summary of some of the common design patterns to
consider when designing and implementing API in terms of dispatch queues
and blocks.
.Pp
A general recommendation is to allow both a callback block and target dispatch
queue to be specified. This gives the application the greatest flexibility in
handling asynchronous events.
.Pp
It's also recommended that interfaces take only a single block as the last
parameter. This is both for consistency across projects, as well as the visual
aesthetics of multiline blocks that are declared inline. The dispatch queue to
which the block will be submitted should immediately precede the block argument
(second-to-last argument). For example:
.Pp
.Bd -literal -offset indent
read_async(file, callback_queue, ^{
printf("received callback.\\n");
});
.Ed
.Pp
When function pointer alternatives to interfaces that take blocks are provided,
the argument order of the function signature should be identical to the block
variant; with the exception that the block argument is replaced with a context
pointer, and a new last parameter is added, which is the function to call.
.Pp
The function based callback should pass the context pointer as the first
argument, and the subsequent arguments should be identical to the block based
variant (albeit offset by one in order).
.Pp
It is also important to use consistent naming. The dispatch API, for example,
uses the suffix "_f" for function based variants.
.Pp
.Sh SEE ALSO
.Xr dispatch 3 ,
.Xr dispatch_async 3 ,
.Xr dispatch_queue_create 3

View File

@@ -0,0 +1,122 @@
.\" Copyright (c) 2008-2017 Apple Inc. All rights reserved.
.Dd May 1, 2009
.Dt dispatch_apply 3
.Os Darwin
.Sh NAME
.Nm dispatch_apply
.Nd schedule blocks for iterative execution
.Sh SYNOPSIS
.Fd #include <dispatch/dispatch.h>
.Ft void
.Fo dispatch_apply
.Fa "size_t iterations" "dispatch_queue_t queue" "void (^block)(size_t)"
.Fc
.Ft void
.Fo dispatch_apply_f
.Fa "size_t iterations" "dispatch_queue_t queue" "void *context" "void (*function)(void *, size_t)"
.Fc
.Sh DESCRIPTION
The
.Fn dispatch_apply
function provides data-level concurrency through a "for (;;)" loop like primitive:
.Bd -literal
size_t iterations = 10;
// 'idx' is zero indexed, just like:
// for (idx = 0; idx < iterations; idx++)
dispatch_apply(iterations, DISPATCH_APPLY_AUTO, ^(size_t idx) {
printf("%zu\\n", idx);
});
.Ed
.Pp
Although any queue can be used, it is strongly recommended to use
.Vt DISPATCH_APPLY_AUTO
as the
.Vt queue
argument to both
.Fn dispatch_apply
and
.Fn dispatch_apply_f ,
as shown in the example above, since this allows the system to automatically use worker threads
that match the configuration of the current thread as closely as possible.
No assumptions should be made about which global concurrent queue will be used.
.Pp
Like a "for (;;)" loop, the
.Fn dispatch_apply
function is synchronous.
If asynchronous behavior is desired, wrap the call to
.Fn dispatch_apply
with a call to
.Fn dispatch_async
against another queue.
.Pp
Sometimes, when the block passed to
.Fn dispatch_apply
is simple, the use of striding can tune performance.
Calculating the optimal stride is best left to experimentation.
Start with a stride of one and work upwards until the desired performance is
achieved (perhaps using a power of two search):
.Bd -literal
#define STRIDE 3
dispatch_apply(count / STRIDE, DISPATCH_APPLY_AUTO, ^(size_t idx) {
size_t j = idx * STRIDE;
size_t j_stop = j + STRIDE;
do {
printf("%zu\\n", j++);
} while (j < j_stop);
});
size_t i;
for (i = count - (count % STRIDE); i < count; i++) {
printf("%zu\\n", i);
}
.Ed
.Sh IMPLIED REFERENCES
Synchronous functions within the dispatch framework hold an implied reference
on the target queue. In other words, the synchronous function borrows the
reference of the calling function (this is valid because the calling function
is blocked waiting for the result of the synchronous function, and therefore
cannot modify the reference count of the target queue until after the
synchronous function has returned).
.Pp
This is in contrast to asynchronous functions which must retain both the block
and target queue for the duration of the asynchronous operation (as the calling
function may immediately release its interest in these objects).
.Sh FUNDAMENTALS
.Fn dispatch_apply
and
.Fn dispatch_apply_f
attempt to quickly create enough worker threads to efficiently iterate work in parallel.
By contrast, a loop that passes work items individually to
.Fn dispatch_async
or
.Fn dispatch_async_f
will incur more overhead and does not express the desired parallel execution semantics to
the system, so may not create an optimal number of worker threads for a parallel workload.
For this reason, prefer to use
.Fn dispatch_apply
or
.Fn dispatch_apply_f
when parallel execution is important.
.Pp
The
.Fn dispatch_apply
function is a wrapper around
.Fn dispatch_apply_f .
.Sh CAVEATS
Unlike
.Fn dispatch_async ,
a block submitted to
.Fn dispatch_apply
is expected to be either independent or dependent
.Em only
on work already performed in lower-indexed invocations of the block. If
the block's index dependency is non-linear, it is recommended to
use a for-loop around invocations of
.Fn dispatch_async .
.Sh SEE ALSO
.Xr dispatch 3 ,
.Xr dispatch_async 3 ,
.Xr dispatch_queue_create 3

View File

@@ -0,0 +1,235 @@
.\" Copyright (c) 2008-2012 Apple Inc. All rights reserved.
.Dd May 1, 2009
.Dt dispatch_async 3
.Os Darwin
.Sh NAME
.Nm dispatch_async ,
.Nm dispatch_sync
.Nd schedule blocks for execution
.Sh SYNOPSIS
.Fd #include <dispatch/dispatch.h>
.Ft void
.Fo dispatch_async
.Fa "dispatch_queue_t queue" "void (^block)(void)"
.Fc
.Ft void
.Fo dispatch_sync
.Fa "dispatch_queue_t queue" "void (^block)(void)"
.Fc
.Ft void
.Fo dispatch_async_f
.Fa "dispatch_queue_t queue" "void *context" "void (*function)(void *)"
.Fc
.Ft void
.Fo dispatch_sync_f
.Fa "dispatch_queue_t queue" "void *context" "void (*function)(void *)"
.Fc
.Sh DESCRIPTION
The
.Fn dispatch_async
and
.Fn dispatch_sync
functions schedule blocks for concurrent execution within the
.Xr dispatch 3
framework. Blocks are submitted to a queue which dictates the policy for their
execution. See
.Xr dispatch_queue_create 3
for more information about creating dispatch queues.
.Pp
These functions support efficient temporal synchronization, background
concurrency and data-level concurrency. These same functions can also be used
for efficient notification of the completion of asynchronous blocks (a.k.a.
callbacks).
.Sh TEMPORAL SYNCHRONIZATION
Synchronization is often required when multiple threads of execution access
shared data concurrently. The simplest form of synchronization is
mutual-exclusion (a lock), whereby different subsystems execute concurrently
until a shared critical section is entered. In the
.Xr pthread 3
family of procedures, temporal synchronization is accomplished like so:
.Bd -literal -offset indent
int r = pthread_mutex_lock(&my_lock);
assert(r == 0);
// critical section
r = pthread_mutex_unlock(&my_lock);
assert(r == 0);
.Ed
.Pp
The
.Fn dispatch_sync
function may be used with a serial queue to accomplish the same style of
synchronization. For example:
.Bd -literal -offset indent
dispatch_sync(my_queue, ^{
// critical section
});
.Ed
.Pp
In addition to providing a more concise expression of synchronization, this
approach is less error prone as the critical section cannot be accidentally
left without restoring the queue to a reentrant state.
.Pp
The
.Fn dispatch_async
function may be used to implement deferred critical sections when the result
of the block is not needed locally. Deferred critical sections have the same
synchronization properties as the above code, but are non-blocking and
therefore more efficient to perform. For example:
.Bd -literal
dispatch_async(my_queue, ^{
// critical section
});
.Ed
.Sh BACKGROUND CONCURRENCY
.The
.Fn dispatch_async
function may be used to execute trivial background tasks on a global concurrent
queue. For example:
.Bd -literal
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
// background operation
});
.Ed
.Pp
This approach is an efficient replacement for
.Xr pthread_create 3 .
.Sh COMPLETION CALLBACKS
Completion callbacks can be accomplished via nested calls to the
.Fn dispatch_async
function. It is important to remember to retain the destination queue before the
first call to
.Fn dispatch_async ,
and to release that queue at the end of the completion callback to ensure the
destination queue is not deallocated while the completion callback is pending.
For example:
.Bd -literal
void
async_read(object_t obj,
void *where, size_t bytes,
dispatch_queue_t destination_queue,
void (^reply_block)(ssize_t r, int err))
{
// There are better ways of doing async I/O.
// This is just an example of nested blocks.
dispatch_retain(destination_queue);
dispatch_async(obj->queue, ^{
ssize_t r = read(obj->fd, where, bytes);
int err = errno;
dispatch_async(destination_queue, ^{
reply_block(r, err);
});
dispatch_release(destination_queue);
});
}
.Ed
.Sh RECURSIVE LOCKS
While
.Fn dispatch_sync
can replace a lock, it cannot replace a recursive lock. Unlike locks, queues
support both asynchronous and synchronous operations, and those operations are
ordered by definition. A recursive call to
.Fn dispatch_sync
causes a simple deadlock as the currently executing block waits for the next
block to complete, but the next block will not start until the currently
running block completes.
.Pp
As the dispatch framework was designed, we studied recursive locks. We found
that the vast majority of recursive locks are deployed retroactively when
ill-defined lock hierarchies are discovered. As a consequence, the adoption of
recursive locks often mutates obvious bugs into obscure ones. This study also
revealed an insight: if reentrancy is unavoidable, then reader/writer locks are
preferable to recursive locks. Disciplined use of reader/writer locks enable
reentrancy only when reentrancy is safe (the "read" side of the lock).
.Pp
Nevertheless, if it is absolutely necessary, what follows is an imperfect way of
implementing recursive locks using the dispatch framework:
.Bd -literal
void
sloppy_lock(object_t object, void (^block)(void))
{
if (object->owner == pthread_self()) {
return block();
}
dispatch_sync(object->queue, ^{
object->owner = pthread_self();
block();
object->owner = NULL;
});
}
.Ed
.Pp
The above example does not solve the case where queue A runs on thread X which
calls
.Fn dispatch_sync
against queue B which runs on thread Y which recursively calls
.Fn dispatch_sync
against queue A, which deadlocks both examples. This is bug-for-bug compatible
with nontrivial pthread usage. In fact, nontrivial reentrancy is impossible to
support in recursive locks once the ultimate level of reentrancy is deployed
(IPC or RPC).
.Sh IMPLIED REFERENCES
Synchronous functions within the dispatch framework hold an implied reference
on the target queue. In other words, the synchronous function borrows the
reference of the calling function (this is valid because the calling function
is blocked waiting for the result of the synchronous function, and therefore
cannot modify the reference count of the target queue until after the
synchronous function has returned).
For example:
.Bd -literal
queue = dispatch_queue_create("com.example.queue", NULL);
assert(queue);
dispatch_sync(queue, ^{
do_something();
//dispatch_release(queue); // NOT SAFE -- dispatch_sync() is still using 'queue'
});
dispatch_release(queue); // SAFELY balanced outside of the block provided to dispatch_sync()
.Ed
.Pp
This is in contrast to asynchronous functions which must retain both the block
and target queue for the duration of the asynchronous operation (as the calling
function may immediately release its interest in these objects).
.Sh FUNDAMENTALS
Conceptually,
.Fn dispatch_sync
is a convenient wrapper around
.Fn dispatch_async
with the addition of a semaphore to wait for completion of the block, and a
wrapper around the block to signal its completion. See
.Xr dispatch_semaphore_create 3
for more information about dispatch semaphores. The actual implementation of the
.Fn dispatch_sync
function may be optimized and differ from the above description.
.Pp
The
.Fn dispatch_async
function is a wrapper around
.Fn dispatch_async_f .
The application-defined
.Fa context
parameter is passed to the
.Fa function
when it is invoked on the target
.Fa queue .
.Pp
The
.Fn dispatch_sync
function is a wrapper around
.Fn dispatch_sync_f .
The application-defined
.Fa context
parameter is passed to the
.Fa function
when it is invoked on the target
.Fa queue .
.Pp
.Sh SEE ALSO
.Xr dispatch 3 ,
.Xr dispatch_apply 3 ,
.Xr dispatch_once 3 ,
.Xr dispatch_queue_create 3 ,
.Xr dispatch_semaphore_create 3

View File

@@ -0,0 +1,59 @@
.\" Copyright (c) 2008-2009 Apple Inc. All rights reserved.
.Dd May 1, 2009
.Dt dispatch_benchmark 3
.Os Darwin
.Sh NAME
.Nm dispatch_benchmark
.Nd Measures block execution time
.Sh SYNOPSIS
.Fd #include <dispatch/dispatch.h>
.Ft uint64_t
.Fo dispatch_benchmark
.Fa "size_t count" "void (^block)(void)"
.Fc
.Ft uint64_t
.Fo dispatch_benchmark_f
.Fa "size_t count" "void *context" "void (*function)(void *)"
.Fc
.Sh DESCRIPTION
The
.Fn dispatch_benchmark
function executes the given
.Fa block
multiple times according to the
.Fa count
variable and then returns the average number of nanoseconds per execution.
This function is for debugging and performance analysis work.
For the best
results, pass a high count value to
.Fn dispatch_benchmark .
When benchmarking concurrent code, please compare the
serial version of the code against the concurrent version, and compare the
concurrent version on different classes of hardware.
Please look for inflection
points with various data sets and keep the following facts in mind:
.Pp
.Bl -bullet -offset indent -compact
.It
Code bound by computational bandwidth may be inferred by proportional
changes in performance as concurrency is increased.
.It
Code bound by memory bandwidth may be inferred by negligible changes in
performance as concurrency is increased.
.It
Code bound by critical sections may be inferred by retrograde changes in
performance as concurrency is increased.
.Bl -bullet -offset indent -compact
.It
Intentional: locks, mutexes, and condition variables.
.It
Accidental: unrelated and frequently modified data on the same cache-line.
.El
.El
.Sh RETURN VALUE
The
.Fn dispatch_benchmark
function returns the average number of nanoseconds the given block takes to
execute.
.Sh SEE ALSO
.Xr dispatch 3

View File

@@ -0,0 +1,220 @@
.\" Copyright (c) 2010-2012 Apple Inc. All rights reserved.
.Dd December 1, 2010
.Dt dispatch_data_create 3
.Os Darwin
.Sh NAME
.Nm dispatch_data_create ,
.Nm dispatch_data_create_concat ,
.Nm dispatch_data_create_subrange ,
.Nm dispatch_data_create_map ,
.Nm dispatch_data_apply ,
.Nm dispatch_data_copy_region ,
.Nm dispatch_data_get_size
.Nd create and manipulate dispatch data objects
.Sh SYNOPSIS
.Fd #include <dispatch/dispatch.h>
.Ft dispatch_data_t
.Fo dispatch_data_create
.Fa "const void* buffer"
.Fa "size_t size"
.Fa "dispatch_queue_t queue"
.Fa "dispatch_block_t destructor"
.Fc
.Ft dispatch_data_t
.Fo dispatch_data_create_concat
.Fa "dispatch_data_t data1"
.Fa "dispatch_data_t data2"
.Fc
.Ft dispatch_data_t
.Fo dispatch_data_create_subrange
.Fa "dispatch_data_t data"
.Fa "size_t offset"
.Fa "size_t length"
.Fc
.Ft dispatch_data_t
.Fo dispatch_data_create_map
.Fa "dispatch_data_t data"
.Fa "const void **buffer_ptr"
.Fa "size_t *size_ptr"
.Fc
.Ft bool
.Fo dispatch_data_apply
.Fa "dispatch_data_t data"
.Fa "bool (^applier)(dispatch_data_t, size_t, const void *, size_t)"
.Fc
.Ft dispatch_data_t
.Fo dispatch_data_copy_region
.Fa "dispatch_data_t data"
.Fa "size_t location"
.Fa "size_t *offset_ptr"
.Fc
.Ft size_t
.Fo dispatch_data_get_size
.Fa "dispatch_data_t data"
.Fc
.Vt dispatch_data_t dispatch_data_empty ;
.Sh DESCRIPTION
Dispatch data objects are opaque containers of bytes that represent one or more
regions of memory. They are created either from memory buffers managed by the
application or the system or from other dispatch data objects. Dispatch data
objects are immutable and the memory regions they represent are required to
remain unchanged for the lifetime of all data objects that reference them.
Dispatch data objects avoid copying the represented memory as much as possible.
Multiple data objects can represent the same memory regions or subsections
thereof.
.Sh CREATION
The
.Fn dispatch_data_create
function creates a new dispatch data object of given
.Fa size
from a
.Fa buffer .
The provided
.Fa destructor
block will be submitted to the specified
.Fa queue
when the object reaches the end of its lifecycle, indicating that the system no
longer references the
.Fa buffer .
This allows the application to deallocate
the associated storage. The
.Fa queue
argument is ignored if one of the following predefined destructors is passed:
.Bl -tag -width DISPATCH_DATA_DESTRUCTOR_DEFAULT -compact -offset indent
.It DISPATCH_DATA_DESTRUCTOR_FREE
indicates that the provided buffer can be deallocated with
.Xr free 3
directly.
.It DISPATCH_DATA_DESTRUCTOR_DEFAULT
indicates that the provided buffer is not managed by the application and should
be copied into memory managed and automatically deallocated by the system.
.El
.Pp
The
.Fn dispatch_data_create_concat
function creates a new data object representing the concatenation of the memory
regions represented by the provided data objects.
.Pp
The
.Fn dispatch_data_create_subrange
function creates a new data object representing the sub-region of the provided
.Fa data
object specified by the
.Fa offset
and
.Fa length
parameters.
.Pp
The
.Fn dispatch_data_create_map
function creates a new data object by mapping the memory represented by the
provided
.Fa data
object as a single contiguous memory region (moving or copying memory as
necessary). If the
.Fa buffer_ptr
and
.Fa size_ptr
references are not
.Dv NULL ,
they are filled with the location and extent of the contiguous region, allowing
direct read access to the mapped memory. These values are valid only as long as
the newly created object has not been released.
.Sh ACCESS
The
.Fn dispatch_data_apply
function provides read access to represented memory without requiring it to be
mapped as a single contiguous region. It traverses the memory regions
represented by the
.Fa data
argument in logical order, invokes the specified
.Fa applier
block for each region and returns a boolean indicating whether traversal
completed successfully. The
.Fa applier
block is passed the following arguments for each memory region and returns a
boolean indicating whether traversal should continue:
.Bl -tag -width "dispatch_data_t rgn" -compact -offset indent
.It Fa "dispatch_data_t rgn"
data object representing the region
.It Fa "size_t offset"
logical position of the region in
.Fa data
.It Vt "const void *loc"
memory location of the region
.It Vt "size_t size"
extent of the region
.El
The
.Fa rgn
data object is released by the system when the
.Fa applier
block returns.
The associated memory location
.Fa loc
is valid only as long as
.Fa rgn
has not been deallocated; if
.Fa loc
is needed outside of the
.Fa applier
block, the
.Fa rgn
object must be retained in the block.
.Pp
The
.Fn dispatch_data_copy_region
function finds the contiguous memory region containing the logical position
specified by the
.Fa location
argument among the regions represented by the provided
.Fa data
object and returns a newly created copy of the data object representing that
region. The variable specified by the
.Fa offset_ptr
argument is filled with the logical position where the returned object starts
in the
.Fa data
object.
.Pp
The
.Fn dispatch_data_get_size
function returns the logical size of the memory region or regions represented
by the provided
.Fa data
object.
.Sh EMPTY DATA OBJECT
The
.Vt dispatch_data_empty
object is the global singleton object representing a zero-length memory region.
It is a valid input to any dispatch_data functions that take data object
parameters.
.Sh MEMORY MODEL
Dispatch data objects are retained and released via calls to
.Fn dispatch_retain
and
.Fn dispatch_release .
Data objects passed as arguments to a dispatch data
.Sy create
or
.Sy copy
function can be released when the function returns. The newly created object
holds implicit references to their constituent memory regions as necessary.
.Pp
The functions
.Fn dispatch_data_create_map
and
.Fn dispatch_data_apply
return an interior pointer to represented memory that is only valid as long as
an associated object has not been released. When Objective-C Automated
Reference Counting is enabled, care needs to be taken if that object is held in
a variable with automatic storage. It may need to be annotated with the
.Li objc_precise_lifetime
attribute, or stored in a
.Li __strong
instance variable instead, to ensure that the object is not released
prematurely before memory accesses via the interor pointer have been completed.
.Sh SEE ALSO
.Xr dispatch 3 ,
.Xr dispatch_object 3 ,
.Xr dispatch_io_read 3

View File

@@ -0,0 +1,180 @@
.\" Copyright (c) 2008-2012 Apple Inc. All rights reserved.
.Dd May 1, 2009
.Dt dispatch_group_create 3
.Os Darwin
.Sh NAME
.Nm dispatch_group_create ,
.Nm dispatch_group_async ,
.Nm dispatch_group_wait ,
.Nm dispatch_group_notify
.Nd group blocks submitted to queues
.Sh SYNOPSIS
.Fd #include <dispatch/dispatch.h>
.Ft dispatch_group_t
.Fo dispatch_group_create
.Fa void
.Fc
.Ft void
.Fo dispatch_group_enter
.Fa "dispatch_group_t group"
.Fc
.Ft void
.Fo dispatch_group_leave
.Fa "dispatch_group_t group"
.Fc
.Ft long
.Fo dispatch_group_wait
.Fa "dispatch_group_t group" "dispatch_time_t timeout"
.Fc
.Ft void
.Fo dispatch_group_notify
.Fa "dispatch_group_t group" "dispatch_queue_t queue" "void (^block)(void)"
.Fc
.Ft void
.Fo dispatch_group_notify_f
.Fa "dispatch_group_t group" "dispatch_queue_t queue" "void *context" "void (*function)(void *)"
.Fc
.Ft void
.Fo dispatch_group_async
.Fa "dispatch_group_t group" "dispatch_queue_t queue" "void (^block)(void)"
.Fc
.Ft void
.Fo dispatch_group_async_f
.Fa "dispatch_group_t group" "dispatch_queue_t queue" "void *context" "void (*function)(void *)"
.Fc
.Sh DESCRIPTION
A dispatch group is an association of one or more blocks submitted to dispatch
queues for asynchronous invocation.
Applications may use dispatch groups to
wait for the completion of blocks associated with the group.
.Pp
The
.Fn dispatch_group_create
function returns a new and empty dispatch group.
.Pp
The
.Fn dispatch_group_enter
and
.Fn dispatch_group_leave
functions update the number of blocks running within a group.
.Pp
The
.Fn dispatch_group_wait
function waits until all blocks associated with the
.Fa group
have completed, or until the specified
.Fa timeout
has elapsed.
If the
.Fa group
becomes empty within the specified amount of time, the function will return zero
indicating success. Otherwise, a non-zero return code will be returned.
When
.Va DISPATCH_TIME_FOREVER
is passed as the
.Fa timeout ,
calls to this function will wait an unlimited amount of time until the group
becomes empty and the return value is always zero.
.Pp
The
.Fn dispatch_group_notify
function provides asynchronous notification of the completion of the blocks
associated with the
.Fa group
by submitting the
.Fa block
to the specified
.Fa queue
once all blocks associated with the
.Fa group
have completed.
The system holds a reference to the dispatch group while an asynchronous
notification is pending, therefore it is valid to release the
.Fa group
after setting a notification block.
The group will be empty at the time the notification block is submitted to the
target queue. The group may either be released with
.Fn dispatch_release
or reused for additional operations.
.Pp
The
.Fn dispatch_group_async
convenience function behaves like so:
.Bd -literal
void
dispatch_group_async(dispatch_group_t group, dispatch_queue_t queue, dispatch_block_t block)
{
dispatch_retain(group);
dispatch_group_enter(group);
dispatch_async(queue, ^{
block();
dispatch_group_leave(group);
dispatch_release(group);
});
}
.Ed
.Sh RETURN VALUE
The
.Fn dispatch_group_create
function returns NULL on failure and non-NULL on success.
.Pp
The
.Fn dispatch_group_wait
function returns zero upon success and non-zero after the timeout expires.
If the timeout is
.Va DISPATCH_TIME_FOREVER ,
then
.Fn dispatch_group_wait
waits forever and always returns zero.
.Sh MEMORY MODEL
Dispatch groups are retained and released via calls to
.Fn dispatch_retain
and
.Fn dispatch_release .
.Sh FUNDAMENTALS
The
.Fn dispatch_group_async
and
.Fn dispatch_group_notify
functions are wrappers around
.Fn dispatch_group_async_f
and
.Fn dispatch_group_notify_f
respectively.
.Sh CAVEATS
In order to ensure deterministic behavior, it is recommended to call
.Fn dispatch_group_wait
only once all blocks have been submitted to the group. If it is later
determined that new blocks should be run, it is recommended not to reuse an
already-running group, but to create a new group.
.Pp
.Fn dispatch_group_wait
returns as soon as there are exactly zero
.Em enqueued or running
blocks associated with a group (more precisely, as soon as every
.Fn dispatch_group_enter
call has been balanced by a
.Fn dispatch_group_leave
call). If one thread waits for a group while another thread submits
new blocks to the group, then the count of associated blocks might
momentarily reach zero before all blocks have been submitted. If this happens,
.Fn dispatch_group_wait
will return too early: some blocks associated with the group have finished,
but some have not yet been submitted or run.
.Pp
However, as a special case, a block associated with a group may submit new
blocks associated with its own group. In this case, the behavior is
deterministic: a waiting thread will
.Em not
wake up until the newly submitted blocks have also finished.
.Pp
All of the foregoing also applies to
.Fn dispath_group_notify
as well, with "block to be submitted" substituted for "waiting thread".
.Sh SEE ALSO
.Xr dispatch 3 ,
.Xr dispatch_async 3 ,
.Xr dispatch_object 3 ,
.Xr dispatch_queue_create 3 ,
.Xr dispatch_semaphore_create 3 ,
.Xr dispatch_time 3

View File

@@ -0,0 +1,282 @@
.\" Copyright (c) 2010-2013 Apple Inc. All rights reserved.
.Dd December 1, 2010
.Dt dispatch_io_create 3
.Os Darwin
.Sh NAME
.Nm dispatch_io_create ,
.Nm dispatch_io_create_with_path ,
.Nm dispatch_io_close ,
.Nm dispatch_io_set_high_water ,
.Nm dispatch_io_set_low_water ,
.Nm dispatch_io_set_interval ,
.Nm dispatch_io_barrier
.Nd open, close and configure dispatch I/O channels
.Sh SYNOPSIS
.Fd #include <dispatch/dispatch.h>
.Ft dispatch_io_t
.Fo dispatch_io_create
.Fa "dispatch_io_type_t type"
.Fa "int fd"
.Fa "dispatch_queue_t queue"
.Fa "void (^cleanup_handler)(int error)"
.Fc
.Ft dispatch_io_t
.Fo dispatch_io_create_with_path
.Fa "dispatch_io_type_t type"
.Fa "const char *path"
.Fa "int oflag"
.Fa "mode_t mode"
.Fa "dispatch_queue_t queue"
.Fa "void (^cleanup_handler)(int error)"
.Fc
.Ft void
.Fo dispatch_io_close
.Fa "dispatch_io_t channel"
.Fa "dispatch_io_close_flags_t flags"
.Fc
.Ft void
.Fo dispatch_io_set_high_water
.Fa "dispatch_io_t channel"
.Fa "size_t high_water"
.Fc
.Ft void
.Fo dispatch_io_set_low_water
.Fa "dispatch_io_t channel"
.Fa "size_t low_water"
.Fc
.Ft void
.Fo dispatch_io_set_interval
.Fa "dispatch_io_t channel"
.Fa "uint64_t interval"
.Fa "dispatch_io_interval_flags_t flags"
.Fc
.Ft void
.Fo dispatch_io_barrier
.Fa "dispatch_io_t channel"
.Fa "void (^barrier)(void)"
.Fc
.Sh DESCRIPTION
The dispatch I/O framework is an API for asynchronous read and write I/O
operations. It is an application of the ideas and idioms present in the
.Xr dispatch 3
framework to device I/O. Dispatch I/O enables an application to more easily
avoid blocking I/O operations and allows it to more directly express its I/O
requirements than by using the raw POSIX file API. Dispatch I/O will make a
best effort to optimize how and when asynchronous I/O operations are performed
based on the capabilities of the targeted device.
.Pp
This page provides details on how to create and configure dispatch I/O
channels. Reading from and writing to these channels is covered in the
.Xr dispatch_io_read 3
page. The dispatch I/O framework also provides the convenience functions
.Xr dispatch_read 3
and
.Xr dispatch_write 3
for uses that do not require the full functionality provided by I/O channels.
.Sh FUNDAMENTALS
A dispatch I/O channel represents the asynchronous I/O policy applied to a file
descriptor and encapsulates it for the purposes of ownership tracking while
I/O operations are ongoing.
.Sh CHANNEL TYPES
Dispatch I/O channels can have one of the following types:
.Bl -tag -width DISPATCH_IO_STREAM -compact -offset indent
.It DISPATCH_IO_STREAM
channels that represent a stream of bytes and do not support reads and writes
at arbitrary offsets, such as pipes or sockets. Channels of this type perform
read and write operations sequentially at the current file pointer position and
ignore any offset specified. Depending on the underlying file descriptor, read
operations may be performed simultaneously with write operations.
.It DISPATCH_IO_RANDOM
channels that represent random access files on disk. Only supported for
seekable file descriptors and paths. Channels of this type may perform
submitted read and write operations concurrently at the specified offset
(interpreted relative to the position of the file pointer when the channel was
created).
.El
.Sh CHANNEL OPENING AND CLOSING
The
.Fn dispatch_io_create
and
.Fn dispatch_io_create_with_path
functions create a dispatch I/O channel of provided
.Fa type
from a file descriptor
.Fa fd
or an absolute pathname, respectively. They can be thought of as analogous to
the
.Xr fdopen 3
POSIX function and the
.Xr fopen 3
function in the standard C library. For a channel created from a pathname, the
provided
.Fa path ,
.Fa oflag
and
.Fa mode
parameters will be passed to
.Xr open 2
when the first I/O operation on the channel is ready to execute.
.Pp
The provided
.Fa cleanup_handler
block will be submitted to the specified
.Fa queue
when all I/O operations on the channel have completed and it is closed or
reaches the end of its lifecycle. If an error occurs during channel creation,
the
.Fa cleanup_handler
block will be submitted immediately and passed an
.Fa error
parameter with the POSIX error encountered. If an invalid
.Fa type
or a non-absolute
.Fa path
argument is specified, these functions will return NULL and the
.Fa cleanup_handler
will not be invoked. After successfully creating a dispatch I/O channel from a
file descriptor, the application must take care not to modify that file
descriptor until the associated
.Fa cleanup_handler
is invoked, see
.Sx "FILEDESCRIPTOR OWNERSHIP"
for details.
.Pp
The
.Fn dispatch_io_close
function closes a dispatch I/O channel to new submissions of I/O operations. If
.Dv DISPATCH_IO_STOP
is passed in the
.Fa flags
parameter, the system will in addition not perform the I/O operations already
submitted to the channel that are still pending and will make a best effort to
interrupt any ongoing operations. Handlers for operations so affected will be
passed the
.Er ECANCELED
error code, along with any partial results.
.Sh CHANNEL CONFIGURATION
Dispatch I/O channels have high-water mark, low-water mark and interval
configuration settings that determine if and when partial results from I/O
operations are delivered via their associated I/O handlers.
.Pp
The
.Fn dispatch_io_set_high_water
and
.Fn dispatch_io_set_low_water
functions configure the water mark settings of a
.Fa channel .
The system will read
or write at least the number of bytes specified by
.Fa low_water
before submitting an I/O handler with partial results, and will make a best
effort to submit an I/O handler as soon as the number of bytes read or written
reaches
.Fa high_water .
.Pp
The
.Fn dispatch_io_set_interval
function configures the time
.Fa interval
at which I/O handlers are submitted (measured in nanoseconds). If
.Dv DISPATCH_IO_STRICT_INTERVAL
is passed in the
.Fa flags
parameter, the interval will be strictly observed even if there is an
insufficient amount of data to deliver; otherwise delivery will be skipped for
intervals where the amount of available data is inferior to the channel's
low-water mark. Note that the system may defer enqueueing interval I/O handlers
by a small unspecified amount of leeway in order to align with other system
activity for improved system performance or power consumption.
.Pp
.Sh DATA DELIVERY
The size of data objects passed to I/O handlers for a channel will never be
larger than the high-water mark set on the channel; it will also never be
smaller than the low-water mark, except in the following cases:
.Bl -dash -offset indent -compact
.It
the final handler invocation for an I/O operation
.It
EOF was encountered
.It
the channel has an interval with the
.Dv DISPATCH_IO_STRICT_INTERVAL
flag set
.El
Bear in mind that dispatch I/O channels will typically deliver amounts of data
significantly higher than the low-water mark. The default value for the
low-water mark is unspecified, but must be assumed to allow intermediate
handler invocations. The default value for the high-water mark is
unlimited (i.e.\&
.Dv SIZE_MAX ) .
Channels that require intermediate results of fixed size should have both the
low-water and the high-water mark set to that size. Channels that do not wish
to receive any intermediate results should have the low-water mark set to
.Dv SIZE_MAX .
.Pp
.Sh FILEDESCRIPTOR OWNERSHIP
When an application creates a dispatch I/O channel from a file descriptor with
the
.Fn dispatch_io_create
function, the system takes control of that file descriptor until the channel is
closed, an error occurs on the file descriptor or all references to the channel
are released. At that time the channel's cleanup handler will be enqueued and
control over the file descriptor relinquished, making it safe for the
application to
.Xr close 2
the file descriptor. While a file descriptor is under the control of a dispatch
I/O channel, file descriptor flags such as
.Dv O_NONBLOCK
will be modified by the system on behalf of the application. It is an error for
the application to modify a file descriptor directly while it is under the
control of a dispatch I/O channel, but it may create further I/O channels
from that file descriptor or use the
.Xr dispatch_read 3
and
.Xr dispatch_write 3
convenience functions with that file descriptor. If multiple I/O channels have
been created from the same file descriptor, all the associated cleanup handlers
will be submitted together once the last channel has been closed resp.\& all
references to those channels have been released. If convenience functions have
also been used on that file descriptor, submission of their handlers will be
tied to the submission of the channel cleanup handlers as well.
.Pp
.Sh BARRIER OPERATIONS
The
.Fn dispatch_io_barrier
function schedules a barrier operation on an I/O channel. The specified barrier
block will be run once, after all current I/O operations (such as
.Xr read 2 or
.Xr write 2 )
on the underlying
file descriptor have finished. No new I/O operations will start until the
barrier block finishes.
.Pp
The barrier block may operate on the underlying file descriptor with functions
like
.Xr fsync 2
or
.Xr lseek 2 .
As discussed in the
.Sx FILEDESCRIPTOR OWNERSHIP
section, the barrier block must not
.Xr close 2
the file descriptor, and if it changes any flags on the file descriptor, it
must restore them before finishing.
.Pp
There is no synchronization between a barrier block and any
.Xr dispatch_io_read 3
or
.Xr dispatch_io_write 3
handler blocks; they may be running at the same time. The barrier block itself
is responsible for any required synchronization.
.Sh MEMORY MODEL
Dispatch I/O channel objects are retained and released via calls to
.Fn dispatch_retain
and
.Fn dispatch_release .
.Sh SEE ALSO
.Xr dispatch 3 ,
.Xr dispatch_io_read 3 ,
.Xr dispatch_object 3 ,
.Xr dispatch_read 3 ,
.Xr fopen 3 ,
.Xr open 2

View File

@@ -0,0 +1,151 @@
.\" Copyright (c) 2010 Apple Inc. All rights reserved.
.Dd December 1, 2010
.Dt dispatch_io_read 3
.Os Darwin
.Sh NAME
.Nm dispatch_io_read ,
.Nm dispatch_io_write
.Nd submit read and write operations to dispatch I/O channels
.Sh SYNOPSIS
.Fd #include <dispatch/dispatch.h>
.Ft void
.Fo dispatch_io_read
.Fa "dispatch_io_t channel"
.Fa "off_t offset"
.Fa "size_t length"
.Fa "dispatch_queue_t queue"
.Fa "void (^handler)(bool done, dispatch_data_t data, int error)"
.Fc
.Ft void
.Fo dispatch_io_write
.Fa "dispatch_io_t channel"
.Fa "off_t offset"
.Fa "dispatch_data_t data"
.Fa "dispatch_queue_t queue"
.Fa "void (^handler)(bool done, dispatch_data_t data, int error)"
.Fc
.Sh DESCRIPTION
The dispatch I/O framework is an API for asynchronous read and write I/O
operations. It is an application of the ideas and idioms present in the
.Xr dispatch 3
framework to device I/O. Dispatch I/O enables an application to more easily
avoid blocking I/O operations and allows it to more directly express its I/O
requirements than by using the raw POSIX file API. Dispatch I/O will make a
best effort to optimize how and when asynchronous I/O operations are performed
based on the capabilities of the targeted device.
.Pp
This page provides details on how to read from and write to dispatch I/O
channels. Creation and configuration of these channels is covered in the
.Xr dispatch_io_create 3
page. The dispatch I/O framework also provides the convenience functions
.Xr dispatch_read 3
and
.Xr dispatch_write 3
for uses that do not require the full functionality provided by I/O channels.
.Pp
.Sh FUNDAMENTALS
The
.Fn dispatch_io_read
and
.Fn dispatch_io_write
functions are used to perform asynchronous read and write operations on
dispatch I/O channels. They can be thought of as asynchronous versions of the
.Xr fread 3
and
.Xr fwrite 3
functions in the standard C library.
.Sh READ OPERATIONS
The
.Fn dispatch_io_read
function schedules an I/O read operation on the specified dispatch I/O
.Va channel .
As results from the read operation become available, the provided
.Va handler
block will be submitted to the specified
.Va queue .
The block will be passed a dispatch data object representing the data that has
been read since the handler's previous invocation.
.Pp
The
.Va offset
parameter indicates where the read operation should begin. For a channel of
.Dv DISPATCH_IO_RANDOM
type it is interpreted relative to the position of the file pointer when the
channel was created, for a channel of
.Dv DISPATCH_IO_STREAM
type it is ignored and the read operation will begin at the current file
pointer position.
.Pp
The
.Va length
parameter indicates the number of bytes that should be read from the I/O
channel. Pass
.Dv SIZE_MAX
to keep reading until EOF is encountered (for a channel created from a
disk-based file this happens when reading past the end of the physical file).
.Sh WRITE OPERATIONS
The
.Fn dispatch_io_write
function schedules an I/O write operation on the specified dispatch I/O
.Va channel .
As the write operation progresses, the provided
.Va handler
block will be submitted to the specified
.Va queue .
The block will be passed a dispatch data object representing the data that
remains to be written as part of this I/O operation.
.Pp
The
.Va offset
parameter indicates where the write operation should begin. It is interpreted
as for read operations above.
.Pp
The
.Va data
parameter specifies the location and amount of data to be written, encapsulated
as a dispatch data object. The object is retained by the system until the write
operation is complete.
.Sh I/O HANDLER BLOCKS
Dispatch I/O handler blocks submitted to a channel via the
.Fn dispatch_io_read
or
.Fn dispatch_io_write
functions will be executed one or more times depending on system load and the
channel's configuration settings (see
.Xr dispatch_io_create 3
for details). The handler block need not be reentrant safe,
no new I/O handler instance is submitted until the previously enqueued handler
block has returned.
.Pp
The dispatch
.Va data
object passed to an I/O handler block will be released by the system when the
block returns, if access to the memory buffer it represents is needed outside
of the handler, the handler block must retain the data object or create a new
(e.g.\& concatenated) data object from it (see
.Xr dispatch_data_create 3
for details).
.Pp
Once an I/O handler block is invoked with the
.Va done
flag set, the associated I/O operation is complete and that handler block will
not be run again. If an unrecoverable error occurs while performing the I/O
operation, the handler block will be submitted with the
.Va done
flag set and the appropriate POSIX error code in the
.Va error
parameter. An invocation of a handler block with the
.Va done
flag set, zero
.Va error
and
.Va data
set to
.Vt dispatch_data_empty
indicates that the I/O operation has encountered EOF.
.Sh SEE ALSO
.Xr dispatch 3 ,
.Xr dispatch_data_create 3 ,
.Xr dispatch_io_create 3 ,
.Xr dispatch_read 3 ,
.Xr fread 3

View File

@@ -0,0 +1,190 @@
.\" Copyright (c) 2008-2012 Apple Inc. All rights reserved.
.Dd March 1, 2012
.Dt dispatch_object 3
.Os Darwin
.Sh NAME
.Nm dispatch_object
.Nd General manipulation of dispatch objects
.Sh SYNOPSIS
.Fd #include <dispatch/dispatch.h>
.Ft void
.Fo dispatch_retain
.Fa "dispatch_object_t object"
.Fc
.Ft void
.Fo dispatch_release
.Fa "dispatch_object_t object"
.Fc
.Ft void
.Fo dispatch_suspend
.Fa "dispatch_object_t object"
.Fc
.Ft void
.Fo dispatch_resume
.Fa "dispatch_object_t object"
.Fc
.Ft void
.Fo dispatch_activate
.Fa "dispatch_object_t object"
.Fc
.Ft "void *"
.Fo dispatch_get_context
.Fa "dispatch_object_t object"
.Fc
.Ft void
.Fo dispatch_set_context
.Fa "dispatch_object_t object"
.Fa "void *context"
.Fc
.Ft void
.Fo dispatch_set_finalizer_f
.Fa "dispatch_object_t object"
.Fa "dispatch_function_t finalizer"
.Fc
.Sh DESCRIPTION
Dispatch objects share functions for coordinating memory management, suspension,
cancellation and context pointers.
.Sh MEMORY MANAGEMENT
Objects returned by creation functions in the dispatch framework may be
uniformly retained and released with the functions
.Fn dispatch_retain
and
.Fn dispatch_release
respectively.
.Pp
The dispatch framework does not guarantee that any given client has the last or
only reference to a given object. Objects may be retained internally by the
system.
.Ss INTEGRATION WITH OBJECTIVE-C
.Bd -filled -offset indent
When building with an Objective-C or Objective-C++ compiler, dispatch objects
are declared as Objective-C types. This results in the following differences
compared to building as plain C/C++:
.Bl -dash
.It
if Objective-C Automated Reference Counting is enabled, dispatch objects are
memory managed by the Objective-C runtime and explicit calls to the
.Fn dispatch_retain
and
.Fn dispatch_release
functions will produce build errors.
.Pp
.Em Note :
when ARC is enabled, care needs to be taken with dispatch API returning an
interior pointer that is only valid as long as an associated object has not
been released. If that object is held in a variable with automatic storage, it
may need to be annotated with the
.Li objc_precise_lifetime
attribute, or stored in a
.Li __strong
instance variable instead, to ensure that the object is not prematurely
released. The functions returning interior pointers are
.Xr dispatch_data_create_map 3
and
.Xr dispatch_data_apply 3 .
.It
the Blocks runtime automatically retains and releases dispatch objects captured
by blocks upon
.Fn Block_copy
and
.Fn Block_release ,
e.g.\& as performed during asynchronous execution of a block via
.Xr dispatch_async 3 .
.Pp
.Em Note :
retain cycles may be encountered if dispatch source objects are captured by
their handler blocks; these cycles can be broken by declaring the captured
object
.Li __weak
or by calling
.Xr dispatch_source_cancel 3
to cause its handler blocks to be released explicitly.
.It
dispatch objects can be added directly to Cocoa collections, and their
lifetime is tracked by the Objective-C static analyzer.
.El
.Pp
Integration of dispatch objects with Objective-C requires targeting Mac\ OS\ X
10.8 or later, and is disabled when building for the legacy Objective-C runtime.
It can also be disabled manually by using compiler options to define the
.Dv OS_OBJECT_USE_OBJC
preprocessor macro to
.Li 0 .
.Ed
.Pp
.Em Important :
When building with a plain C/C++ compiler or when integration with Objective-C
is disabled, dispatch objects are
.Em not
automatically retained and released when captured by a block. Therefore, when a
dispatch object is captured by a block that will be executed asynchronously,
the object must be manually retained and released:
.Pp
.Bd -literal -offset indent
dispatch_retain(object);
dispatch_async(queue, ^{
do_something_with_object(object);
dispatch_release(object);
});
.Ed
.Sh ACTIVATION
Dispatch objects such as queues and sources may be created in an inactive
state. Objects in this state must be activated before any blocks
associated with them will be invoked. Calling
.Fn dispatch_activate
on an active object has no effect.
.Pp
Changing attributes such as the target queue or a source handler is no longer permitted
once the object has been activated (see
.Xr dispatch_set_target_queue 3 ,
.Xr dispatch_source_set_event_handler 3 ).
.Sh SUSPENSION
The invocation of blocks on dispatch queues or dispatch sources may be suspended
or resumed with the functions
.Fn dispatch_suspend
and
.Fn dispatch_resume
respectively. Other dispatch objects do not support suspension.
.Pp
The dispatch framework always checks the suspension status before executing a
block, but such changes never affect a block during execution (non-preemptive).
Therefore the suspension of an object is asynchronous, unless it is performed
from the context of the target queue for the given object.
The result of suspending or resuming an object that is not a dispatch queue or
a dispatch source is undefined.
.Pp
.Em Important :
suspension applies to all aspects of the dispatch object life cycle, including
the finalizer function and cancellation handler. Suspending an object causes it
to be retained and resuming an object causes it to be released. Therefore it is
important to balance calls to
.Fn dispatch_suspend
and
.Fn dispatch_resume
such that the dispatch object is fully resumed when the last reference is
released. The result of releasing all references to a dispatch object while in
an inactive or suspended state is undefined.
.Sh CONTEXT POINTERS
Dispatch objects support supplemental context pointers. The value of the
context pointer may be retrieved and updated with
.Fn dispatch_get_context
and
.Fn dispatch_set_context
respectively.
The
.Fn dispatch_set_finalizer_f
specifies an optional per-object finalizer function that is invoked
asynchronously if the context pointer is not NULL when the last
reference to the object is released.
This gives the
application an opportunity to free the context data associated with the object.
The finalizer will be run on the object's target queue.
.Sh SEE ALSO
.Xr dispatch 3 ,
.Xr dispatch_async 3 ,
.Xr dispatch_group_create 3 ,
.Xr dispatch_queue_create 3 ,
.Xr dispatch_semaphore_create 3 ,
.Xr dispatch_set_target_queue 3 ,
.Xr dispatch_source_cancel 3 ,
.Xr dispatch_source_create 3

View File

@@ -0,0 +1,46 @@
.\" Copyright (c) 2008-2009 Apple Inc. All rights reserved.
.Dd May 1, 2009
.Dt dispatch_once 3
.Os Darwin
.Sh NAME
.Nm dispatch_once
.Nd execute a block only once
.Sh SYNOPSIS
.Fd #include <dispatch/dispatch.h>
.Ft void
.Fo dispatch_once
.Fa "dispatch_once_t *predicate" "void (^block)(void)"
.Fc
.Ft void
.Fo dispatch_once_f
.Fa "dispatch_once_t *predicate" "void *context" "void (*function)(void *)"
.Fc
.Sh DESCRIPTION
The
.Fn dispatch_once
function provides a simple and efficient mechanism to run an initializer
exactly once, similar to
.Xr pthread_once 3 .
Well designed code hides the use of lazy initialization.
For example:
.Bd -literal
FILE *getlogfile(void)
{
static dispatch_once_t pred;
static FILE *logfile;
dispatch_once(&pred, ^{
logfile = fopen(MY_LOG_FILE, "a");
});
return logfile;
}
.Ed
.Pp
.Sh FUNDAMENTALS
The
.Fn dispatch_once
function is a wrapper around
.Fn dispatch_once_f .
.Sh SEE ALSO
.Xr dispatch 3

View File

@@ -0,0 +1,371 @@
.\" Copyright (c) 2008-2012 Apple Inc. All rights reserved.
.Dd May 1, 2008
.Dt dispatch_queue_create 3
.Os Darwin
.Sh NAME
.Nm dispatch_queue_create ,
.Nm dispatch_queue_get_label ,
.Nm dispatch_get_current_queue ,
.Nm dispatch_get_global_queue ,
.Nm dispatch_get_main_queue ,
.Nm dispatch_main ,
.Nm dispatch_set_target_queue
.Nd where blocks are scheduled for execution
.Sh SYNOPSIS
.Fd #include <dispatch/dispatch.h>
.Ft dispatch_queue_t
.Fo dispatch_queue_create
.Fa "const char *label" "dispatch_queue_attr_t attr"
.Fc
.Ft "const char *"
.Fo dispatch_queue_get_label
.Fa "dispatch_queue_t queue"
.Fc
.Ft dispatch_queue_t
.Fo dispatch_get_global_queue
.Fa "long priority"
.Fa "unsigned long flags"
.Fc
.Ft dispatch_queue_t
.Fo dispatch_get_main_queue
.Fa void
.Fc
.Ft void
.Fo dispatch_main
.Fa void
.Fc
.Ft void
.Fo dispatch_set_target_queue
.Fa "dispatch_object_t object"
.Fa "dispatch_queue_t target"
.Fc
.Sh DESCRIPTION
Queues are the fundamental mechanism for scheduling blocks for execution within
the
.Xr dispatch 3
framework.
.Pp
All blocks submitted to dispatch queues are dequeued in FIFO order.
Queues created with the
.Dv DISPATCH_QUEUE_SERIAL
attribute wait for the previously dequeued block to complete before dequeuing
the next block. A queue with this FIFO completion behavior is usually simply
described as a "serial queue." All memory writes performed by a block dispatched
to a serial queue are guaranteed to be visible to subsequent blocks dispatched
to the same queue. Queues are not bound to any specific thread of execution and
blocks submitted to independent queues may execute concurrently.
.Pp
Queues created with the
.Dv DISPATCH_QUEUE_CONCURRENT
attribute may execute dequeued blocks concurrently and support barrier blocks
submitted with the dispatch barrier API.
.Sh CREATION
Queues are created with the
.Fn dispatch_queue_create
function. Queues, like all dispatch objects, are reference counted and newly
created queues have a reference count of one.
.Pp
The optional
.Fa label
argument is used to describe the purpose of the queue and is useful during
debugging and performance analysis. If a label is provided, it is copied.
By convention, clients should pass a reverse DNS style label. For example:
.Pp
.Bd -literal -offset indent
my_queue = dispatch_queue_create("com.example.subsystem.taskXYZ",
DISPATCH_QUEUE_SERIAL);
.Ed
.Pp
The
.Fa attr
argument specifies the type of queue to create and must be either
.Dv DISPATCH_QUEUE_SERIAL
or
.Dv DISPATCH_QUEUE_CONCURRENT .
.Pp
The
.Fn dispatch_queue_get_label
function returns the label provided when the given
.Fa queue
was created (or an empty C string if no label was provided at creation).
Passing the constant
.Dv DISPATCH_CURRENT_QUEUE_LABEL
to
.Fn dispatch_queue_get_label
returns the label of the current queue.
.Sh SUSPENSION
Queues may be temporarily suspended and resumed with the functions
.Fn dispatch_suspend
and
.Fn dispatch_resume
respectively. Suspension is checked prior to block execution and is
.Em not
preemptive.
.Sh MAIN QUEUE
The dispatch framework provides a default serial queue for the application to
use. This queue is accessed via the
.Fn dispatch_get_main_queue
function.
.Pp
Programs must call
.Fn dispatch_main
at the end of
.Fn main
in order to process blocks submitted to the main queue. (See the
.Sx COMPATIBILITY
section for exceptions.) The
.Fn dispatch_main
function never returns.
.Sh GLOBAL CONCURRENT QUEUES
Unlike the main queue or queues allocated with
.Fn dispatch_queue_create ,
the global concurrent queues schedule blocks as soon as threads become
available (non-FIFO completion order). Four global concurrent queues are
provided, representing the following priority bands:
.Bl -bullet -compact -offset indent
.It
DISPATCH_QUEUE_PRIORITY_HIGH
.It
DISPATCH_QUEUE_PRIORITY_DEFAULT
.It
DISPATCH_QUEUE_PRIORITY_LOW
.It
DISPATCH_QUEUE_PRIORITY_BACKGROUND
.El
.Pp
The priority of a global concurrent queue controls the scheduling priority of
the threads created by the system to invoke the blocks submitted to that queue.
Global queues with lower priority will be scheduled for execution after all
global queues with higher priority have been scheduled. Additionally, items on
the background priority global queue will execute on threads with background
state as described in
.Xr setpriority 2
(i.e.\& disk I/O is throttled and the thread's scheduling priority is set to
lowest value).
.Pp
Use the
.Fn dispatch_get_global_queue
function to obtain the global queue of given priority. The
.Fa flags
argument is reserved for future use and must be zero. Passing any value other
than zero may result in a NULL return value.
.Sh TARGET QUEUE
The
.Fn dispatch_set_target_queue
function updates the target queue of the given dispatch object. The target
queue of an object is responsible for processing the object.
.Pp
The new target queue is retained by the given object before the previous target
queue is released. The new target queue setting will take effect between block
executions on the object, but not in the middle of any existing block executions
(non-preemptive).
.Pp
The default target queue of all dispatch objects created by the application is
the default priority global concurrent queue. To reset an object's target queue
to the default, pass the
.Dv DISPATCH_TARGET_QUEUE_DEFAULT
constant to
.Fn dispatch_set_target_queue .
.Pp
The priority of a dispatch queue is inherited from its target queue.
In order to change the priority of a queue created with
.Fn dispatch_queue_create ,
use the
.Fn dispatch_get_global_queue
function to obtain a target queue of the desired priority.
.Pp
Blocks submitted to a serial queue whose target queue is another serial queue
will not be invoked concurrently with blocks submitted to the target queue or
to any other queue with that same target queue.
.Pp
The target queue of a dispatch source specifies where its event handler and
cancellation handler blocks will be submitted. See
.Xr dispatch_source_create 3
for more information about dispatch sources.
.Pp
The target queue of a dispatch I/O channel specifies the priority of the global
queue where its I/O operations are executed. See
.Xr dispatch_io_create 3
for more information about dispatch I/O channels.
.Pp
For all other dispatch object types, the only function of the target queue is
to determine where an object's finalizer function is invoked.
.Pp
The result of passing the main queue or a global concurrent queue as the first
argument of
.Fn dispatch_set_target_queue
is undefined.
.Pp
Directly or indirectly setting the target queue of a dispatch queue to itself is
undefined.
.Sh DEPRECATED FUNCTIONS
The following functions are deprecated and will be removed in a future release:
.Bl -item
.It
.Ft dispatch_queue_t
.Fn dispatch_get_current_queue void ;
.El
.Pp
.Fn dispatch_get_current_queue
always returns a valid queue. When called from within a block
submitted to a dispatch queue, that queue will be returned. If this function is
called from the main thread before
.Fn dispatch_main
is called, then the result of
.Fn dispatch_get_main_queue
is returned. In all other cases, the default target queue will be returned.
.Pp
The use of
.Fn dispatch_get_current_queue
is strongly discouraged except for debugging and logging purposes. Code must not
make any assumptions about the queue returned, unless it is one of the global
queues or a queue the code has itself created. The returned queue may have
arbitrary policies that may surprise code that tries to schedule work with the
queue. The list of policies includes, but is not limited to, queue width (i.e.
serial vs. concurrent), scheduling priority, security credential or filesystem
configuration. This function is deprecated and will be removed in a future
release.
.Pp
It is equally unsafe for code to assume that synchronous execution onto a queue
is safe from deadlock if that queue is not the one returned by
.Fn dispatch_get_current_queue .
.Pp
The result of
.Fn dispatch_get_main_queue
may or may not equal the result of
.Fn dispatch_get_current_queue
when called on the main thread. Comparing the two is not a valid way to test
whether code is executing on the main thread. Foundation/AppKit programs should
use [NSThread isMainThread]. POSIX programs may use
.Xr pthread_main_np 3 .
.Pp
.Fn dispatch_get_current_queue
may return a queue owned by a different subsystem which has already had all
external references to it released. While such a queue will continue to exist
until all blocks submitted to it have completed, attempting to retain it is
forbidden and will trigger an assertion. If Objective-C Automatic Reference
Counting is enabled, any use of the object returned by
.Fn dispatch_get_current_queue
will cause retain calls to be automatically generated, so the use of
.Fn dispatch_get_current_queue
for any reason in code built with ARC is particularly strongly discouraged.
.Sh COMPATIBILITY
Cocoa applications need not call
.Fn dispatch_main .
Blocks submitted to the main queue will be executed as part of the "common
modes" of the application's main NSRunLoop or CFRunLoop.
However, blocks submitted to the main queue in applications using
.Fn dispatch_main
are not guaranteed to execute on the main thread.
.Pp
The dispatch framework is a pure C level API. As a result, it does not catch
exceptions generated by higher level languages such as Objective-C or C++.
Applications
.Em MUST
catch all exceptions before returning from a block submitted to a dispatch
queue; otherwise the process will be terminated with an uncaught exception.
.Pp
The dispatch framework manages the relationship between dispatch queues and
threads of execution. As a result, applications
.Em MUST NOT
delete or mutate objects that they did not create. The following interfaces
.Em MUST NOT
be called by blocks submitted to a dispatch queue:
.Bl -bullet -offset indent
.It
.Fn pthread_cancel
.It
.Fn pthread_detach
.It
.Fn pthread_join
.It
.Fn pthread_kill
.It
.Fn pthread_exit
.El
.Pp
Applications
.Em MAY
call the following interfaces from a block submitted to a dispatch queue if
and only if they restore the thread to its original state before returning:
.Bl -bullet -offset indent
.It
.Fn pthread_setcancelstate
.It
.Fn pthread_setcanceltype
.It
.Fn pthread_setschedparam
.It
.Fn pthread_sigmask
.It
.Fn pthread_setugid_np
.El
.Pp
Applications
.Em MUST NOT
rely on the following interfaces returning predictable results between
invocations of blocks submitted to a dispatch queue:
.Bl -bullet -offset indent
.It
.Fn pthread_self
.It
.Fn pthread_getschedparam
.It
.Fn pthread_get_stacksize_np
.It
.Fn pthread_get_stackaddr_np
.It
.Fn pthread_mach_thread_np
.It
.Fn pthread_from_mach_thread_np
.El
.Pp
While the result of
.Fn pthread_self
may change between invocations of blocks, the value will not change during the
execution of any single block. Because the underlying thread may change beteween
block invocations on a single queue, using per-thread data as an out-of-band
return value is error prone. In other words, the result of calling
.Fn pthread_setspecific
and
.Fn pthread_getspecific
is well defined within a signle block, but not across multiple blocks. Also,
one cannot make any assumptions about when the destructor passed to
.Fn pthread_key_create
is called. The destructor may be called between the invocation of blocks on
the same queue, or during the idle state of a process.
.Pp
The following example code correctly handles per-thread return values:
.Bd -literal -offset indent
__block int r;
__block int e;
dispatch_sync(queue, ^{
r = kill(1, 0);
// Copy the per-thread return value to the callee thread
e = errno;
});
printf("kill(1,0) returned %d and errno %d\n", r, e);
.Ed
.Pp
Note that in the above example
.Va errno
is a per-thread variable and must be copied out explicitly as the block may be
invoked on different thread of execution than the caller. Another example of
per-thread data that would need to be copied is the use of
.Fn getpwnam
instead of
.Fn getpwnam_r .
.Pp
As an optimization,
.Fn dispatch_sync
invokes the block on the current thread when possible. In this case, the thread
specific data such as
.Va errno
may persist from the block until back to the caller. Great care should be taken
not to accidentally rely on this side-effect.
.Pp
.Sh SEE ALSO
.Xr dispatch 3 ,
.Xr dispatch_async 3 ,
.Xr dispatch_object 3 ,
.Xr dispatch_source_create 3

View File

@@ -0,0 +1,123 @@
.\" Copyright (c) 2010 Apple Inc. All rights reserved.
.Dd December 1, 2010
.Dt dispatch_read 3
.Os Darwin
.Sh NAME
.Nm dispatch_read ,
.Nm dispatch_write
.Nd asynchronously read from and write to file descriptors
.Sh SYNOPSIS
.Fd #include <dispatch/dispatch.h>
.Ft void
.Fo dispatch_read
.Fa "int fd"
.Fa "size_t length"
.Fa "dispatch_queue_t queue"
.Fa "void (^handler)(dispatch_data_t data, int error)"
.Fc
.Ft void
.Fo dispatch_write
.Fa "int fd"
.Fa "dispatch_data_t data"
.Fa "dispatch_queue_t queue"
.Fa "void (^handler)(dispatch_data_t data, int error))"
.Fc
.Sh DESCRIPTION
The
.Fn dispatch_read
and
.Fn dispatch_write
functions asynchronously read from and write to POSIX file descriptors. They
can be thought of as asynchronous, callback-based versions of the
.Fn fread
and
.Fn fwrite
functions provided by the standard C library. They are convenience functions
based on the
.Xr dispatch_io_read 3
and
.Xr dispatch_io_write 3
functions, intended for simple one-shot read or write requests. Multiple
request on the same file desciptor are better handled with the full underlying
dispatch I/O channel functions.
.Sh BEHAVIOR
The
.Fn dispatch_read
function schedules an asynchronous read operation on the file descriptor
.Va fd .
Once the file descriptor is readable, the system will read as much data as is
currently available, up to the specified
.Va length ,
starting at the current file pointer position. The given
.Va handler
block will be submitted to
.Va queue
when the operation completes or an error occurs. The block will be passed a
dispatch
.Va data
object with the result of the read operation. If an error occurred while
reading from the file descriptor, the
.Va error
parameter to the block will be set to the appropriate POSIX error code and
.Va data
will contain any data that could be read successfully. If the file pointer
position is at end-of-file, emtpy
.Va data
and zero
.Va error
will be passed to the handler block.
.Pp
The
.Fn dispatch_write
function schedules an asynchronous write operation on the file descriptor
.Va fd .
The system will attempt to write the entire contents of the provided
.Va data
object to
.Va fd
at the current file pointer position. The given
.Va handler
block will be submitted to
.Va queue
when the operation completes or an error occurs. If the write operation
completed successfully, the
.Va error
parameter to the block will be set to zero, otherwise it will be set to the
appropriate POSIX error code and the
.Va data
parameter will contain any data that could not be written.
.Sh CAVEATS
The
.Va data
object passed to a
.Va handler
block is released by the system when the block returns. If
.Va data
is needed outside of the handler block, it must concatenate, copy, or retain
it.
.Pp
Once an asynchronous read or write operation has been submitted on a file
descriptor
.Va fd ,
the system takes control of that file descriptor until the
.Va handler
block is executed. During this time the application must not manipulate
.Va fd
directly, in particular it is only safe to close
.Va fd
from the handler block (or after it has returned).
.Pp
If multiple asynchronous read or write operations are submitted to the same
file descriptor, they will be performed in order, but their handlers will only
be submitted once all operations have completed and control over the file
descriptor has been relinquished. For details on this and on the interaction
with dispatch I/O channels created from the same file descriptor, see
.Sx FILEDESCRIPTOR OWNERSHIP
in
.Xr dispatch_io_create 3 .
.Sh SEE ALSO
.Xr dispatch 3 ,
.Xr dispatch_data_create 3 ,
.Xr dispatch_io_create 3 ,
.Xr dispatch_io_read 3 ,
.Xr fread 3

View File

@@ -0,0 +1,121 @@
.\" Copyright (c) 2008-2012 Apple Inc. All rights reserved.
.Dd May 1, 2009
.Dt dispatch_semaphore_create 3
.Os Darwin
.Sh NAME
.Nm dispatch_semaphore_create ,
.Nm dispatch_semaphore_signal ,
.Nm dispatch_semaphore_wait
.Nd synchronized counting semaphore
.Sh SYNOPSIS
.Fd #include <dispatch/dispatch.h>
.Ft dispatch_semaphore_t
.Fo dispatch_semaphore_create
.Fa "long count"
.Fc
.Ft long
.Fo dispatch_semaphore_signal
.Fa "dispatch_semaphore_t semaphore"
.Fc
.Ft long
.Fo dispatch_semaphore_wait
.Fa "dispatch_semaphore_t semaphore" "dispatch_time_t timeout"
.Fc
.Sh DESCRIPTION
Dispatch semaphores are used to synchronize threads.
.Pp
The
.Fn dispatch_semaphore_wait
function decrements the semaphore. If the resulting value is less than zero,
it waits for a signal from a thread that increments the semaphore by calling
.Fn dispatch_semaphore_signal
before returning.
The
.Fa timeout
parameter is creatable with the
.Xr dispatch_time 3
or
.Xr dispatch_walltime 3
functions. If the timeout is reached without a signal being received, the semaphore
is re-incremented before the function returns.
.Pp
The
.Fn dispatch_semaphore_signal
function increments the counting semaphore. If the previous value was less than zero,
it wakes one of the threads that are waiting in
.Fn dispatch_semaphore_wait
before returning.
.Sh COMPLETION SYNCHRONIZATION
If the
.Fa count
parameter is equal to zero, then the semaphore is useful for synchronizing
completion of work.
For example:
.Bd -literal -offset indent
sema = dispatch_semaphore_create(0);
dispatch_async(queue, ^{
foo();
dispatch_semaphore_signal(sema);
});
bar();
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
.Ed
.Sh FINITE RESOURCE POOL
If the
.Fa count
parameter is greater than zero, then the semaphore is useful for managing a
finite pool of resources.
For example, a library that wants to limit Unix descriptor usage:
.Bd -literal -offset indent
sema = dispatch_semaphore_create(getdtablesize() / 4);
.Ed
.Pp
At each Unix FD allocation:
.Bd -literal -offset indent
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
fd = open("/etc/services", O_RDONLY);
.Ed
.Pp
When each FD is closed:
.Bd -literal -offset indent
close(fd);
dispatch_semaphore_signal(sema);
.Ed
.Sh RETURN VALUES
The
.Fn dispatch_semaphore_create
function returns NULL if no memory is available or if the
.Fa count
parameter is less than zero.
.Pp
The
.Fn dispatch_semaphore_signal
function returns non-zero when a thread is woken.
Otherwise, zero is returned.
.Pp
The
.Fn dispatch_semaphore_wait
function returns zero upon success and non-zero after the timeout expires. If
the timeout is DISPATCH_TIME_FOREVER, then
.Fn dispatch_semaphore_wait
waits forever and always returns zero.
.Sh MEMORY MODEL
Dispatch semaphores are retained and released via calls to
.Fn dispatch_retain
and
.Fn dispatch_release .
.Sh CAVEATS
Unbalanced dispatch semaphores cannot be released.
For a given semaphore, calls to
.Fn dispatch_semaphore_signal
and
.Fn dispatch_semaphore_wait
must be balanced before
.Fn dispatch_release
is called on it.
.Sh SEE ALSO
.Xr dispatch 3 ,
.Xr dispatch_object 3

View File

@@ -0,0 +1,587 @@
.\" Copyright (c) 2008-2013 Apple Inc. All rights reserved.
.Dd May 1, 2009
.Dt dispatch_source_create 3
.Os Darwin
.Sh NAME
.Nm dispatch_source_create
.Nd dispatch event sources
.Sh SYNOPSIS
.Fd #include <dispatch/dispatch.h>
.Ft dispatch_source_t
.Fo dispatch_source_create
.Fa "dispatch_source_type_t type"
.Fa "uintptr_t handle"
.Fa "unsigned long mask"
.Fa "dispatch_queue_t queue"
.Fc
.Ft void
.Fo dispatch_source_set_event_handler
.Fa "dispatch_source_t source"
.Fa "void (^block)(void)"
.Fc
.Ft void
.Fo dispatch_source_set_event_handler_f
.Fa "dispatch_source_t source"
.Fa "void (*function)(void *)"
.Fc
.Ft void
.Fo dispatch_source_set_registration_handler
.Fa "dispatch_source_t source"
.Fa "void (^block)(void)"
.Fc
.Ft void
.Fo dispatch_source_set_registration_handler_f
.Fa "dispatch_source_t source"
.Fa "void (*function)(void *)"
.Fc
.Ft void
.Fo dispatch_source_set_cancel_handler
.Fa "dispatch_source_t source"
.Fa "void (^block)(void)"
.Fc
.Ft void
.Fo dispatch_source_set_cancel_handler_f
.Fa "dispatch_source_t source"
.Fa "void (*function)(void *)"
.Fc
.Ft void
.Fo dispatch_source_cancel
.Fa "dispatch_source_t source"
.Fc
.Ft long
.Fo dispatch_source_testcancel
.Fa "dispatch_source_t source"
.Fc
.Ft uintptr_t
.Fo dispatch_source_get_handle
.Fa "dispatch_source_t source"
.Fc
.Ft "unsigned long"
.Fo dispatch_source_get_mask
.Fa "dispatch_source_t source"
.Fc
.Ft "unsigned long"
.Fo dispatch_source_get_data
.Fa "dispatch_source_t source"
.Fc
.Ft void
.Fo dispatch_source_merge_data
.Fa "dispatch_source_t source"
.Fa "unsigned long data"
.Fc
.Ft void
.Fo dispatch_source_set_timer
.Fa "dispatch_source_t source"
.Fa "dispatch_time_t start"
.Fa "uint64_t interval"
.Fa "uint64_t leeway"
.Fc
.Sh 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.
.Pp
When a state change occurs, the dispatch source will submit its event handler
block to its target queue.
.Pp
The
.Fn dispatch_source_create
function creates a new dispatch source object that may be retained and released
with calls to
.Fn dispatch_retain
and
.Fn dispatch_release
respectively. The
.Fa queue
parameter specifies the target queue of the new source object, it will
be retained by the source object. Pass the
.Dv DISPATCH_TARGET_QUEUE_DEFAULT
constant to use the default target queue (the default priority global
concurrent queue).
.Pp
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
.Fn dispatch_resume
before any events will be delivered.
.Pp
Dispatch sources may be one of the following types:
.Bl -bullet -compact -offset indent
.It
DISPATCH_SOURCE_TYPE_DATA_ADD
.It
DISPATCH_SOURCE_TYPE_DATA_OR
.It
DISPATCH_SOURCE_TYPE_DATA_REPLACE
.It
DISPATCH_SOURCE_TYPE_MACH_SEND
.It
DISPATCH_SOURCE_TYPE_MACH_RECV
.It
DISPATCH_SOURCE_TYPE_MEMORYPRESSURE
.It
DISPATCH_SOURCE_TYPE_PROC
.It
DISPATCH_SOURCE_TYPE_READ
.It
DISPATCH_SOURCE_TYPE_SIGNAL
.It
DISPATCH_SOURCE_TYPE_TIMER
.It
DISPATCH_SOURCE_TYPE_VNODE
.It
DISPATCH_SOURCE_TYPE_WRITE
.El
.Pp
The
.Fa handle
and
.Fa mask
arguments to
.Fn dispatch_source_create
and the return values of the
.Fn dispatch_source_get_handle ,
.Fn dispatch_source_get_mask ,
and
.Fn dispatch_source_get_data
functions should be interpreted according to the type of the dispatch source.
.Pp
The
.Fn 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.
.Pp
The
.Fn dispatch_source_get_mask
function
returns the set of flags that were specified at source creation time via the
.Fa mask
argument.
.Pp
The
.Fn 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.
.Pp
The
.Fn dispatch_source_merge_data
function is intended for use with the
.Vt DISPATCH_SOURCE_TYPE_DATA_ADD ,
.Vt DISPATCH_SOURCE_TYPE_DATA_OR
and
.Vt 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:
.Bl -tag -width "XXDISPATCH_SOURCE_TYPE_DATA_REPLACE" -compact -offset indent
.It \(bu DISPATCH_SOURCE_TYPE_DATA_ADD
.Vt data
is atomically added to the source's data
.It \(bu DISPATCH_SOURCE_TYPE_DATA_OR
.Vt data
is atomically bitwise ORed into the source's data
.It \(bu DISPATCH_SOURCE_TYPE_DATA_REPLACE
.Vt data
atomically replaces the source's data.
.El
.Pp
If the source data value resulting from the merge operation is 0, the source
handler will not be invoked. This can happen if:
.Bl -bullet -compact -offset indent
.It
the atomic addition wraps for sources of type
.Vt DISPATCH_SOURCE_TYPE_DATA_ADD ,
.It
0 is merged for sources of type
.Vt DISPATCH_SOURCE_TYPE_DATA_REPLACE .
.El
.Pp
.Sh SOURCE EVENT HANDLERS
In order to receive events from the dispatch source, an event handler should be
specified via
.Fn 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.
.Pp
Dispatch sources may be suspended or resumed independently of their target
queues using
.Fn dispatch_suspend
and
.Fn 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.
.Pp
The
.Fa handler
block
need not be reentrant safe, as it is not resubmitted to the target
.Fa queue
until any prior invocation for that dispatch source has completed.
When the handler is set, the dispatch source will perform a
.Fn Block_copy
on the
.Fa handler
block.
.Pp
To unset the event handler, call
.Fn dispatch_source_set_event_handler_f
and pass NULL as
.Fa 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.
.Sh REGISTRATION
When
.Fn 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.
.Pp
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
.Fn dispatch_source_set_registration_handler .
.Pp
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.
.Pp
.Sh CANCELLATION
The
.Fn 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.)
.Pp
The
.Fn 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.
.Pp
When a dispatch source is canceled its optional cancellation handler will be
submitted to its target queue. The cancellation handler may be specified via
.Fn dispatch_source_set_cancel_handler .
This cancellation handler is invoked only once, and only as a direct consequence
of calling
.Fn dispatch_source_cancel .
.Pp
.Em 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.
.Pp
.Sh DISPATCH SOURCE TYPES
The following section contains a summary of supported dispatch event types and
the interpretation of their parameters and returned data.
.Pp
.Vt DISPATCH_SOURCE_TYPE_DATA_ADD ,
.Vt DISPATCH_SOURCE_TYPE_DATA_OR ,
.Vt DISPATCH_SOURCE_TYPE_DATA_REPLACE
.Pp
Sources of this type allow applications to manually trigger the source's event
handler via a call to
.Fn 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
.Fa data
is application defined. These sources have no
.Fa handle
or
.Fa mask
and zero should be used.
.Pp
.Vt DISPATCH_SOURCE_TYPE_MACH_SEND
.Pp
Sources of this type monitor a mach port with a send right for state changes.
The
.Fa handle
is the mach port (mach_port_t) to monitor and the
.Fa mask
may be:
.Bl -tag -width "XXDISPATCH_PROC_SIGNAL" -compact -offset indent
.It \(bu DISPATCH_MACH_SEND_DEAD
The port's corresponding receive right has been destroyed
.El
.Pp
The data returned by
.Fn dispatch_source_get_data
is a bitmask that indicates which of the events in the
.Fa 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
.Fn mach_port_request_notification
on the same port.
.Pp
.Vt DISPATCH_SOURCE_TYPE_MACH_RECV
.Pp
Sources of this type monitor a mach port with a receive right for state changes.
The
.Fa handle
is the mach port (mach_port_t) to monitor and the
.Fa 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.
.Pp
.Vt DISPATCH_SOURCE_TYPE_MEMORYPRESSURE
.Pp
Sources of this type monitor the system memory pressure condition for state
changes. The
.Fa handle
is unused and should be zero. The
.Fa mask
may be one or more of the following:
.Bl -tag -width "XXDISPATCH_MEMORYPRESSURE_CRITICAL" -compact -offset indent
.It \(bu DISPATCH_MEMORYPRESSURE_NORMAL
The system memory pressure condition has returned to normal.
.It \(bu DISPATCH_MEMORYPRESSURE_WARN
The system memory pressure condition has changed to warning.
.It \(bu DISPATCH_MEMORYPRESSURE_CRITICAL
The system memory pressure condition has changed to critical.
.El
.Pp
The data returned by
.Fn dispatch_source_get_data
indicates which of the events in the
.Fa mask
were observed.
.Pp
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.
.Pp
However, applications should
.Em 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.
.Pp
.Vt DISPATCH_SOURCE_TYPE_PROC
.Pp
Sources of this type monitor processes for state changes.
The
.Fa handle
is the process identifier (pid_t) of the process to monitor and the
.Fa mask
may be one or more of the following:
.Bl -tag -width "XXDISPATCH_PROC_SIGNAL" -compact -offset indent
.It \(bu DISPATCH_PROC_EXIT
The process has exited and is available to
.Xr wait 2 .
.It \(bu DISPATCH_PROC_FORK
The process has created one or more child processes.
.It \(bu DISPATCH_PROC_EXEC
The process has become another executable image via a call to
.Xr execve 2
or
.Xr posix_spawn 2 .
.It \(bu DISPATCH_PROC_SIGNAL
A signal was delivered to the process.
.El
.Pp
The data returned by
.Fn dispatch_source_get_data
is a bitmask that indicates which of the events in the
.Fa mask
were observed.
.Pp
.Vt DISPATCH_SOURCE_TYPE_READ
.Pp
Sources of this type monitor file descriptors for pending data.
The
.Fa handle
is the file descriptor (int) to monitor and the
.Fa mask
is unused and should be zero.
.Pp
The data returned by
.Fn 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
.Em minimum
read buffer size. There are no guarantees that a complete read of this size
will be performed.
.Pp
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
.Xr fcntl 2
for additional information about setting the
.Vt O_NONBLOCK
flag on a file descriptor.
.Pp
.Vt DISPATCH_SOURCE_TYPE_SIGNAL
.Pp
Sources of this type monitor signals delivered to the current process. The
.Fa handle
is the signal number to monitor (int) and the
.Fa mask
is unused and should be zero.
.Pp
The data returned by
.Fn dispatch_source_get_data
is the number of signals received since the last invocation of the event handler
block.
.Pp
Unlike signal handlers specified via
.Fn 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
.Xr sigaction 2 .
Furthermore, multiple observers of a given signal are supported; thus allowing
applications and libraries to cooperate safely. However, a dispatch source
.Em 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
.Fn main :
.Bd -literal -offset ident
signal(SIGTERM, SIG_IGN);
.Ed
.Pp
.Vt DISPATCH_SOURCE_TYPE_TIMER
.Pp
Sources of this type periodically submit the event handler block to the target
queue. The
.Fa handle
argument is unused and should be zero.
.Pp
The data returned by
.Fn dispatch_source_get_data
is the number of times the timer has fired since the last invocation of the
event handler block.
.Pp
The timer parameters are configured with the
.Fn 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
.Fa start ,
and every
.Fa interval
nanoseconds thereafter until the timer source is canceled.
.Pp
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
.Fa leeway
argument, the lower limit is under the control of the system.
.Pp
For the initial timer fire at
.Fa start ,
the upper limit to the allowable delay is set to
.Fa leeway
nanoseconds. For the subsequent timer fires at
.Fa start
.Li "+ N *"
.Fa interval ,
the upper limit is
.Li MIN(
.Fa leeway ,
.Fa interval
.Li "/ 2 )" .
.Pp
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
.Fa mask
of
.Vt DISPATCH_TIMER_STRICT ,
the system will make a best effort to strictly observe the provided
.Fa 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.
.Pp
The
.Fa start
argument also determines which clock will be used for the timer: If
.Fa start
is
.Vt DISPATCH_TIME_NOW
or was created with
.Xr dispatch_time 3 ,
the timer is based on up time (which is obtained from
.Fn mach_absolute_time
on Apple platforms).
If
.Fa start
was created with
.Xr dispatch_walltime 3 ,
the timer is based on
.Xr gettimeofday 3 .
.Pp
.Vt DISPATCH_SOURCE_TYPE_VNODE
.Pp
Sources of this type monitor the virtual filesystem nodes for state changes.
The
.Fa handle
is a file descriptor (int) referencing the node to monitor, and
the
.Fa mask
may be one or more of the following:
.Bl -tag -width "XXDISPATCH_VNODE_ATTRIB" -compact -offset indent
.It \(bu DISPATCH_VNODE_DELETE
The referenced node was removed from the filesystem namespace via
.Xr unlink 2 .
.It \(bu DISPATCH_VNODE_WRITE
A write to the referenced file occurred.
.It \(bu DISPATCH_VNODE_EXTEND
The referenced file was extended.
.It \(bu DISPATCH_VNODE_ATTRIB
The metadata attributes of the referenced node have changed.
.It \(bu DISPATCH_VNODE_LINK
The link count on the referenced node has changed.
.It \(bu DISPATCH_VNODE_RENAME
The referenced node was renamed.
.It \(bu DISPATCH_VNODE_REVOKE
Access to the referenced node was revoked via
.Xr revoke 2
or the underlying fileystem was unmounted.
.It \(bu DISPATCH_VNODE_FUNLOCK
The referenced file was unlocked by
.Xr flock 2
or
.Xr close 2 .
.El
.Pp
The data returned by
.Fn dispatch_source_get_data
is a bitmask that indicates which of the events in the
.Fa mask
were observed.
.Pp
.Vt DISPATCH_SOURCE_TYPE_WRITE
.Pp
Sources of this type monitor file descriptors for available write buffer space.
The
.Fa handle
is the file descriptor (int) to monitor and the
.Fa mask
is unused and should be zero.
.Pp
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
.Xr fcntl 2
for additional information about setting the
.Vt O_NONBLOCK
flag on a file descriptor.
.Pp
.Sh SEE ALSO
.Xr dispatch 3 ,
.Xr dispatch_object 3 ,
.Xr dispatch_queue_create 3

View File

@@ -0,0 +1,130 @@
.\" Copyright (c) 2008-2013 Apple Inc. All rights reserved.
.Dd May 1, 2009
.Dt dispatch_time 3
.Os Darwin
.Sh NAME
.Nm dispatch_time ,
.Nm dispatch_walltime
.Nd Calculate temporal milestones
.Sh SYNOPSIS
.Fd #include <dispatch/dispatch.h>
.Vt static const dispatch_time_t DISPATCH_TIME_NOW = 0ull ;
.Vt static const dispatch_time_t DISPATCH_WALLTIME_NOW = ~1ull ;
.Vt static const dispatch_time_t DISPATCH_TIME_FOREVER = ~0ull ;
.Ft dispatch_time_t
.Fo dispatch_time
.Fa "dispatch_time_t base" "int64_t offset"
.Fc
.Ft dispatch_time_t
.Fo dispatch_walltime
.Fa "struct timespec *base" "int64_t offset"
.Fc
.Sh DESCRIPTION
The
.Fn dispatch_time
and
.Fn dispatch_walltime
functions provide a simple mechanism for expressing temporal milestones for use
with dispatch functions that need timeouts or operate on a schedule.
.Pp
The
.Fa dispatch_time_t
type is a semi-opaque integer, with only the special values
.Vt DISPATCH_TIME_NOW ,
.Vt DISPATCH_WALLTIME_NOW
and
.Vt DISPATCH_TIME_FOREVER
being externally defined. All other values are represented using an internal
format that is not safe for integer arithmetic or comparison.
The internal format is subject to change.
.Pp
The
.Fn dispatch_time
function returns a milestone relative to an existing milestone after adding
.Fa offset
nanoseconds.
If the
.Fa base
parameter maps internally to a wall clock or is
.Vt DISPATCH_WALLTIME_NOW ,
then the returned value is relative to the wall clock.
Otherwise, if
.Fa base
is
.Vt DISPATCH_TIME_NOW ,
then the current time of the default host clock is used. On Apple platforms,
the value of the default host clock is obtained from
.Vt mach_absolute_time() .
.Pp
The
.Fn dispatch_walltime
function is useful for creating a milestone relative to a fixed point in time
using the wall clock, as specified by the optional
.Fa base
parameter. If
.Fa base
is NULL, then the current time of the wall clock is used.
.Vt dispatch_walltime(NULL, offset)
is equivalent to
.Vt dispatch_time(DISPATCH_WALLTIME_NOW, offset) .
.Sh EDGE CONDITIONS
The
.Fn dispatch_time
and
.Fn dispatch_walltime
functions detect overflow and underflow conditions when applying the
.Fa offset
parameter.
.Pp
Overflow causes
.Vt DISPATCH_TIME_FOREVER
to be returned. When
.Fa base
is
.Vt DISPATCH_TIME_FOREVER ,
then the
.Fa offset
parameter is ignored.
.Pp
Underflow causes the smallest representable value to be
returned for a given clock.
.Sh EXAMPLES
Create a milestone two seconds in the future, relative to the default clock:
.Bd -literal -offset indent
milestone = dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC);
.Ed
.Pp
Create a milestone two seconds in the future, in wall clock time:
.Bd -literal -offset indent
milestone = dispatch_time(DISPATCH_WALLTIME_NOW, 2 * NSEC_PER_SEC);
.Ed
.Pp
Create a milestone for use as an infinite timeout:
.Bd -literal -offset indent
milestone = DISPATCH_TIME_FOREVER;
.Ed
.Pp
Create a milestone on Tuesday, January 19, 2038:
.Bd -literal -offset indent
struct timespec ts;
ts.tv_sec = 0x7FFFFFFF;
ts.tv_nsec = 0;
milestone = dispatch_walltime(&ts, 0);
.Ed
.Pp
Use a negative delta to create a milestone an hour before the one above:
.Bd -literal -offset indent
milestone = dispatch_walltime(&ts, -60 * 60 * NSEC_PER_SEC);
.Ed
.Sh RETURN VALUE
These functions return an abstract value for use with
.Fn dispatch_after ,
.Fn dispatch_group_wait ,
.Fn dispatch_semaphore_wait ,
or
.Fn dispatch_source_set_timer .
.Sh SEE ALSO
.Xr dispatch 3 ,
.Xr dispatch_after 3 ,
.Xr dispatch_group_create 3 ,
.Xr dispatch_semaphore_create 3