1/*
2 * Copyright (c) 2008-2014 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 */
67DISPATCH_DECL(dispatch_queue);
68
69__BEGIN_DECLS
70
71/*!
72 * @function dispatch_async
73 *
74 * @abstract
75 * Submits a block for asynchronous execution on a dispatch queue.
76 *
77 * @discussion
78 * The dispatch_async() function is the fundamental mechanism for submitting
79 * blocks to a dispatch queue.
80 *
81 * Calls to dispatch_async() always return immediately after the block has
82 * been submitted, and never wait for the block to be invoked.
83 *
84 * The target queue determines whether the block will be invoked serially or
85 * concurrently with respect to other blocks submitted to that same queue.
86 * Serial queues are processed concurrently with respect to each other.
87 *
88 * @param queue
89 * The target dispatch queue to which the block is submitted.
90 * The system will hold a reference on the target queue until the block
91 * has finished.
92 * The result of passing NULL in this parameter is undefined.
93 *
94 * @param block
95 * The block to submit to the target dispatch queue. This function performs
96 * Block_copy() and Block_release() on behalf of callers.
97 * The result of passing NULL in this parameter is undefined.
98 */
99#ifdef __BLOCKS__
100__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
101DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
102void
103dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
104#endif
105
106/*!
107 * @function dispatch_async_f
108 *
109 * @abstract
110 * Submits a function for asynchronous execution on a dispatch queue.
111 *
112 * @discussion
113 * See dispatch_async() for details.
114 *
115 * @param queue
116 * The target dispatch queue to which the function is submitted.
117 * The system will hold a reference on the target queue until the function
118 * has returned.
119 * The result of passing NULL in this parameter is undefined.
120 *
121 * @param context
122 * The application-defined context parameter to pass to the function.
123 *
124 * @param work
125 * The application-defined function to invoke on the target queue. The first
126 * parameter passed to this function is the context provided to
127 * dispatch_async_f().
128 * The result of passing NULL in this parameter is undefined.
129 */
130__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
131DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
132void
133dispatch_async_f(dispatch_queue_t queue,
134	void *context,
135	dispatch_function_t work);
136
137/*!
138 * @function dispatch_sync
139 *
140 * @abstract
141 * Submits a block for synchronous execution on a dispatch queue.
142 *
143 * @discussion
144 * Submits a block to a dispatch queue like dispatch_async(), however
145 * dispatch_sync() will not return until the block has finished.
146 *
147 * Calls to dispatch_sync() targeting the current queue will result
148 * in dead-lock. Use of dispatch_sync() is also subject to the same
149 * multi-party dead-lock problems that may result from the use of a mutex.
150 * Use of dispatch_async() is preferred.
151 *
152 * Unlike dispatch_async(), no retain is performed on the target queue. Because
153 * calls to this function are synchronous, the dispatch_sync() "borrows" the
154 * reference of the caller.
155 *
156 * As an optimization, dispatch_sync() invokes the block on the current
157 * thread when possible.
158 *
159 * @param queue
160 * The target dispatch queue to which the block is submitted.
161 * The result of passing NULL in this parameter is undefined.
162 *
163 * @param block
164 * The block to be invoked on the target dispatch queue.
165 * The result of passing NULL in this parameter is undefined.
166 */
167#ifdef __BLOCKS__
168__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
169DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
170void
171dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
172#endif
173
174/*!
175 * @function dispatch_sync_f
176 *
177 * @abstract
178 * Submits a function for synchronous execution on a dispatch queue.
179 *
180 * @discussion
181 * See dispatch_sync() for details.
182 *
183 * @param queue
184 * The target dispatch queue to which the function is submitted.
185 * The result of passing NULL in this parameter is undefined.
186 *
187 * @param context
188 * The application-defined context parameter to pass to the function.
189 *
190 * @param work
191 * The application-defined function to invoke on the target queue. The first
192 * parameter passed to this function is the context provided to
193 * dispatch_sync_f().
194 * The result of passing NULL in this parameter is undefined.
195 */
196__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
197DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
198void
199dispatch_sync_f(dispatch_queue_t queue,
200	void *context,
201	dispatch_function_t work);
202
203/*!
204 * @function dispatch_apply
205 *
206 * @abstract
207 * Submits a block to a dispatch queue for multiple invocations.
208 *
209 * @discussion
210 * Submits a block to a dispatch queue for multiple invocations. This function
211 * waits for the task block to complete before returning. If the target queue
212 * is concurrent, the block may be invoked concurrently, and it must therefore
213 * be reentrant safe.
214 *
215 * Each invocation of the block will be passed the current index of iteration.
216 *
217 * @param iterations
218 * The number of iterations to perform.
219 *
220 * @param queue
221 * The target dispatch queue to which the block is submitted.
222 * The result of passing NULL in this parameter is undefined.
223 *
224 * @param block
225 * The block to be invoked the specified number of iterations.
226 * The result of passing NULL in this parameter is undefined.
227 */
228#ifdef __BLOCKS__
229__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
230DISPATCH_EXPORT DISPATCH_NONNULL3 DISPATCH_NOTHROW
231void
232dispatch_apply(size_t iterations, dispatch_queue_t queue,
233		void (^block)(size_t));
234#endif
235
236/*!
237 * @function dispatch_apply_f
238 *
239 * @abstract
240 * Submits a function to a dispatch queue for multiple invocations.
241 *
242 * @discussion
243 * See dispatch_apply() for details.
244 *
245 * @param iterations
246 * The number of iterations to perform.
247 *
248 * @param queue
249 * The target dispatch queue to which the function is submitted.
250 * The result of passing NULL in this parameter is undefined.
251 *
252 * @param context
253 * The application-defined context parameter to pass to the function.
254 *
255 * @param work
256 * The application-defined function to invoke on the target queue. The first
257 * parameter passed to this function is the context provided to
258 * dispatch_apply_f(). The second parameter passed to this function is the
259 * current index of iteration.
260 * The result of passing NULL in this parameter is undefined.
261 */
262__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
263DISPATCH_EXPORT DISPATCH_NONNULL4 DISPATCH_NOTHROW
264void
265dispatch_apply_f(size_t iterations, dispatch_queue_t queue,
266	void *context,
267	void (*work)(void *, size_t));
268
269/*!
270 * @function dispatch_get_current_queue
271 *
272 * @abstract
273 * Returns the queue on which the currently executing block is running.
274 *
275 * @discussion
276 * Returns the queue on which the currently executing block is running.
277 *
278 * When dispatch_get_current_queue() is called outside of the context of a
279 * submitted block, it will return the default concurrent queue.
280 *
281 * Recommended for debugging and logging purposes only:
282 * The code must not make any assumptions about the queue returned, unless it
283 * is one of the global queues or a queue the code has itself created.
284 * The code must not assume that synchronous execution onto a queue is safe
285 * from deadlock if that queue is not the one returned by
286 * dispatch_get_current_queue().
287 *
288 * When dispatch_get_current_queue() is called on the main thread, it may
289 * or may not return the same value as dispatch_get_main_queue(). Comparing
290 * the two is not a valid way to test whether code is executing on the
291 * main thread.
292 *
293 * This function is deprecated and will be removed in a future release.
294 *
295 * @result
296 * Returns the current queue.
297 */
298__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6,__MAC_10_9,__IPHONE_4_0,__IPHONE_6_0)
299DISPATCH_EXPORT DISPATCH_PURE DISPATCH_WARN_RESULT DISPATCH_NOTHROW
300dispatch_queue_t
301dispatch_get_current_queue(void);
302
303__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
304DISPATCH_EXPORT struct dispatch_queue_s _dispatch_main_q;
305
306/*!
307 * @function dispatch_get_main_queue
308 *
309 * @abstract
310 * Returns the default queue that is bound to the main thread.
311 *
312 * @discussion
313 * In order to invoke blocks submitted to the main queue, the application must
314 * call dispatch_main(), NSApplicationMain(), or use a CFRunLoop on the main
315 * thread.
316 *
317 * @result
318 * Returns the main queue. This queue is created automatically on behalf of
319 * the main thread before main() is called.
320 */
321DISPATCH_INLINE DISPATCH_ALWAYS_INLINE DISPATCH_CONST DISPATCH_NOTHROW
322dispatch_queue_t
323dispatch_get_main_queue(void)
324{
325	return DISPATCH_GLOBAL_OBJECT(dispatch_queue_t, _dispatch_main_q);
326}
327
328/*!
329 * @typedef dispatch_queue_priority_t
330 * Type of dispatch_queue_priority
331 *
332 * @constant DISPATCH_QUEUE_PRIORITY_HIGH
333 * Items dispatched to the queue will run at high priority,
334 * i.e. the queue will be scheduled for execution before
335 * any default priority or low priority queue.
336 *
337 * @constant DISPATCH_QUEUE_PRIORITY_DEFAULT
338 * Items dispatched to the queue will run at the default
339 * priority, i.e. the queue will be scheduled for execution
340 * after all high priority queues have been scheduled, but
341 * before any low priority queues have been scheduled.
342 *
343 * @constant DISPATCH_QUEUE_PRIORITY_LOW
344 * Items dispatched to the queue will run at low priority,
345 * i.e. the queue will be scheduled for execution after all
346 * default priority and high priority queues have been
347 * scheduled.
348 *
349 * @constant DISPATCH_QUEUE_PRIORITY_BACKGROUND
350 * Items dispatched to the queue will run at background priority, i.e. the queue
351 * will be scheduled for execution after all higher priority queues have been
352 * scheduled and the system will run items on this queue on a thread with
353 * background status as per setpriority(2) (i.e. disk I/O is throttled and the
354 * thread's scheduling priority is set to lowest value).
355 */
356#define DISPATCH_QUEUE_PRIORITY_HIGH 2
357#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
358#define DISPATCH_QUEUE_PRIORITY_LOW (-2)
359#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
360
361typedef long dispatch_queue_priority_t;
362
363/*!
364 * @typedef dispatch_qos_class_t
365 * Alias for qos_class_t type.
366 */
367#if __has_include(<sys/qos.h>)
368#include <sys/qos.h>
369typedef qos_class_t dispatch_qos_class_t;
370#else
371typedef unsigned int dispatch_qos_class_t;
372#endif
373
374/*!
375 * @function dispatch_get_global_queue
376 *
377 * @abstract
378 * Returns a well-known global concurrent queue of a given quality of service
379 * class.
380 *
381 * @discussion
382 * The well-known global concurrent queues may not be modified. Calls to
383 * dispatch_suspend(), dispatch_resume(), dispatch_set_context(), etc., will
384 * have no effect when used with queues returned by this function.
385 *
386 * @param identifier
387 * A quality of service class defined in qos_class_t or a priority defined in
388 * dispatch_queue_priority_t.
389 *
390 * It is recommended to use quality of service class values to identify the
391 * well-known global concurrent queues:
392 *  - QOS_CLASS_USER_INTERACTIVE
393 *  - QOS_CLASS_USER_INITIATED
394 *  - QOS_CLASS_DEFAULT
395 *  - QOS_CLASS_UTILITY
396 *  - QOS_CLASS_BACKGROUND
397 *
398 * The global concurrent queues may still be identified by their priority,
399 * which map to the following QOS classes:
400 *  - DISPATCH_QUEUE_PRIORITY_HIGH:         QOS_CLASS_USER_INITIATED
401 *  - DISPATCH_QUEUE_PRIORITY_DEFAULT:      QOS_CLASS_DEFAULT
402 *  - DISPATCH_QUEUE_PRIORITY_LOW:          QOS_CLASS_UTILITY
403 *  - DISPATCH_QUEUE_PRIORITY_BACKGROUND:   QOS_CLASS_BACKGROUND
404 *
405 * @param flags
406 * Reserved for future use. Passing any value other than zero may result in
407 * a NULL return value.
408 *
409 * @result
410 * Returns the requested global queue or NULL if the requested global queue
411 * does not exist.
412 */
413__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
414DISPATCH_EXPORT DISPATCH_CONST DISPATCH_WARN_RESULT DISPATCH_NOTHROW
415dispatch_queue_t
416dispatch_get_global_queue(long identifier, unsigned long flags);
417
418/*!
419 * @typedef dispatch_queue_attr_t
420 *
421 * @abstract
422 * Attribute for dispatch queues.
423 */
424DISPATCH_DECL(dispatch_queue_attr);
425
426/*!
427 * @const DISPATCH_QUEUE_SERIAL
428 * @discussion A dispatch queue that invokes blocks serially in FIFO order.
429 */
430#define DISPATCH_QUEUE_SERIAL NULL
431
432/*!
433 * @const DISPATCH_QUEUE_CONCURRENT
434 * @discussion A dispatch queue that may invoke blocks concurrently and supports
435 * barrier blocks submitted with the dispatch barrier API.
436 */
437#define DISPATCH_QUEUE_CONCURRENT \
438		DISPATCH_GLOBAL_OBJECT(dispatch_queue_attr_t, \
439		_dispatch_queue_attr_concurrent)
440__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_3)
441DISPATCH_EXPORT
442struct dispatch_queue_attr_s _dispatch_queue_attr_concurrent;
443
444/*!
445 * @function dispatch_queue_attr_make_with_qos_class
446 *
447 * @abstract
448 * Returns an attribute value which may be provided to dispatch_queue_create()
449 * in order to assign a QOS class and relative priority to the queue.
450 *
451 * @discussion
452 * When specified in this manner, the QOS class and relative priority take
453 * precedence over those inherited from the dispatch queue's target queue (if
454 * any) as long that does not result in a lower QOS class and relative priority.
455 *
456 * The global queue priorities map to the following QOS classes:
457 *  - DISPATCH_QUEUE_PRIORITY_HIGH:         QOS_CLASS_USER_INITIATED
458 *  - DISPATCH_QUEUE_PRIORITY_DEFAULT:      QOS_CLASS_DEFAULT
459 *  - DISPATCH_QUEUE_PRIORITY_LOW:          QOS_CLASS_UTILITY
460 *  - DISPATCH_QUEUE_PRIORITY_BACKGROUND:   QOS_CLASS_BACKGROUND
461 *
462 * Example:
463 * <code>
464 *	dispatch_queue_t queue;
465 *	dispatch_queue_attr_t attr;
466 *	attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL,
467 *			QOS_CLASS_UTILITY, 0);
468 *	queue = dispatch_queue_create("com.example.myqueue", attr);
469 * </code>
470 *
471 * @param attr
472 * A queue attribute value to be combined with the QOS class, or NULL.
473 *
474 * @param qos_class
475 * A QOS class value:
476 *  - QOS_CLASS_USER_INTERACTIVE
477 *  - QOS_CLASS_USER_INITIATED
478 *  - QOS_CLASS_DEFAULT
479 *  - QOS_CLASS_UTILITY
480 *  - QOS_CLASS_BACKGROUND
481 * Passing any other value results in NULL being returned.
482 *
483 * @param relative_priority
484 * A relative priority within the QOS class. This value is a negative
485 * offset from the maximum supported scheduler priority for the given class.
486 * Passing a value greater than zero or less than QOS_MIN_RELATIVE_PRIORITY
487 * results in NULL being returned.
488 *
489 * @return
490 * Returns an attribute value which may be provided to dispatch_queue_create(),
491 * or NULL if an invalid QOS class was requested.
492 * The new value combines the attributes specified by the 'attr' parameter and
493 * the new QOS class and relative priority.
494 */
495__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0)
496DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_PURE DISPATCH_NOTHROW
497dispatch_queue_attr_t
498dispatch_queue_attr_make_with_qos_class(dispatch_queue_attr_t attr,
499		dispatch_qos_class_t qos_class, int relative_priority);
500
501/*!
502 * @function dispatch_queue_create
503 *
504 * @abstract
505 * Creates a new dispatch queue to which blocks may be submitted.
506 *
507 * @discussion
508 * Dispatch queues created with the DISPATCH_QUEUE_SERIAL or a NULL attribute
509 * invoke blocks serially in FIFO order.
510 *
511 * Dispatch queues created with the DISPATCH_QUEUE_CONCURRENT attribute may
512 * invoke blocks concurrently (similarly to the global concurrent queues, but
513 * potentially with more overhead), and support barrier blocks submitted with
514 * the dispatch barrier API, which e.g. enables the implementation of efficient
515 * reader-writer schemes.
516 *
517 * When a dispatch queue is no longer needed, it should be released with
518 * dispatch_release(). Note that any pending blocks submitted to a queue will
519 * hold a reference to that queue. Therefore a queue will not be deallocated
520 * until all pending blocks have finished.
521 *
522 * Passing the result of the dispatch_queue_attr_make_with_qos_class() function
523 * to the attr parameter of this function allows a quality of service class and
524 * relative priority to be specified for the newly created queue.
525 * The quality of service class so specified takes precedence over the quality
526 * of service class of the newly created dispatch queue's target queue (if any)
527 * as long that does not result in a lower QOS class and relative priority.
528 *
529 * When no quality of service class is specified, the target queue of a newly
530 * created dispatch queue is the default priority global concurrent queue.
531 *
532 * @param label
533 * A string label to attach to the queue.
534 * This parameter is optional and may be NULL.
535 *
536 * @param attr
537 * DISPATCH_QUEUE_SERIAL, DISPATCH_QUEUE_CONCURRENT, or the result of a call to
538 * the function dispatch_queue_attr_make_with_qos_class().
539 *
540 * @result
541 * The newly created dispatch queue.
542 */
543__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
544DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
545DISPATCH_NOTHROW
546dispatch_queue_t
547dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);
548
549/*!
550 * @const DISPATCH_CURRENT_QUEUE_LABEL
551 * @discussion Constant to pass to the dispatch_queue_get_label() function to
552 * retrieve the label of the current queue.
553 */
554#define DISPATCH_CURRENT_QUEUE_LABEL NULL
555
556/*!
557 * @function dispatch_queue_get_label
558 *
559 * @abstract
560 * Returns the label of the given queue, as specified when the queue was
561 * created, or the empty string if a NULL label was specified.
562 *
563 * Passing DISPATCH_CURRENT_QUEUE_LABEL will return the label of the current
564 * queue.
565 *
566 * @param queue
567 * The queue to query, or DISPATCH_CURRENT_QUEUE_LABEL.
568 *
569 * @result
570 * The label of the queue.
571 */
572__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
573DISPATCH_EXPORT DISPATCH_PURE DISPATCH_WARN_RESULT DISPATCH_NOTHROW
574const char *
575dispatch_queue_get_label(dispatch_queue_t queue);
576
577/*!
578 * @function dispatch_queue_get_qos_class
579 *
580 * @abstract
581 * Returns the QOS class and relative priority of the given queue.
582 *
583 * @discussion
584 * If the given queue was created with an attribute value returned from
585 * dispatch_queue_attr_make_with_qos_class(), this function returns the QOS
586 * class and relative priority specified at that time; for any other attribute
587 * value it returns a QOS class of QOS_CLASS_UNSPECIFIED and a relative
588 * priority of 0.
589 *
590 * If the given queue is one of the global queues, this function returns its
591 * assigned QOS class value as documented under dispatch_get_global_queue() and
592 * a relative priority of 0; in the case of the main queue it returns the QOS
593 * value provided by qos_class_main() and a relative priority of 0.
594 *
595 * @param queue
596 * The queue to query.
597 *
598 * @param relative_priority_ptr
599 * A pointer to an int variable to be filled with the relative priority offset
600 * within the QOS class, or NULL.
601 *
602 * @return
603 * A QOS class value:
604 *	- QOS_CLASS_USER_INTERACTIVE
605 *	- QOS_CLASS_USER_INITIATED
606 *	- QOS_CLASS_DEFAULT
607 *	- QOS_CLASS_UTILITY
608 *	- QOS_CLASS_BACKGROUND
609 *	- QOS_CLASS_UNSPECIFIED
610 */
611__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0)
612DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_NONNULL1 DISPATCH_NOTHROW
613dispatch_qos_class_t
614dispatch_queue_get_qos_class(dispatch_queue_t queue,
615		int *relative_priority_ptr);
616
617/*!
618 * @const DISPATCH_TARGET_QUEUE_DEFAULT
619 * @discussion Constant to pass to the dispatch_set_target_queue() and
620 * dispatch_source_create() functions to indicate that the default target queue
621 * for the given object type should be used.
622 */
623#define DISPATCH_TARGET_QUEUE_DEFAULT NULL
624
625/*!
626 * @function dispatch_set_target_queue
627 *
628 * @abstract
629 * Sets the target queue for the given object.
630 *
631 * @discussion
632 * An object's target queue is responsible for processing the object.
633 *
634 * When no quality of service class and relative priority is specified for a
635 * dispatch queue at the time of creation, a dispatch queue's quality of service
636 * class is inherited from its target queue. The dispatch_get_global_queue()
637 * function may be used to obtain a target queue of a specific quality of
638 * service class, however the use of dispatch_queue_attr_make_with_qos_class()
639 * is recommended instead.
640 *
641 * Blocks submitted to a serial queue whose target queue is another serial
642 * queue will not be invoked concurrently with blocks submitted to the target
643 * queue or to any other queue with that same target queue.
644 *
645 * The result of introducing a cycle into the hierarchy of target queues is
646 * undefined.
647 *
648 * A dispatch source's target queue specifies where its event handler and
649 * cancellation handler blocks will be submitted.
650 *
651 * A dispatch I/O channel's target queue specifies where where its I/O
652 * operations are executed. If the channel's target queue's priority is set to
653 * DISPATCH_QUEUE_PRIORITY_BACKGROUND, then the I/O operations performed by
654 * dispatch_io_read() or dispatch_io_write() on that queue will be
655 * throttled when there is I/O contention.
656 *
657 * For all other dispatch object types, the only function of the target queue
658 * is to determine where an object's finalizer function is invoked.
659 *
660 * @param object
661 * The object to modify.
662 * The result of passing NULL in this parameter is undefined.
663 *
664 * @param queue
665 * The new target queue for the object. The queue is retained, and the
666 * previous target queue, if any, is released.
667 * If queue is DISPATCH_TARGET_QUEUE_DEFAULT, set the object's target queue
668 * to the default target queue for the given object type.
669 */
670__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
671DISPATCH_EXPORT DISPATCH_NOTHROW // DISPATCH_NONNULL1
672void
673dispatch_set_target_queue(dispatch_object_t object, dispatch_queue_t queue);
674
675/*!
676 * @function dispatch_main
677 *
678 * @abstract
679 * Execute blocks submitted to the main queue.
680 *
681 * @discussion
682 * This function "parks" the main thread and waits for blocks to be submitted
683 * to the main queue. This function never returns.
684 *
685 * Applications that call NSApplicationMain() or CFRunLoopRun() on the
686 * main thread do not need to call dispatch_main().
687 */
688__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
689DISPATCH_EXPORT DISPATCH_NOTHROW DISPATCH_NORETURN
690void
691dispatch_main(void);
692
693/*!
694 * @function dispatch_after
695 *
696 * @abstract
697 * Schedule a block for execution on a given queue at a specified time.
698 *
699 * @discussion
700 * Passing DISPATCH_TIME_NOW as the "when" parameter is supported, but not as
701 * optimal as calling dispatch_async() instead. Passing DISPATCH_TIME_FOREVER
702 * is undefined.
703 *
704 * @param when
705 * A temporal milestone returned by dispatch_time() or dispatch_walltime().
706 *
707 * @param queue
708 * A queue to which the given block will be submitted at the specified time.
709 * The result of passing NULL in this parameter is undefined.
710 *
711 * @param block
712 * The block of code to execute.
713 * The result of passing NULL in this parameter is undefined.
714 */
715#ifdef __BLOCKS__
716__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
717DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NONNULL3 DISPATCH_NOTHROW
718void
719dispatch_after(dispatch_time_t when,
720	dispatch_queue_t queue,
721	dispatch_block_t block);
722#endif
723
724/*!
725 * @function dispatch_after_f
726 *
727 * @abstract
728 * Schedule a function for execution on a given queue at a specified time.
729 *
730 * @discussion
731 * See dispatch_after() for details.
732 *
733 * @param when
734 * A temporal milestone returned by dispatch_time() or dispatch_walltime().
735 *
736 * @param queue
737 * A queue to which the given function will be submitted at the specified time.
738 * The result of passing NULL in this parameter is undefined.
739 *
740 * @param context
741 * The application-defined context parameter to pass to the function.
742 *
743 * @param work
744 * The application-defined function to invoke on the target queue. The first
745 * parameter passed to this function is the context provided to
746 * dispatch_after_f().
747 * The result of passing NULL in this parameter is undefined.
748 */
749__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
750DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NONNULL4 DISPATCH_NOTHROW
751void
752dispatch_after_f(dispatch_time_t when,
753	dispatch_queue_t queue,
754	void *context,
755	dispatch_function_t work);
756
757/*!
758 * @functiongroup Dispatch Barrier API
759 * The dispatch barrier API is a mechanism for submitting barrier blocks to a
760 * dispatch queue, analogous to the dispatch_async()/dispatch_sync() API.
761 * It enables the implementation of efficient reader/writer schemes.
762 * Barrier blocks only behave specially when submitted to queues created with
763 * the DISPATCH_QUEUE_CONCURRENT attribute; on such a queue, a barrier block
764 * will not run until all blocks submitted to the queue earlier have completed,
765 * and any blocks submitted to the queue after a barrier block will not run
766 * until the barrier block has completed.
767 * When submitted to a a global queue or to a queue not created with the
768 * DISPATCH_QUEUE_CONCURRENT attribute, barrier blocks behave identically to
769 * blocks submitted with the dispatch_async()/dispatch_sync() API.
770 */
771
772/*!
773 * @function dispatch_barrier_async
774 *
775 * @abstract
776 * Submits a barrier block for asynchronous execution on a dispatch queue.
777 *
778 * @discussion
779 * Submits a block to a dispatch queue like dispatch_async(), but marks that
780 * block as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT queues).
781 *
782 * See dispatch_async() for details.
783 *
784 * @param queue
785 * The target dispatch queue to which the block is submitted.
786 * The system will hold a reference on the target queue until the block
787 * has finished.
788 * The result of passing NULL in this parameter is undefined.
789 *
790 * @param block
791 * The block to submit to the target dispatch queue. This function performs
792 * Block_copy() and Block_release() on behalf of callers.
793 * The result of passing NULL in this parameter is undefined.
794 */
795#ifdef __BLOCKS__
796__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_3)
797DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
798void
799dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
800#endif
801
802/*!
803 * @function dispatch_barrier_async_f
804 *
805 * @abstract
806 * Submits a barrier function for asynchronous execution on a dispatch queue.
807 *
808 * @discussion
809 * Submits a function to a dispatch queue like dispatch_async_f(), but marks
810 * that function as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT
811 * queues).
812 *
813 * See dispatch_async_f() for details.
814 *
815 * @param queue
816 * The target dispatch queue to which the function is submitted.
817 * The system will hold a reference on the target queue until the function
818 * has returned.
819 * The result of passing NULL in this parameter is undefined.
820 *
821 * @param context
822 * The application-defined context parameter to pass to the function.
823 *
824 * @param work
825 * The application-defined function to invoke on the target queue. The first
826 * parameter passed to this function is the context provided to
827 * dispatch_barrier_async_f().
828 * The result of passing NULL in this parameter is undefined.
829 */
830__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_3)
831DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
832void
833dispatch_barrier_async_f(dispatch_queue_t queue,
834	void *context,
835	dispatch_function_t work);
836
837/*!
838 * @function dispatch_barrier_sync
839 *
840 * @abstract
841 * Submits a barrier block for synchronous execution on a dispatch queue.
842 *
843 * @discussion
844 * Submits a block to a dispatch queue like dispatch_sync(), but marks that
845 * block as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT queues).
846 *
847 * See dispatch_sync() for details.
848 *
849 * @param queue
850 * The target dispatch queue to which the block is submitted.
851 * The result of passing NULL in this parameter is undefined.
852 *
853 * @param block
854 * The block to be invoked on the target dispatch queue.
855 * The result of passing NULL in this parameter is undefined.
856 */
857#ifdef __BLOCKS__
858__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_3)
859DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
860void
861dispatch_barrier_sync(dispatch_queue_t queue, dispatch_block_t block);
862#endif
863
864/*!
865 * @function dispatch_barrier_sync_f
866 *
867 * @abstract
868 * Submits a barrier function for synchronous execution on a dispatch queue.
869 *
870 * @discussion
871 * Submits a function to a dispatch queue like dispatch_sync_f(), but marks that
872 * fuction as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT queues).
873 *
874 * See dispatch_sync_f() for details.
875 *
876 * @param queue
877 * The target dispatch queue to which the function is submitted.
878 * The result of passing NULL in this parameter is undefined.
879 *
880 * @param context
881 * The application-defined context parameter to pass to the function.
882 *
883 * @param work
884 * The application-defined function to invoke on the target queue. The first
885 * parameter passed to this function is the context provided to
886 * dispatch_barrier_sync_f().
887 * The result of passing NULL in this parameter is undefined.
888 */
889__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_3)
890DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
891void
892dispatch_barrier_sync_f(dispatch_queue_t queue,
893	void *context,
894	dispatch_function_t work);
895
896/*!
897 * @functiongroup Dispatch queue-specific contexts
898 * This API allows different subsystems to associate context to a shared queue
899 * without risk of collision and to retrieve that context from blocks executing
900 * on that queue or any of its child queues in the target queue hierarchy.
901 */
902
903/*!
904 * @function dispatch_queue_set_specific
905 *
906 * @abstract
907 * Associates a subsystem-specific context with a dispatch queue, for a key
908 * unique to the subsystem.
909 *
910 * @discussion
911 * The specified destructor will be invoked with the context on the default
912 * priority global concurrent queue when a new context is set for the same key,
913 * or after all references to the queue have been released.
914 *
915 * @param queue
916 * The dispatch queue to modify.
917 * The result of passing NULL in this parameter is undefined.
918 *
919 * @param key
920 * The key to set the context for, typically a pointer to a static variable
921 * specific to the subsystem. Keys are only compared as pointers and never
922 * dereferenced. Passing a string constant directly is not recommended.
923 * The NULL key is reserved and attemps to set a context for it are ignored.
924 *
925 * @param context
926 * The new subsystem-specific context for the object. This may be NULL.
927 *
928 * @param destructor
929 * The destructor function pointer. This may be NULL and is ignored if context
930 * is NULL.
931 */
932__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0)
933DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL2 DISPATCH_NOTHROW
934void
935dispatch_queue_set_specific(dispatch_queue_t queue, const void *key,
936	void *context, dispatch_function_t destructor);
937
938/*!
939 * @function dispatch_queue_get_specific
940 *
941 * @abstract
942 * Returns the subsystem-specific context associated with a dispatch queue, for
943 * a key unique to the subsystem.
944 *
945 * @discussion
946 * Returns the context for the specified key if it has been set on the specified
947 * queue.
948 *
949 * @param queue
950 * The dispatch queue to query.
951 * The result of passing NULL in this parameter is undefined.
952 *
953 * @param key
954 * The key to get the context for, typically a pointer to a static variable
955 * specific to the subsystem. Keys are only compared as pointers and never
956 * dereferenced. Passing a string constant directly is not recommended.
957 *
958 * @result
959 * The context for the specified key or NULL if no context was found.
960 */
961__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0)
962DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_PURE DISPATCH_WARN_RESULT
963DISPATCH_NOTHROW
964void *
965dispatch_queue_get_specific(dispatch_queue_t queue, const void *key);
966
967/*!
968 * @function dispatch_get_specific
969 *
970 * @abstract
971 * Returns the current subsystem-specific context for a key unique to the
972 * subsystem.
973 *
974 * @discussion
975 * When called from a block executing on a queue, returns the context for the
976 * specified key if it has been set on the queue, otherwise returns the result
977 * of dispatch_get_specific() executed on the queue's target queue or NULL
978 * if the current queue is a global concurrent queue.
979 *
980 * @param key
981 * The key to get the context for, typically a pointer to a static variable
982 * specific to the subsystem. Keys are only compared as pointers and never
983 * dereferenced. Passing a string constant directly is not recommended.
984 *
985 * @result
986 * The context for the specified key or NULL if no context was found.
987 */
988__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0)
989DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_PURE DISPATCH_WARN_RESULT
990DISPATCH_NOTHROW
991void *
992dispatch_get_specific(const void *key);
993
994__END_DECLS
995
996#endif
997