1 .\" Copyright (c) 2008-2009 Apple Inc. All rights reserved.
 
   3 .Dt dispatch_queue_create 3
 
   6 .Nm dispatch_queue_create ,
 
   7 .Nm dispatch_queue_get_label ,
 
   8 .Nm dispatch_get_current_queue ,
 
   9 .Nm dispatch_get_global_queue ,
 
  10 .Nm dispatch_get_main_queue ,
 
  12 .Nm dispatch_set_target_queue
 
  13 .Nd where blocks are scheduled for execution
 
  15 .Fd #include <dispatch/dispatch.h>
 
  17 .Fo dispatch_queue_create
 
  18 .Fa "const char *label" "dispatch_queue_attr_t attr"
 
  21 .Fo dispatch_queue_get_label
 
  22 .Fa "dispatch_queue_t queue"
 
  25 .Fo dispatch_get_current_queue
 
  29 .Fo dispatch_get_global_queue
 
  31 .Fa "unsigned long flags"
 
  34 .Fo dispatch_get_main_queue
 
  42 .Fo dispatch_set_target_queue
 
  43 .Fa "dispatch_object_t object"
 
  44 .Fa "dispatch_queue_t target"
 
  47 Queues are the fundamental mechanism for scheduling blocks for execution within
 
  52 All blocks submitted to dispatch queues are dequeued in FIFO order.
 
  53 By default, queues created with
 
  54 .Fn dispatch_queue_create
 
  55 wait for the previously dequeued block to complete before dequeuing the next
 
  56 block. This FIFO completion behavior is sometimes simply described as a "serial queue."
 
  57 Queues are not bound to any specific thread of execution and blocks submitted
 
  58 to independent queues may execute concurrently.
 
  59 Queues, like all dispatch objects, are reference counted and newly created
 
  60 queues have a reference count of one.
 
  64 argument is used to describe the purpose of the queue and is useful during
 
  65 debugging and performance analysis. By convention, clients should pass a
 
  66 reverse DNS style label.
 
  67 If a label is provided, it is copied. If a label is not provided, then
 
  68 .Fn dispatch_queue_get_label
 
  69 returns an empty C string.
 
  73 my_queue = dispatch_queue_create("com.example.subsystem.taskXYZ", NULL);
 
  78 argument is reserved for future use and must be NULL.
 
  80 Queues may be temporarily suspended and resumed with the functions
 
  84 respectively. Suspension is checked prior to block execution and is
 
  88 The dispatch framework provides a default serial queue for the application to use.
 
  89 This queue is accessed via
 
  90 .Fn dispatch_get_main_queue .
 
  95 in order to process blocks submitted to the main queue. (See the compatibility
 
  96 section for exceptions.)
 
  97 .Sh GLOBAL CONCURRENT QUEUES
 
  98 Unlike the main queue or queues allocated with
 
  99 .Fn dispatch_queue_create ,
 
 100 the global concurrent queues schedule blocks as soon as threads become
 
 101 available (non-FIFO completion order). The global concurrent queues represent
 
 102 three priority bands:
 
 103 .Bl -bullet -compact -offset indent
 
 105 DISPATCH_QUEUE_PRIORITY_HIGH
 
 107 DISPATCH_QUEUE_PRIORITY_DEFAULT
 
 109 DISPATCH_QUEUE_PRIORITY_LOW
 
 112 Blocks submitted to the high priority global queue will be invoked before those
 
 113 submitted to the default or low priority global queues. Blocks submitted to the
 
 114 low priority global queue will only be invoked if no blocks are pending on the
 
 115 default or high priority queues.
 
 119 .Fn dispatch_queue_create
 
 120 function returns NULL on failure.
 
 123 .Fn dispatch_queue_get_label
 
 124 function always returns a valid C string. An empty C string is returned if the
 
 126 was NULL creation time.
 
 129 .Fn dispatch_get_main_queue
 
 130 function returns the default main queue.
 
 133 .Fn dispatch_get_current_queue
 
 134 function always returns a valid queue. When called from within a block submitted
 
 135 to a dispatch queue, that queue will be returned. If this function is called from
 
 136 the main thread before
 
 138 is called, then the result of
 
 139 .Fn dispatch_get_main_queue
 
 140 is returned.  Otherwise, the result of
 
 141 .Fo dispatch_get_global_queue
 
 142 .Fa DISPATCH_QUEUE_PRIORITY_DEFAULT
 
 145 will be returned in all other cases.
 
 149 function never returns.
 
 152 .Fn dispatch_set_target_queue
 
 153 function updates the target queue of the given dispatch object. The target
 
 154 queue of an object is responsible for processing the object. Currently only
 
 155 dispatch queues and dispatch sources are supported by this function. The result
 
 157 .Fn dispatch_set_target_queue
 
 158 with any other dispatch object type is undefined.
 
 160 The new target queue is retained by the given object before the previous target
 
 161 queue is released. The new target queue will take effect between block
 
 162 executions, but not in the middle of any existing block executions
 
 165 The priority of a dispatch queue is inherited by its target queue. 
 
 166 In order to change the priority of a queue created with
 
 167 .Fn dispatch_queue_create ,
 
 169 .Fn dispatch_get_global_queue
 
 170 function to obtain a target queue of the desired priority. The
 
 172 argument is reserved for future use and must be zero. Passing any value other
 
 173 than zero may result in a
 
 177 The target queue of a dispatch source specifies where its event handler and
 
 178 cancellation handler blocks will be submitted. See
 
 179 .Xr dispatch_source_create 3
 
 180 for more information about dispatch sources.
 
 182 The result of passing the main queue or a global concurrent queue to the first
 
 184 .Fn dispatch_set_target_queue
 
 187 Directly or indirectly setting the target queue of a dispatch queue to itself is undefined.
 
 189 Code cannot make any assumptions about the queue returned by
 
 190 .Fn dispatch_get_current_queue .
 
 191 The returned queue may have arbitrary policies that may surprise code that tries
 
 192 to schedule work with the queue. The list of policies includes, but is not
 
 193 limited to, queue width (i.e. serial vs. concurrent), scheduling priority,
 
 194 security credential or filesystem configuration. Therefore,
 
 195 .Fn dispatch_get_current_queue
 
 197 only be used for identity tests or debugging.
 
 199 Cocoa applications need not call
 
 201 Blocks submitted to the main queue will be executed as part of the "common modes"
 
 202 of the application's main NSRunLoop or CFRunLoop.
 
 204 The dispatch framework is a pure C level API. As a result, it does not catch
 
 205 exceptions generated by higher level languages such as Objective-C or C++.
 
 208 catch all exceptions before returning from a block submitted to a dispatch
 
 209 queue; otherwise the internal data structures of the dispatch framework will be
 
 210 left in an inconsistent state.
 
 212 The dispatch framework manages the relationship between dispatch queues and
 
 213 threads of execution. As a result, applications
 
 215 delete or mutate objects that they did not create. The following interfaces
 
 217 be called by blocks submitted to a dispatch queue:
 
 218 .Bl -bullet -offset indent
 
 233 call the following interfaces from a block submitted to a dispatch queue if
 
 234 and only if they restore the thread to its original state before returning:
 
 235 .Bl -bullet -offset indent
 
 237 .Fn pthread_setcancelstate
 
 239 .Fn pthread_setcanceltype
 
 241 .Fn pthread_setschedparam
 
 245 .Fn pthread_setugid_np
 
 254 rely on the following interfaces returning predictable results between
 
 255 invocations of blocks submitted to a dispatch queue:
 
 256 .Bl -bullet -offset indent
 
 260 .Fn pthread_getschedparam
 
 262 .Fn pthread_get_stacksize_np
 
 264 .Fn pthread_get_stackaddr_np
 
 266 .Fn pthread_mach_thread_np
 
 268 .Fn pthread_from_mach_thread_np
 
 273 may change between invocations of blocks, the value will not change during the
 
 274 execution of any single block. Because the underlying thread may change beteween
 
 275 block invocations on a single queue, using per-thread data as an out-of-band
 
 276 return value is error prone. In other words, the result of calling
 
 277 .Fn pthread_setspecific
 
 279 .Fn pthread_getspecific
 
 280 is well defined within a signle block, but not across multiple blocks. Also,
 
 281 one cannot make any assumptions about when the destructor passed to
 
 282 .Fn pthread_key_create
 
 283 is called. The destructor may be called between the invocation of blocks on
 
 284 the same queue, or during the idle state of a process.
 
 286 The following example code correctly handles per-thread return values:
 
 287 .Bd -literal -offset indent
 
 290 dispatch_sync(queue, ^{
 
 292         // Copy the per-thread return value to the callee thread
 
 295 printf("kill(1,0) returned %d and errno %d\n", r, e);
 
 298 Note that in the above example
 
 300 is a per-thread variable and must be copied out explicitly as the block may be
 
 301 invoked on different thread of execution than the caller. Another example of
 
 302 per-thread data that would need to be copied is the use of 
 
 309 invokes the block on the current thread when possible. In this case, the thread
 
 310 specific data such as
 
 312 may persist from the block until back to the caller. Great care should be taken
 
 313 not to accidentally rely on this side-effect.
 
 316 .Xr dispatch_object 3 ,
 
 317 .Xr dispatch_async 3 ,
 
 318 .Xr dispatch_source_create 3