]> git.saurik.com Git - apple/libdispatch.git/blob - src/queue.h
libdispatch-84.5.tar.gz
[apple/libdispatch.git] / src / queue.h
1 /*
2 * Copyright (c) 2008-2009 Apple Inc. All rights reserved.
3 *
4 * @APPLE_APACHE_LICENSE_HEADER_START@
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * @APPLE_APACHE_LICENSE_HEADER_END@
19 */
20
21 #ifndef __DISPATCH_QUEUE__
22 #define __DISPATCH_QUEUE__
23
24 #ifndef __DISPATCH_INDIRECT__
25 #error "Please #include <dispatch/dispatch.h> instead of this file directly."
26 #include <dispatch/base.h> // for HeaderDoc
27 #endif
28
29 /*!
30 * @header
31 *
32 * Dispatch is an abstract model for expressing concurrency via simple but
33 * powerful API.
34 *
35 * At the core, dispatch provides serial FIFO queues to which blocks may be
36 * submitted. Blocks submitted to these dispatch queues are invoked on a pool
37 * of threads fully managed by the system. No guarantee is made regarding
38 * which thread a block will be invoked on; however, it is guaranteed that only
39 * one block submitted to the FIFO dispatch queue will be invoked at a time.
40 *
41 * When multiple queues have blocks to be processed, the system is free to
42 * allocate additional threads to invoke the blocks concurrently. When the
43 * queues become empty, these threads are automatically released.
44 */
45
46 /*!
47 * @typedef dispatch_queue_t
48 *
49 * @abstract
50 * Dispatch queues invoke blocks submitted to them serially in FIFO order. A
51 * queue will only invoke one block at a time, but independent queues may each
52 * invoke their blocks concurrently with respect to each other.
53 *
54 * @discussion
55 * Dispatch queues are lightweight objects to which blocks may be submitted.
56 * The system manages a pool of threads which process dispatch queues and
57 * invoke blocks submitted to them.
58 *
59 * Conceptually a dispatch queue may have its own thread of execution, and
60 * interaction between queues is highly asynchronous.
61 *
62 * Dispatch queues are reference counted via calls to dispatch_retain() and
63 * dispatch_release(). Pending blocks submitted to a queue also hold a
64 * reference to the queue until they have finished. Once all references to a
65 * queue have been released, the queue will be deallocated by the system.
66 */
67 DISPATCH_DECL(dispatch_queue);
68
69 /*!
70 * @typedef dispatch_queue_attr_t
71 *
72 * @abstract
73 * Attribute and policy extensions for dispatch queues.
74 */
75 DISPATCH_DECL(dispatch_queue_attr);
76
77 /*!
78 * @typedef dispatch_block_t
79 *
80 * @abstract
81 * The prototype of blocks submitted to dispatch queues, which take no
82 * arguments and have no return value.
83 *
84 * @discussion
85 * The declaration of a block allocates storage on the stack. Therefore, this
86 * is an invalid construct:
87 *
88 * dispatch_block_t block;
89 *
90 * if (x) {
91 * block = ^{ printf("true\n"); };
92 * } else {
93 * block = ^{ printf("false\n"); };
94 * }
95 * block(); // unsafe!!!
96 *
97 * What is happening behind the scenes:
98 *
99 * if (x) {
100 * struct Block __tmp_1 = ...; // setup details
101 * block = &__tmp_1;
102 * } else {
103 * struct Block __tmp_2 = ...; // setup details
104 * block = &__tmp_2;
105 * }
106 *
107 * As the example demonstrates, the address of a stack variable is escaping the
108 * scope in which it is allocated. That is a classic C bug.
109 */
110 #ifdef __BLOCKS__
111 typedef void (^dispatch_block_t)(void);
112 #endif
113
114 __BEGIN_DECLS
115
116 /*!
117 * @function dispatch_async
118 *
119 * @abstract
120 * Submits a block for asynchronous execution on a dispatch queue.
121 *
122 * @discussion
123 * The dispatch_async() function is the fundamental mechanism for submitting
124 * blocks to a dispatch queue.
125 *
126 * Calls to dispatch_async() always return immediately after the block has
127 * been submitted, and never wait for the block to be invoked.
128 *
129 * The target queue determines whether the block will be invoked serially or
130 * concurrently with respect to other blocks submitted to that same queue.
131 * Serial queues are processed concurrently with with respect to each other.
132 *
133 * @param queue
134 * The target dispatch queue to which the block is submitted.
135 * The system will hold a reference on the target queue until the block
136 * has finished.
137 * The result of passing NULL in this parameter is undefined.
138 *
139 * @param block
140 * The block to submit to the target dispatch queue. This function performs
141 * Block_copy() and Block_release() on behalf of callers.
142 * The result of passing NULL in this parameter is undefined.
143 */
144 #ifdef __BLOCKS__
145 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
146 DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
147 void
148 dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
149 #endif
150
151 /*!
152 * @function dispatch_async_f
153 *
154 * @abstract
155 * Submits a function for asynchronous execution on a dispatch queue.
156 *
157 * @discussion
158 * See dispatch_async() for details.
159 *
160 * @param queue
161 * The target dispatch queue to which the function is submitted.
162 * The system will hold a reference on the target queue until the function
163 * has returned.
164 * The result of passing NULL in this parameter is undefined.
165 *
166 * @param context
167 * The application-defined context parameter to pass to the function.
168 *
169 * @param work
170 * The application-defined function to invoke on the target queue. The first
171 * parameter passed to this function is the context provided to
172 * dispatch_async_f().
173 * The result of passing NULL in this parameter is undefined.
174 */
175 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
176 DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
177 void
178 dispatch_async_f(dispatch_queue_t queue,
179 void *context,
180 dispatch_function_t work);
181
182 /*!
183 * @function dispatch_sync
184 *
185 * @abstract
186 * Submits a block for synchronous execution on a dispatch queue.
187 *
188 * @discussion
189 * Submits a block to a dispatch queue like dispatch_async(), however
190 * dispatch_sync() will not return until the block has finished.
191 *
192 * Calls to dispatch_sync() targeting the current queue will result
193 * in dead-lock. Use of dispatch_sync() is also subject to the same
194 * multi-party dead-lock problems that may result from the use of a mutex.
195 * Use of dispatch_async() is preferred.
196 *
197 * Unlike dispatch_async(), no retain is performed on the target queue. Because
198 * calls to this function are synchronous, the dispatch_sync() "borrows" the
199 * reference of the caller.
200 *
201 * As an optimization, dispatch_sync() invokes the block on the current
202 * thread when possible.
203 *
204 * @param queue
205 * The target dispatch queue to which the block is submitted.
206 * The result of passing NULL in this parameter is undefined.
207 *
208 * @param block
209 * The block to be invoked on the target dispatch queue.
210 * The result of passing NULL in this parameter is undefined.
211 */
212 #ifdef __BLOCKS__
213 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
214 DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
215 void
216 dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
217 #endif
218
219 /*!
220 * @function dispatch_sync_f
221 *
222 * @abstract
223 * Submits a function for synchronous execution on a dispatch queue.
224 *
225 * @discussion
226 * See dispatch_sync() for details.
227 *
228 * @param queue
229 * The target dispatch queue to which the function is submitted.
230 * The result of passing NULL in this parameter is undefined.
231 *
232 * @param context
233 * The application-defined context parameter to pass to the function.
234 *
235 * @param work
236 * The application-defined function to invoke on the target queue. The first
237 * parameter passed to this function is the context provided to
238 * dispatch_sync_f().
239 * The result of passing NULL in this parameter is undefined.
240 */
241 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
242 DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
243 void
244 dispatch_sync_f(dispatch_queue_t queue,
245 void *context,
246 dispatch_function_t work);
247
248 /*!
249 * @function dispatch_apply
250 *
251 * @abstract
252 * Submits a block to a dispatch queue for multiple invocations.
253 *
254 * @discussion
255 * Submits a block to a dispatch queue for multiple invocations. This function
256 * waits for the task block to complete before returning. If the target queue
257 * is a concurrent queue returned by dispatch_get_concurrent_queue(), the block
258 * may be invoked concurrently, and it must therefore be reentrant safe.
259 *
260 * Each invocation of the block will be passed the current index of iteration.
261 *
262 * @param iterations
263 * The number of iterations to perform.
264 *
265 * @param queue
266 * The target dispatch queue to which the block is submitted.
267 * The result of passing NULL in this parameter is undefined.
268 *
269 * @param block
270 * The block to be invoked the specified number of iterations.
271 * The result of passing NULL in this parameter is undefined.
272 */
273 #ifdef __BLOCKS__
274 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
275 DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
276 void
277 dispatch_apply(size_t iterations, dispatch_queue_t queue, void (^block)(size_t));
278 #endif
279
280 /*!
281 * @function dispatch_apply_f
282 *
283 * @abstract
284 * Submits a function to a dispatch queue for multiple invocations.
285 *
286 * @discussion
287 * See dispatch_apply() for details.
288 *
289 * @param iterations
290 * The number of iterations to perform.
291 *
292 * @param queue
293 * The target dispatch queue to which the function is submitted.
294 * The result of passing NULL in this parameter is undefined.
295 *
296 * @param context
297 * The application-defined context parameter to pass to the function.
298 *
299 * @param work
300 * The application-defined function to invoke on the target queue. The first
301 * parameter passed to this function is the context provided to
302 * dispatch_apply_f(). The second parameter passed to this function is the
303 * current index of iteration.
304 * The result of passing NULL in this parameter is undefined.
305 */
306 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
307 DISPATCH_NONNULL2 DISPATCH_NONNULL4 DISPATCH_NOTHROW
308 void
309 dispatch_apply_f(size_t iterations, dispatch_queue_t queue,
310 void *context,
311 void (*work)(void *, size_t));
312
313 /*!
314 * @function dispatch_get_current_queue
315 *
316 * @abstract
317 * Returns the queue on which the currently executing block is running.
318 *
319 * @discussion
320 * Returns the queue on which the currently executing block is running.
321 *
322 * When dispatch_get_current_queue() is called outside of the context of a
323 * submitted block, it will return the default concurrent queue.
324 *
325 * @result
326 * Returns the current queue.
327 */
328 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
329 DISPATCH_PURE DISPATCH_WARN_RESULT DISPATCH_NOTHROW
330 dispatch_queue_t
331 dispatch_get_current_queue(void);
332
333 /*!
334 * @function dispatch_get_main_queue
335 *
336 * @abstract
337 * Returns the default queue that is bound to the main thread.
338 *
339 * @discussion
340 * In order to invoke blocks submitted to the main queue, the application must
341 * call dispatch_main(), NSApplicationMain(), or use a CFRunLoop on the main
342 * thread.
343 *
344 * @result
345 * Returns the main queue. This queue is created automatically on behalf of
346 * the main thread before main() is called.
347 */
348 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
349 extern struct dispatch_queue_s _dispatch_main_q;
350 #define dispatch_get_main_queue() (&_dispatch_main_q)
351
352 /*!
353 * @enum dispatch_queue_priority_t
354 *
355 * @constant DISPATCH_QUEUE_PRIORITY_HIGH
356 * Items dispatched to the queue will run at high priority,
357 * i.e. the queue will be scheduled for execution before
358 * any default priority or low priority queue.
359 *
360 * @constant DISPATCH_QUEUE_PRIORITY_DEFAULT
361 * Items dispatched to the queue will run at the default
362 * priority, i.e. the queue will be scheduled for execution
363 * after all high priority queues have been scheduled, but
364 * before any low priority queues have been scheduled.
365 *
366 * @constant DISPATCH_QUEUE_PRIORITY_LOW
367 * Items dispatched to the queue will run at low priority,
368 * i.e. the queue will be scheduled for execution after all
369 * default priority and high priority queues have been
370 * scheduled.
371 */
372 enum {
373 DISPATCH_QUEUE_PRIORITY_HIGH = 2,
374 DISPATCH_QUEUE_PRIORITY_DEFAULT = 0,
375 DISPATCH_QUEUE_PRIORITY_LOW = -2,
376 };
377
378 /*!
379 * @function dispatch_get_global_queue
380 *
381 * @abstract
382 * Returns a well-known global concurrent queue of a given priority level.
383 *
384 * @discussion
385 * The well-known global concurrent queues may not be modified. Calls to
386 * dispatch_suspend(), dispatch_resume(), dispatch_set_context(), etc., will
387 * have no effect when used with queues returned by this function.
388 *
389 * @param priority
390 * A priority defined in dispatch_queue_priority_t
391 *
392 * @param flags
393 * Reserved for future use. Passing any value other than zero may result in
394 * a NULL return value.
395 *
396 * @result
397 * Returns the requested global queue.
398 */
399 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
400 DISPATCH_PURE DISPATCH_WARN_RESULT DISPATCH_NOTHROW
401 dispatch_queue_t
402 dispatch_get_global_queue(long priority, unsigned long flags);
403
404 /*!
405 * @function dispatch_queue_create
406 *
407 * @abstract
408 * Creates a new dispatch queue to which blocks may be submitted.
409 *
410 * @discussion
411 * Dispatch queues invoke blocks serially in FIFO order.
412 *
413 * When the dispatch queue is no longer needed, it should be released
414 * with dispatch_release(). Note that any pending blocks submitted
415 * to a queue will hold a reference to that queue. Therefore a queue
416 * will not be deallocated until all pending blocks have finished.
417 *
418 * @param label
419 * A string label to attach to the queue.
420 * This parameter is optional and may be NULL.
421 *
422 * @param attr
423 * Unused. Pass NULL for now.
424 *
425 * @result
426 * The newly created dispatch queue.
427 */
428 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
429 DISPATCH_MALLOC DISPATCH_WARN_RESULT DISPATCH_NOTHROW
430 dispatch_queue_t
431 dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);
432
433 /*!
434 * @function dispatch_queue_get_label
435 *
436 * @abstract
437 * Returns the label of the queue that was specified when the
438 * queue was created.
439 *
440 * @param queue
441 * The result of passing NULL in this parameter is undefined.
442 *
443 * @result
444 * The label of the queue. The result may be NULL.
445 */
446 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
447 DISPATCH_NONNULL_ALL DISPATCH_PURE DISPATCH_WARN_RESULT DISPATCH_NOTHROW
448 const char *
449 dispatch_queue_get_label(dispatch_queue_t queue);
450
451 /*!
452 * @function dispatch_set_target_queue
453 *
454 * @abstract
455 * Sets the target queue for the given object.
456 *
457 * @discussion
458 * An object's target queue is responsible for processing the object.
459 *
460 * A dispatch queue's priority is inherited by its target queue. Use the
461 * dispatch_get_global_queue() function to obtain suitable target queue
462 * of the desired priority.
463 *
464 * A dispatch source's target queue specifies where its event handler and
465 * cancellation handler blocks will be submitted.
466 *
467 * The result of calling dispatch_set_target_queue() on any other type of
468 * dispatch object is undefined.
469 *
470 * @param object
471 * The object to modify.
472 * The result of passing NULL in this parameter is undefined.
473 *
474 * @param queue
475 * The new target queue for the object. The queue is retained, and the
476 * previous one, if any, is released.
477 * The result of passing NULL in this parameter is undefined.
478 */
479 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
480 DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
481 void
482 dispatch_set_target_queue(dispatch_object_t object, dispatch_queue_t queue);
483
484 /*!
485 * @function dispatch_main
486 *
487 * @abstract
488 * Execute blocks submitted to the main queue.
489 *
490 * @discussion
491 * This function "parks" the main thread and waits for blocks to be submitted
492 * to the main queue. This function never returns.
493 *
494 * Applications that call NSApplicationMain() or CFRunLoopRun() on the
495 * main thread do not need to call dispatch_main().
496 */
497 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
498 DISPATCH_NOTHROW DISPATCH_NORETURN
499 void
500 dispatch_main(void);
501
502 /*!
503 * @function dispatch_after
504 *
505 * @abstract
506 * Schedule a block for execution on a given queue at a specified time.
507 *
508 * @discussion
509 * Passing DISPATCH_TIME_NOW as the "when" parameter is supported, but not as
510 * optimal as calling dispatch_async() instead. Passing DISPATCH_TIME_FOREVER
511 * is undefined.
512 *
513 * @param when
514 * A temporal milestone returned by dispatch_time() or dispatch_walltime().
515 *
516 * @param queue
517 * A queue to which the given block will be submitted at the specified time.
518 * The result of passing NULL in this parameter is undefined.
519 *
520 * @param block
521 * The block of code to execute.
522 * The result of passing NULL in this parameter is undefined.
523 */
524 #ifdef __BLOCKS__
525 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
526 DISPATCH_NONNULL2 DISPATCH_NONNULL3 DISPATCH_NOTHROW
527 void
528 dispatch_after(dispatch_time_t when,
529 dispatch_queue_t queue,
530 dispatch_block_t block);
531 #endif
532
533 /*!
534 * @function dispatch_after_f
535 *
536 * @abstract
537 * Schedule a function for execution on a given queue at a specified time.
538 *
539 * @discussion
540 * See dispatch_after() for details.
541 *
542 * @param when
543 * A temporal milestone returned by dispatch_time() or dispatch_walltime().
544 *
545 * @param queue
546 * A queue to which the given function will be submitted at the specified time.
547 * The result of passing NULL in this parameter is undefined.
548 *
549 * @param context
550 * The application-defined context parameter to pass to the function.
551 *
552 * @param work
553 * The application-defined function to invoke on the target queue. The first
554 * parameter passed to this function is the context provided to
555 * dispatch_after_f().
556 * The result of passing NULL in this parameter is undefined.
557 */
558 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_NA)
559 DISPATCH_NONNULL2 DISPATCH_NONNULL4 DISPATCH_NOTHROW
560 void
561 dispatch_after_f(dispatch_time_t when,
562 dispatch_queue_t queue,
563 void *context,
564 dispatch_function_t work);
565
566 __END_DECLS
567
568 #endif