]>
Commit | Line | Data |
---|---|---|
1 | .\" Copyright (c) 2008-2009 Apple Inc. All rights reserved. | |
2 | .Dd May 1, 2008 | |
3 | .Dt dispatch_queue_create 3 | |
4 | .Os Darwin | |
5 | .Sh NAME | |
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 , | |
11 | .Nm dispatch_main , | |
12 | .Nm dispatch_set_target_queue | |
13 | .Nd where blocks are scheduled for execution | |
14 | .Sh SYNOPSIS | |
15 | .Fd #include <dispatch/dispatch.h> | |
16 | .Ft dispatch_queue_t | |
17 | .Fo dispatch_queue_create | |
18 | .Fa "const char *label" "dispatch_queue_attr_t attr" | |
19 | .Fc | |
20 | .Ft "const char *" | |
21 | .Fo dispatch_queue_get_label | |
22 | .Fa "dispatch_queue_t queue" | |
23 | .Fc | |
24 | .Ft dispatch_queue_t | |
25 | .Fo dispatch_get_current_queue | |
26 | .Fa void | |
27 | .Fc | |
28 | .Ft dispatch_queue_t | |
29 | .Fo dispatch_get_global_queue | |
30 | .Fa "long priority" | |
31 | .Fa "unsigned long flags" | |
32 | .Fc | |
33 | .Ft dispatch_queue_t | |
34 | .Fo dispatch_get_main_queue | |
35 | .Fa void | |
36 | .Fc | |
37 | .Ft void | |
38 | .Fo dispatch_main | |
39 | .Fa void | |
40 | .Fc | |
41 | .Ft void | |
42 | .Fo dispatch_set_target_queue | |
43 | .Fa "dispatch_object_t object" | |
44 | .Fa "dispatch_queue_t target" | |
45 | .Fc | |
46 | .Sh DESCRIPTION | |
47 | Queues are the fundamental mechanism for scheduling blocks for execution within | |
48 | the | |
49 | .Xr dispatch 3 | |
50 | framework. | |
51 | .Pp | |
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. | |
61 | .Pp | |
62 | The optional | |
63 | .Fa label | |
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. | |
70 | For example: | |
71 | .Pp | |
72 | .Bd -literal | |
73 | my_queue = dispatch_queue_create("com.example.subsystem.taskXYZ", NULL); | |
74 | .Ed | |
75 | .Pp | |
76 | The | |
77 | .Fa attr | |
78 | argument is reserved for future use and must be NULL. | |
79 | .Pp | |
80 | Queues may be temporarily suspended and resumed with the functions | |
81 | .Fn dispatch_suspend | |
82 | and | |
83 | .Fn dispatch_resume | |
84 | respectively. Suspension is checked prior to block execution and is | |
85 | .Em not | |
86 | preemptive. | |
87 | .Sh MAIN QUEUE | |
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 . | |
91 | Programs must call | |
92 | .Fn dispatch_main | |
93 | at the end of | |
94 | .Fn main | |
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 | |
104 | .It | |
105 | DISPATCH_QUEUE_PRIORITY_HIGH | |
106 | .It | |
107 | DISPATCH_QUEUE_PRIORITY_DEFAULT | |
108 | .It | |
109 | DISPATCH_QUEUE_PRIORITY_LOW | |
110 | .El | |
111 | .Pp | |
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. | |
116 | .Pp | |
117 | .Sh RETURN VALUES | |
118 | The | |
119 | .Fn dispatch_queue_create | |
120 | function returns NULL on failure. | |
121 | .Pp | |
122 | The | |
123 | .Fn dispatch_queue_get_label | |
124 | function always returns a valid C string. An empty C string is returned if the | |
125 | .Fa label | |
126 | was NULL creation time. | |
127 | .Pp | |
128 | The | |
129 | .Fn dispatch_get_main_queue | |
130 | function returns the default main queue. | |
131 | .Pp | |
132 | The | |
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 | |
137 | .Fn dispatch_main | |
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 | |
143 | .Fa 0 | |
144 | .Fc | |
145 | will be returned in all other cases. | |
146 | .Pp | |
147 | The | |
148 | .Fn dispatch_main | |
149 | function never returns. | |
150 | .Sh TARGET QUEUE | |
151 | The | |
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 | |
156 | of using | |
157 | .Fn dispatch_set_target_queue | |
158 | with any other dispatch object type is undefined. | |
159 | .Pp | |
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 | |
163 | (non-preemptive). | |
164 | .Pp | |
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 , | |
168 | use the | |
169 | .Fn dispatch_get_global_queue | |
170 | function to obtain a target queue of the desired priority. The | |
171 | .Fa flags | |
172 | argument is reserved for future use and must be zero. Passing any value other | |
173 | than zero may result in a | |
174 | .Vt NULL | |
175 | return value. | |
176 | .Pp | |
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. | |
181 | .Pp | |
182 | The result of passing the main queue or a global concurrent queue to the first | |
183 | argument of | |
184 | .Fn dispatch_set_target_queue | |
185 | is undefined. | |
186 | .Pp | |
187 | Directly or indirectly setting the target queue of a dispatch queue to itself is undefined. | |
188 | .Sh CAVEATS | |
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 | |
196 | .Em MUST | |
197 | only be used for identity tests or debugging. | |
198 | .Sh COMPATIBILITY | |
199 | Cocoa applications need not call | |
200 | .Fn dispatch_main . | |
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. | |
203 | .Pp | |
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++. | |
206 | Applications | |
207 | .Em MUST | |
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. | |
211 | .Pp | |
212 | The dispatch framework manages the relationship between dispatch queues and | |
213 | threads of execution. As a result, applications | |
214 | .Em MUST NOT | |
215 | delete or mutate objects that they did not create. The following interfaces | |
216 | .Em MUST NOT | |
217 | be called by blocks submitted to a dispatch queue: | |
218 | .Bl -bullet -offset indent | |
219 | .It | |
220 | .Fn pthread_cancel | |
221 | .It | |
222 | .Fn pthread_detach | |
223 | .It | |
224 | .Fn pthread_join | |
225 | .It | |
226 | .Fn pthread_kill | |
227 | .It | |
228 | .Fn pthread_exit | |
229 | .El | |
230 | .Pp | |
231 | Applications | |
232 | .Em MAY | |
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 | |
236 | .It | |
237 | .Fn pthread_setcancelstate | |
238 | .It | |
239 | .Fn pthread_setcanceltype | |
240 | .It | |
241 | .Fn pthread_setschedparam | |
242 | .It | |
243 | .Fn pthread_sigmask | |
244 | .It | |
245 | .Fn pthread_setugid_np | |
246 | .It | |
247 | .Fn pthread_chdir | |
248 | .It | |
249 | .Fn pthread_fchdir | |
250 | .El | |
251 | .Pp | |
252 | Applications | |
253 | .Em MUST NOT | |
254 | rely on the following interfaces returning predictable results between | |
255 | invocations of blocks submitted to a dispatch queue: | |
256 | .Bl -bullet -offset indent | |
257 | .It | |
258 | .Fn pthread_self | |
259 | .It | |
260 | .Fn pthread_getschedparam | |
261 | .It | |
262 | .Fn pthread_get_stacksize_np | |
263 | .It | |
264 | .Fn pthread_get_stackaddr_np | |
265 | .It | |
266 | .Fn pthread_mach_thread_np | |
267 | .It | |
268 | .Fn pthread_from_mach_thread_np | |
269 | .El | |
270 | .Pp | |
271 | While the result of | |
272 | .Fn pthread_self | |
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 | |
278 | and | |
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. | |
285 | .Pp | |
286 | The following example code correctly handles per-thread return values: | |
287 | .Bd -literal -offset indent | |
288 | __block int r; | |
289 | __block int e; | |
290 | dispatch_sync(queue, ^{ | |
291 | r = kill(1, 0); | |
292 | // Copy the per-thread return value to the callee thread | |
293 | e = errno; | |
294 | }); | |
295 | printf("kill(1,0) returned %d and errno %d\n", r, e); | |
296 | .Ed | |
297 | .Pp | |
298 | Note that in the above example | |
299 | .Va errno | |
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 | |
303 | .Fn getpwnam | |
304 | instead of | |
305 | .Fn getpwnam_r . | |
306 | .Pp | |
307 | As an optimization, | |
308 | .Fn dispatch_sync | |
309 | invokes the block on the current thread when possible. In this case, the thread | |
310 | specific data such as | |
311 | .Va errno | |
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. | |
314 | .Pp | |
315 | .Sh SEE ALSO | |
316 | .Xr dispatch_object 3 , | |
317 | .Xr dispatch_async 3 , | |
318 | .Xr dispatch_source_create 3 |