Provided by: libdispatch-dev_0~svn197-3.3ubuntu2_amd64 bug


     dispatch_queue_create, dispatch_queue_get_label, dispatch_get_current_queue,
     dispatch_get_global_queue, dispatch_get_main_queue, dispatch_main, dispatch_set_target_queue
     — where blocks are scheduled for execution


     #include <dispatch/dispatch.h>

     dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);

     const char *
     dispatch_queue_get_label(dispatch_queue_t queue);


     dispatch_get_global_queue(long priority, unsigned long flags);



     dispatch_set_target_queue(dispatch_object_t object, dispatch_queue_t target);


     Queues are the fundamental mechanism for scheduling blocks for execution within the
     dispatch(3) framework.

     All blocks submitted to dispatch queues are dequeued in FIFO order.  By default, queues
     created with dispatch_queue_create() wait for the previously dequeued block to complete
     before dequeuing the next block. This FIFO completion behavior is sometimes simply described
     as a "serial queue."  Queues are not bound to any specific thread of execution and blocks
     submitted to independent queues may execute concurrently.  Queues, like all dispatch
     objects, are reference counted and newly created queues have a reference count of one.

     The optional label argument is used to describe the purpose of the queue and is useful
     during debugging and performance analysis. By convention, clients should pass a reverse DNS
     style label.  If a label is provided, it is copied. If a label is not provided, then
     dispatch_queue_get_label() returns an empty C string.  For example:

     my_queue = dispatch_queue_create("com.example.subsystem.taskXYZ", NULL);

     The attr argument is reserved for future use and must be NULL.

     Queues may be temporarily suspended and resumed with the functions dispatch_suspend() and
     dispatch_resume() respectively. Suspension is checked prior to block execution and is not


     The dispatch framework provides a default serial queue for the application to use.  This
     queue is accessed via dispatch_get_main_queue().  Programs must call dispatch_main() at the
     end of main() in order to process blocks submitted to the main queue. (See the compatibility
     section for exceptions.)


     Unlike the main queue or queues allocated with dispatch_queue_create(), the global
     concurrent queues schedule blocks as soon as threads become available (non-FIFO completion
     order). The global concurrent queues represent three priority bands:

     Blocks submitted to the high priority global queue will be invoked before those submitted to
     the default or low priority global queues. Blocks submitted to the low priority global queue
     will only be invoked if no blocks are pending on the default or high priority queues.


     The dispatch_queue_create() function returns NULL on failure.

     The dispatch_queue_get_label() function always returns a valid C string. An empty C string
     is returned if the label was NULL creation time.

     The dispatch_get_main_queue() function returns the default main queue.

     The dispatch_get_current_queue() function 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 dispatch_main() is called, then the result of
     dispatch_get_main_queue() is returned.  Otherwise, the result of
     dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) will be returned in all other

     The dispatch_main() function never returns.


     The 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. Currently
     only dispatch queues and dispatch sources are supported by this function. The result of
     using dispatch_set_target_queue() with any other dispatch object type is undefined.

     The new target queue is retained by the given object before the previous target queue is
     released. The new target queue will take effect between block executions, but not in the
     middle of any existing block executions (non-preemptive).

     The priority of a dispatch queue is inherited by its target queue.  In order to change the
     priority of a queue created with dispatch_queue_create(), use the
     dispatch_get_global_queue() function to obtain a target queue of the desired priority. The
     flags argument is reserved for future use and must be zero. Passing any value other than
     zero may result in a NULL return value.

     The target queue of a dispatch source specifies where its event handler and cancellation
     handler blocks will be submitted. See dispatch_source_create(3) for more information about
     dispatch sources.

     The result of passing the main queue or a global concurrent queue to the first argument of
     dispatch_set_target_queue() is undefined.

     Directly or indirectly setting the target queue of a dispatch queue to itself is undefined.


     Code cannot make any assumptions about the queue returned by dispatch_get_current_queue().
     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. Therefore, dispatch_get_current_queue() MUST only be used for identity tests
     or debugging.


     Cocoa applications need not call 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 dispatch_main() are not
     guaranteed to execute on the main thread.

     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 MUST catch all
     exceptions before returning from a block submitted to a dispatch queue; otherwise the
     internal data structures of the dispatch framework will be left in an inconsistent state.

     The dispatch framework manages the relationship between dispatch queues and threads of
     execution. As a result, applications MUST NOT delete or mutate objects that they did not
     create. The following interfaces MUST NOT be called by blocks submitted to a dispatch queue:

           ·   pthread_cancel()

           ·   pthread_detach()

           ·   pthread_join()

           ·   pthread_kill()

           ·   pthread_exit()

     Applications 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:

           ·   pthread_setcancelstate()

           ·   pthread_setcanceltype()

           ·   pthread_setschedparam()

           ·   pthread_sigmask()

           ·   pthread_setugid_np()

           ·   pthread_chdir()

           ·   pthread_fchdir()

     Applications MUST NOT rely on the following interfaces returning predictable results between
     invocations of blocks submitted to a dispatch queue:

           ·   pthread_self()

           ·   pthread_getschedparam()

           ·   pthread_get_stacksize_np()

           ·   pthread_get_stackaddr_np()

           ·   pthread_mach_thread_np()

           ·   pthread_from_mach_thread_np()

     While the result of 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 pthread_setspecific() and
     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
     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.

     The following example code correctly handles per-thread return values:

           __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 %d0, r, e);

     Note that in the above example 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 getpwnam()
     instead of getpwnam_r().

     As an optimization, dispatch_sync() invokes the block on the current thread when possible.
     In this case, the thread specific data such as errno may persist from the block until back
     to the caller. Great care should be taken not to accidentally rely on this side-effect.


     dispatch(3), dispatch_async(3), dispatch_object(3), dispatch_source_create(3)