]> git.saurik.com Git - apple/libdispatch.git/blob - dispatch/queue.h
libdispatch-913.1.6.tar.gz
[apple/libdispatch.git] / dispatch / queue.h
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 #if __has_include(<sys/qos.h>)
30 #include <sys/qos.h>
31 #endif
32
33 DISPATCH_ASSUME_NONNULL_BEGIN
34
35 /*!
36 * @header
37 *
38 * Dispatch is an abstract model for expressing concurrency via simple but
39 * powerful API.
40 *
41 * At the core, dispatch provides serial FIFO queues to which blocks may be
42 * submitted. Blocks submitted to these dispatch queues are invoked on a pool
43 * of threads fully managed by the system. No guarantee is made regarding
44 * which thread a block will be invoked on; however, it is guaranteed that only
45 * one block submitted to the FIFO dispatch queue will be invoked at a time.
46 *
47 * When multiple queues have blocks to be processed, the system is free to
48 * allocate additional threads to invoke the blocks concurrently. When the
49 * queues become empty, these threads are automatically released.
50 */
51
52 /*!
53 * @typedef dispatch_queue_t
54 *
55 * @abstract
56 * Dispatch queues invoke blocks submitted to them serially in FIFO order. A
57 * queue will only invoke one block at a time, but independent queues may each
58 * invoke their blocks concurrently with respect to each other.
59 *
60 * @discussion
61 * Dispatch queues are lightweight objects to which blocks may be submitted.
62 * The system manages a pool of threads which process dispatch queues and
63 * invoke blocks submitted to them.
64 *
65 * Conceptually a dispatch queue may have its own thread of execution, and
66 * interaction between queues is highly asynchronous.
67 *
68 * Dispatch queues are reference counted via calls to dispatch_retain() and
69 * dispatch_release(). Pending blocks submitted to a queue also hold a
70 * reference to the queue until they have finished. Once all references to a
71 * queue have been released, the queue will be deallocated by the system.
72 */
73 DISPATCH_DECL(dispatch_queue);
74
75 __BEGIN_DECLS
76
77 /*!
78 * @function dispatch_async
79 *
80 * @abstract
81 * Submits a block for asynchronous execution on a dispatch queue.
82 *
83 * @discussion
84 * The dispatch_async() function is the fundamental mechanism for submitting
85 * blocks to a dispatch queue.
86 *
87 * Calls to dispatch_async() always return immediately after the block has
88 * been submitted, and never wait for the block to be invoked.
89 *
90 * The target queue determines whether the block will be invoked serially or
91 * concurrently with respect to other blocks submitted to that same queue.
92 * Serial queues are processed concurrently with respect to each other.
93 *
94 * @param queue
95 * The target dispatch queue to which the block is submitted.
96 * The system will hold a reference on the target queue until the block
97 * has finished.
98 * The result of passing NULL in this parameter is undefined.
99 *
100 * @param block
101 * The block to submit to the target dispatch queue. This function performs
102 * Block_copy() and Block_release() on behalf of callers.
103 * The result of passing NULL in this parameter is undefined.
104 */
105 #ifdef __BLOCKS__
106 API_AVAILABLE(macos(10.6), ios(4.0))
107 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
108 void
109 dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
110 #endif
111
112 /*!
113 * @function dispatch_async_f
114 *
115 * @abstract
116 * Submits a function for asynchronous execution on a dispatch queue.
117 *
118 * @discussion
119 * See dispatch_async() for details.
120 *
121 * @param queue
122 * The target dispatch queue to which the function is submitted.
123 * The system will hold a reference on the target queue until the function
124 * has returned.
125 * The result of passing NULL in this parameter is undefined.
126 *
127 * @param context
128 * The application-defined context parameter to pass to the function.
129 *
130 * @param work
131 * The application-defined function to invoke on the target queue. The first
132 * parameter passed to this function is the context provided to
133 * dispatch_async_f().
134 * The result of passing NULL in this parameter is undefined.
135 */
136 API_AVAILABLE(macos(10.6), ios(4.0))
137 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
138 void
139 dispatch_async_f(dispatch_queue_t queue,
140 void *_Nullable context,
141 dispatch_function_t work);
142
143 /*!
144 * @function dispatch_sync
145 *
146 * @abstract
147 * Submits a block for synchronous execution on a dispatch queue.
148 *
149 * @discussion
150 * Submits a block to a dispatch queue like dispatch_async(), however
151 * dispatch_sync() will not return until the block has finished.
152 *
153 * Calls to dispatch_sync() targeting the current queue will result
154 * in dead-lock. Use of dispatch_sync() is also subject to the same
155 * multi-party dead-lock problems that may result from the use of a mutex.
156 * Use of dispatch_async() is preferred.
157 *
158 * Unlike dispatch_async(), no retain is performed on the target queue. Because
159 * calls to this function are synchronous, the dispatch_sync() "borrows" the
160 * reference of the caller.
161 *
162 * As an optimization, dispatch_sync() invokes the block on the current
163 * thread when possible.
164 *
165 * @param queue
166 * The target dispatch queue to which the block is submitted.
167 * The result of passing NULL in this parameter is undefined.
168 *
169 * @param block
170 * The block to be invoked on the target dispatch queue.
171 * The result of passing NULL in this parameter is undefined.
172 */
173 #ifdef __BLOCKS__
174 API_AVAILABLE(macos(10.6), ios(4.0))
175 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
176 void
177 dispatch_sync(dispatch_queue_t queue, DISPATCH_NOESCAPE dispatch_block_t block);
178 #endif
179
180 /*!
181 * @function dispatch_sync_f
182 *
183 * @abstract
184 * Submits a function for synchronous execution on a dispatch queue.
185 *
186 * @discussion
187 * See dispatch_sync() for details.
188 *
189 * @param queue
190 * The target dispatch queue to which the function is submitted.
191 * The result of passing NULL in this parameter is undefined.
192 *
193 * @param context
194 * The application-defined context parameter to pass to the function.
195 *
196 * @param work
197 * The application-defined function to invoke on the target queue. The first
198 * parameter passed to this function is the context provided to
199 * dispatch_sync_f().
200 * The result of passing NULL in this parameter is undefined.
201 */
202 API_AVAILABLE(macos(10.6), ios(4.0))
203 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
204 void
205 dispatch_sync_f(dispatch_queue_t queue,
206 void *_Nullable context,
207 dispatch_function_t work);
208
209
210 #if !defined(__APPLE__) || TARGET_OS_WATCH || TARGET_OS_TV || \
211 (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \
212 __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0) || \
213 (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \
214 __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_9)
215 #define DISPATCH_APPLY_AUTO_AVAILABLE 1
216 #else
217 #define DISPATCH_APPLY_AUTO_AVAILABLE 0
218 #endif
219
220 /*!
221 * @constant DISPATCH_APPLY_AUTO
222 *
223 * @abstract
224 * Constant to pass to dispatch_apply() or dispatch_apply_f() to request that
225 * the system automatically use worker threads that match the configuration of
226 * the current thread as closely as possible.
227 *
228 * @discussion
229 * When submitting a block for parallel invocation, passing this constant as the
230 * queue argument will automatically use the global concurrent queue that
231 * matches the Quality of Service of the caller most closely.
232 *
233 * No assumptions should be made about which global concurrent queue will
234 * actually be used.
235 *
236 * Using this constant deploys backward to macOS 10.9, iOS 7.0 and any tvOS or
237 * watchOS version.
238 */
239 #if DISPATCH_APPLY_AUTO_AVAILABLE
240 #define DISPATCH_APPLY_AUTO ((dispatch_queue_t _Nonnull)0)
241 #endif
242
243 /*!
244 * @function dispatch_apply
245 *
246 * @abstract
247 * Submits a block to a dispatch queue for parallel invocation.
248 *
249 * @discussion
250 * Submits a block to a dispatch queue for parallel invocation. This function
251 * waits for the task block to complete before returning. If the specified queue
252 * is concurrent, the block may be invoked concurrently, and it must therefore
253 * be reentrant safe.
254 *
255 * Each invocation of the block will be passed the current index of iteration.
256 *
257 * @param iterations
258 * The number of iterations to perform.
259 *
260 * @param queue
261 * The dispatch queue to which the block is submitted.
262 * The preferred value to pass is DISPATCH_APPLY_AUTO to automatically use
263 * a queue appropriate for the calling thread.
264 *
265 * @param block
266 * The block to be invoked the specified number of iterations.
267 * The result of passing NULL in this parameter is undefined.
268 */
269 #ifdef __BLOCKS__
270 API_AVAILABLE(macos(10.6), ios(4.0))
271 DISPATCH_EXPORT DISPATCH_NONNULL3 DISPATCH_NOTHROW
272 void
273 dispatch_apply(size_t iterations, dispatch_queue_t queue,
274 DISPATCH_NOESCAPE void (^block)(size_t));
275 #endif
276
277 /*!
278 * @function dispatch_apply_f
279 *
280 * @abstract
281 * Submits a function to a dispatch queue for parallel invocation.
282 *
283 * @discussion
284 * See dispatch_apply() for details.
285 *
286 * @param iterations
287 * The number of iterations to perform.
288 *
289 * @param queue
290 * The dispatch queue to which the function is submitted.
291 * The preferred value to pass is DISPATCH_APPLY_AUTO to automatically use
292 * a queue appropriate for the calling thread.
293 *
294 * @param context
295 * The application-defined context parameter to pass to the function.
296 *
297 * @param work
298 * The application-defined function to invoke on the specified queue. The first
299 * parameter passed to this function is the context provided to
300 * dispatch_apply_f(). The second parameter passed to this function is the
301 * current index of iteration.
302 * The result of passing NULL in this parameter is undefined.
303 */
304 API_AVAILABLE(macos(10.6), ios(4.0))
305 DISPATCH_EXPORT DISPATCH_NONNULL4 DISPATCH_NOTHROW
306 void
307 dispatch_apply_f(size_t iterations, dispatch_queue_t queue,
308 void *_Nullable context,
309 void (*work)(void *_Nullable, size_t));
310
311 /*!
312 * @function dispatch_get_current_queue
313 *
314 * @abstract
315 * Returns the queue on which the currently executing block is running.
316 *
317 * @discussion
318 * Returns the queue on which the currently executing block is running.
319 *
320 * When dispatch_get_current_queue() is called outside of the context of a
321 * submitted block, it will return the default concurrent queue.
322 *
323 * Recommended for debugging and logging purposes only:
324 * The code must not make any assumptions about the queue returned, unless it
325 * is one of the global queues or a queue the code has itself created.
326 * The code must not assume that synchronous execution onto a queue is safe
327 * from deadlock if that queue is not the one returned by
328 * dispatch_get_current_queue().
329 *
330 * When dispatch_get_current_queue() is called on the main thread, it may
331 * or may not return the same value as dispatch_get_main_queue(). Comparing
332 * the two is not a valid way to test whether code is executing on the
333 * main thread (see dispatch_assert_queue() and dispatch_assert_queue_not()).
334 *
335 * This function is deprecated and will be removed in a future release.
336 *
337 * @result
338 * Returns the current queue.
339 */
340 API_DEPRECATED("unsupported interface", macos(10.6,10.9), ios(4.0,6.0))
341 DISPATCH_EXPORT DISPATCH_PURE DISPATCH_WARN_RESULT DISPATCH_NOTHROW
342 dispatch_queue_t
343 dispatch_get_current_queue(void);
344
345 API_AVAILABLE(macos(10.6), ios(4.0))
346 DISPATCH_EXPORT struct dispatch_queue_s _dispatch_main_q;
347
348 /*!
349 * @function dispatch_get_main_queue
350 *
351 * @abstract
352 * Returns the default queue that is bound to the main thread.
353 *
354 * @discussion
355 * In order to invoke blocks submitted to the main queue, the application must
356 * call dispatch_main(), NSApplicationMain(), or use a CFRunLoop on the main
357 * thread.
358 *
359 * @result
360 * Returns the main queue. This queue is created automatically on behalf of
361 * the main thread before main() is called.
362 */
363 DISPATCH_INLINE DISPATCH_ALWAYS_INLINE DISPATCH_CONST DISPATCH_NOTHROW
364 dispatch_queue_t
365 dispatch_get_main_queue(void)
366 {
367 return DISPATCH_GLOBAL_OBJECT(dispatch_queue_t, _dispatch_main_q);
368 }
369
370 /*!
371 * @typedef dispatch_queue_priority_t
372 * Type of dispatch_queue_priority
373 *
374 * @constant DISPATCH_QUEUE_PRIORITY_HIGH
375 * Items dispatched to the queue will run at high priority,
376 * i.e. the queue will be scheduled for execution before
377 * any default priority or low priority queue.
378 *
379 * @constant DISPATCH_QUEUE_PRIORITY_DEFAULT
380 * Items dispatched to the queue will run at the default
381 * priority, i.e. the queue will be scheduled for execution
382 * after all high priority queues have been scheduled, but
383 * before any low priority queues have been scheduled.
384 *
385 * @constant DISPATCH_QUEUE_PRIORITY_LOW
386 * Items dispatched to the queue will run at low priority,
387 * i.e. the queue will be scheduled for execution after all
388 * default priority and high priority queues have been
389 * scheduled.
390 *
391 * @constant DISPATCH_QUEUE_PRIORITY_BACKGROUND
392 * Items dispatched to the queue will run at background priority, i.e. the queue
393 * will be scheduled for execution after all higher priority queues have been
394 * scheduled and the system will run items on this queue on a thread with
395 * background status as per setpriority(2) (i.e. disk I/O is throttled and the
396 * thread's scheduling priority is set to lowest value).
397 */
398 #define DISPATCH_QUEUE_PRIORITY_HIGH 2
399 #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
400 #define DISPATCH_QUEUE_PRIORITY_LOW (-2)
401 #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
402
403 typedef long dispatch_queue_priority_t;
404
405 /*!
406 * @typedef dispatch_qos_class_t
407 * Alias for qos_class_t type.
408 */
409 #if __has_include(<sys/qos.h>)
410 typedef qos_class_t dispatch_qos_class_t;
411 #else
412 typedef unsigned int dispatch_qos_class_t;
413 #endif
414
415 /*!
416 * @function dispatch_get_global_queue
417 *
418 * @abstract
419 * Returns a well-known global concurrent queue of a given quality of service
420 * class.
421 *
422 * @discussion
423 * The well-known global concurrent queues may not be modified. Calls to
424 * dispatch_suspend(), dispatch_resume(), dispatch_set_context(), etc., will
425 * have no effect when used with queues returned by this function.
426 *
427 * @param identifier
428 * A quality of service class defined in qos_class_t or a priority defined in
429 * dispatch_queue_priority_t.
430 *
431 * It is recommended to use quality of service class values to identify the
432 * well-known global concurrent queues:
433 * - QOS_CLASS_USER_INTERACTIVE
434 * - QOS_CLASS_USER_INITIATED
435 * - QOS_CLASS_DEFAULT
436 * - QOS_CLASS_UTILITY
437 * - QOS_CLASS_BACKGROUND
438 *
439 * The global concurrent queues may still be identified by their priority,
440 * which map to the following QOS classes:
441 * - DISPATCH_QUEUE_PRIORITY_HIGH: QOS_CLASS_USER_INITIATED
442 * - DISPATCH_QUEUE_PRIORITY_DEFAULT: QOS_CLASS_DEFAULT
443 * - DISPATCH_QUEUE_PRIORITY_LOW: QOS_CLASS_UTILITY
444 * - DISPATCH_QUEUE_PRIORITY_BACKGROUND: QOS_CLASS_BACKGROUND
445 *
446 * @param flags
447 * Reserved for future use. Passing any value other than zero may result in
448 * a NULL return value.
449 *
450 * @result
451 * Returns the requested global queue or NULL if the requested global queue
452 * does not exist.
453 */
454 API_AVAILABLE(macos(10.6), ios(4.0))
455 DISPATCH_EXPORT DISPATCH_CONST DISPATCH_WARN_RESULT DISPATCH_NOTHROW
456 dispatch_queue_t
457 dispatch_get_global_queue(long identifier, unsigned long flags);
458
459 /*!
460 * @typedef dispatch_queue_attr_t
461 *
462 * @abstract
463 * Attribute for dispatch queues.
464 */
465 DISPATCH_DECL(dispatch_queue_attr);
466
467 /*!
468 * @const DISPATCH_QUEUE_SERIAL
469 *
470 * @discussion A dispatch queue that invokes blocks serially in FIFO order.
471 */
472 #define DISPATCH_QUEUE_SERIAL NULL
473
474 /*!
475 * @const DISPATCH_QUEUE_SERIAL_INACTIVE
476 *
477 * @discussion
478 * A dispatch queue that invokes blocks serially in FIFO order, and that is
479 * created initially inactive. See dispatch_queue_attr_make_initially_inactive().
480 */
481 #define DISPATCH_QUEUE_SERIAL_INACTIVE \
482 dispatch_queue_attr_make_initially_inactive(DISPATCH_QUEUE_SERIAL)
483
484 /*!
485 * @const DISPATCH_QUEUE_CONCURRENT
486 *
487 * @discussion A dispatch queue that may invoke blocks concurrently and supports
488 * barrier blocks submitted with the dispatch barrier API.
489 */
490 #define DISPATCH_QUEUE_CONCURRENT \
491 DISPATCH_GLOBAL_OBJECT(dispatch_queue_attr_t, \
492 _dispatch_queue_attr_concurrent)
493 API_AVAILABLE(macos(10.7), ios(4.3))
494 DISPATCH_EXPORT
495 struct dispatch_queue_attr_s _dispatch_queue_attr_concurrent;
496
497 /*!
498 * @const DISPATCH_QUEUE_CONCURRENT_INACTIVE
499 *
500 * @discussion
501 * A dispatch queue that may invoke blocks concurrently and supports barrier
502 * blocks submitted with the dispatch barrier API, and that is created initially
503 * inactive. See dispatch_queue_attr_make_initially_inactive().
504 */
505 #define DISPATCH_QUEUE_CONCURRENT_INACTIVE \
506 dispatch_queue_attr_make_initially_inactive(DISPATCH_QUEUE_CONCURRENT)
507
508 /*!
509 * @function dispatch_queue_attr_make_initially_inactive
510 *
511 * @abstract
512 * Returns an attribute value which may be provided to dispatch_queue_create()
513 * or dispatch_queue_create_with_target(), in order to make the created queue
514 * initially inactive.
515 *
516 * @discussion
517 * Dispatch queues may be created in an inactive state. Queues in this state
518 * have to be activated before any blocks associated with them will be invoked.
519 *
520 * A queue in inactive state cannot be deallocated, dispatch_activate() must be
521 * called before the last reference to a queue created with this attribute is
522 * released.
523 *
524 * The target queue of a queue in inactive state can be changed using
525 * dispatch_set_target_queue(). Change of target queue is no longer permitted
526 * once an initially inactive queue has been activated.
527 *
528 * @param attr
529 * A queue attribute value to be combined with the initially inactive attribute.
530 *
531 * @return
532 * Returns an attribute value which may be provided to dispatch_queue_create()
533 * and dispatch_queue_create_with_target().
534 * The new value combines the attributes specified by the 'attr' parameter with
535 * the initially inactive attribute.
536 */
537 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
538 DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_PURE DISPATCH_NOTHROW
539 dispatch_queue_attr_t
540 dispatch_queue_attr_make_initially_inactive(
541 dispatch_queue_attr_t _Nullable attr);
542
543 /*!
544 * @const DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL
545 *
546 * @discussion
547 * A dispatch queue created with this attribute invokes blocks serially in FIFO
548 * order, and surrounds execution of any block submitted asynchronously to it
549 * with the equivalent of a individual Objective-C <code>@autoreleasepool</code>
550 * scope.
551 *
552 * See dispatch_queue_attr_make_with_autorelease_frequency().
553 */
554 #define DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL \
555 dispatch_queue_attr_make_with_autorelease_frequency(\
556 DISPATCH_QUEUE_SERIAL, DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM)
557
558 /*!
559 * @const DISPATCH_QUEUE_CONCURRENT_WITH_AUTORELEASE_POOL
560 *
561 * @discussion
562 * A dispatch queue created with this attribute may invokes blocks concurrently
563 * and supports barrier blocks submitted with the dispatch barrier API. It also
564 * surrounds execution of any block submitted asynchronously to it with the
565 * equivalent of a individual Objective-C <code>@autoreleasepool</code>
566 *
567 * See dispatch_queue_attr_make_with_autorelease_frequency().
568 */
569 #define DISPATCH_QUEUE_CONCURRENT_WITH_AUTORELEASE_POOL \
570 dispatch_queue_attr_make_with_autorelease_frequency(\
571 DISPATCH_QUEUE_CONCURRENT, DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM)
572
573 /*!
574 * @typedef dispatch_autorelease_frequency_t
575 * Values to pass to the dispatch_queue_attr_make_with_autorelease_frequency()
576 * function.
577 *
578 * @const DISPATCH_AUTORELEASE_FREQUENCY_INHERIT
579 * Dispatch queues with this autorelease frequency inherit the behavior from
580 * their target queue. This is the default behavior for manually created queues.
581 *
582 * @const DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM
583 * Dispatch queues with this autorelease frequency push and pop an autorelease
584 * pool around the execution of every block that was submitted to it
585 * asynchronously.
586 * @see dispatch_queue_attr_make_with_autorelease_frequency().
587 *
588 * @const DISPATCH_AUTORELEASE_FREQUENCY_NEVER
589 * Dispatch queues with this autorelease frequency never set up an individual
590 * autorelease pool around the execution of a block that is submitted to it
591 * asynchronously. This is the behavior of the global concurrent queues.
592 */
593 DISPATCH_ENUM(dispatch_autorelease_frequency, unsigned long,
594 DISPATCH_AUTORELEASE_FREQUENCY_INHERIT DISPATCH_ENUM_API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) = 0,
595 DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM DISPATCH_ENUM_API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) = 1,
596 DISPATCH_AUTORELEASE_FREQUENCY_NEVER DISPATCH_ENUM_API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) = 2,
597 );
598
599 /*!
600 * @function dispatch_queue_attr_make_with_autorelease_frequency
601 *
602 * @abstract
603 * Returns a dispatch queue attribute value with the autorelease frequency
604 * set to the specified value.
605 *
606 * @discussion
607 * When a queue uses the per-workitem autorelease frequency (either directly
608 * or inherithed from its target queue), any block submitted asynchronously to
609 * this queue (via dispatch_async(), dispatch_barrier_async(),
610 * dispatch_group_notify(), etc...) is executed as if surrounded by a individual
611 * Objective-C <code>@autoreleasepool</code> scope.
612 *
613 * Autorelease frequency has no effect on blocks that are submitted
614 * synchronously to a queue (via dispatch_sync(), dispatch_barrier_sync()).
615 *
616 * The global concurrent queues have the DISPATCH_AUTORELEASE_FREQUENCY_NEVER
617 * behavior. Manually created dispatch queues use
618 * DISPATCH_AUTORELEASE_FREQUENCY_INHERIT by default.
619 *
620 * Queues created with this attribute cannot change target queues after having
621 * been activated. See dispatch_set_target_queue() and dispatch_activate().
622 *
623 * @param attr
624 * A queue attribute value to be combined with the specified autorelease
625 * frequency or NULL.
626 *
627 * @param frequency
628 * The requested autorelease frequency.
629 *
630 * @return
631 * Returns an attribute value which may be provided to dispatch_queue_create()
632 * or NULL if an invalid autorelease frequency was requested.
633 * This new value combines the attributes specified by the 'attr' parameter and
634 * the chosen autorelease frequency.
635 */
636 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
637 DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_PURE DISPATCH_NOTHROW
638 dispatch_queue_attr_t
639 dispatch_queue_attr_make_with_autorelease_frequency(
640 dispatch_queue_attr_t _Nullable attr,
641 dispatch_autorelease_frequency_t frequency);
642
643 /*!
644 * @function dispatch_queue_attr_make_with_qos_class
645 *
646 * @abstract
647 * Returns an attribute value which may be provided to dispatch_queue_create()
648 * or dispatch_queue_create_with_target(), in order to assign a QOS class and
649 * relative priority to the queue.
650 *
651 * @discussion
652 * When specified in this manner, the QOS class and relative priority take
653 * precedence over those inherited from the dispatch queue's target queue (if
654 * any) as long that does not result in a lower QOS class and relative priority.
655 *
656 * The global queue priorities map to the following QOS classes:
657 * - DISPATCH_QUEUE_PRIORITY_HIGH: QOS_CLASS_USER_INITIATED
658 * - DISPATCH_QUEUE_PRIORITY_DEFAULT: QOS_CLASS_DEFAULT
659 * - DISPATCH_QUEUE_PRIORITY_LOW: QOS_CLASS_UTILITY
660 * - DISPATCH_QUEUE_PRIORITY_BACKGROUND: QOS_CLASS_BACKGROUND
661 *
662 * Example:
663 * <code>
664 * dispatch_queue_t queue;
665 * dispatch_queue_attr_t attr;
666 * attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL,
667 * QOS_CLASS_UTILITY, 0);
668 * queue = dispatch_queue_create("com.example.myqueue", attr);
669 * </code>
670 *
671 * @param attr
672 * A queue attribute value to be combined with the QOS class, or NULL.
673 *
674 * @param qos_class
675 * A QOS class value:
676 * - QOS_CLASS_USER_INTERACTIVE
677 * - QOS_CLASS_USER_INITIATED
678 * - QOS_CLASS_DEFAULT
679 * - QOS_CLASS_UTILITY
680 * - QOS_CLASS_BACKGROUND
681 * Passing any other value results in NULL being returned.
682 *
683 * @param relative_priority
684 * A relative priority within the QOS class. This value is a negative
685 * offset from the maximum supported scheduler priority for the given class.
686 * Passing a value greater than zero or less than QOS_MIN_RELATIVE_PRIORITY
687 * results in NULL being returned.
688 *
689 * @return
690 * Returns an attribute value which may be provided to dispatch_queue_create()
691 * and dispatch_queue_create_with_target(), or NULL if an invalid QOS class was
692 * requested.
693 * The new value combines the attributes specified by the 'attr' parameter and
694 * the new QOS class and relative priority.
695 */
696 API_AVAILABLE(macos(10.10), ios(8.0))
697 DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_PURE DISPATCH_NOTHROW
698 dispatch_queue_attr_t
699 dispatch_queue_attr_make_with_qos_class(dispatch_queue_attr_t _Nullable attr,
700 dispatch_qos_class_t qos_class, int relative_priority);
701
702 /*!
703 * @const DISPATCH_TARGET_QUEUE_DEFAULT
704 * @discussion Constant to pass to the dispatch_queue_create_with_target(),
705 * dispatch_set_target_queue() and dispatch_source_create() functions to
706 * indicate that the default target queue for the object type in question
707 * should be used.
708 */
709 #define DISPATCH_TARGET_QUEUE_DEFAULT NULL
710
711 /*!
712 * @function dispatch_queue_create_with_target
713 *
714 * @abstract
715 * Creates a new dispatch queue with a specified target queue.
716 *
717 * @discussion
718 * Dispatch queues created with the DISPATCH_QUEUE_SERIAL or a NULL attribute
719 * invoke blocks serially in FIFO order.
720 *
721 * Dispatch queues created with the DISPATCH_QUEUE_CONCURRENT attribute may
722 * invoke blocks concurrently (similarly to the global concurrent queues, but
723 * potentially with more overhead), and support barrier blocks submitted with
724 * the dispatch barrier API, which e.g. enables the implementation of efficient
725 * reader-writer schemes.
726 *
727 * When a dispatch queue is no longer needed, it should be released with
728 * dispatch_release(). Note that any pending blocks submitted to a queue will
729 * hold a reference to that queue. Therefore a queue will not be deallocated
730 * until all pending blocks have finished.
731 *
732 * When using a dispatch queue attribute @a attr specifying a QoS class (derived
733 * from the result of dispatch_queue_attr_make_with_qos_class()), passing the
734 * result of dispatch_get_global_queue() in @a target will ignore the QoS class
735 * of that global queue and will use the global queue with the QoS class
736 * specified by attr instead.
737 *
738 * Queues created with dispatch_queue_create_with_target() cannot have their
739 * target queue changed, unless created inactive (See
740 * dispatch_queue_attr_make_initially_inactive()), in which case the target
741 * queue can be changed until the newly created queue is activated with
742 * dispatch_activate().
743 *
744 * @param label
745 * A string label to attach to the queue.
746 * This parameter is optional and may be NULL.
747 *
748 * @param attr
749 * A predefined attribute such as DISPATCH_QUEUE_SERIAL,
750 * DISPATCH_QUEUE_CONCURRENT, or the result of a call to
751 * a dispatch_queue_attr_make_with_* function.
752 *
753 * @param target
754 * The target queue for the newly created queue. The target queue is retained.
755 * If this parameter is DISPATCH_TARGET_QUEUE_DEFAULT, sets the queue's target
756 * queue to the default target queue for the given queue type.
757 *
758 * @result
759 * The newly created dispatch queue.
760 */
761 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
762 DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
763 DISPATCH_NOTHROW
764 dispatch_queue_t
765 dispatch_queue_create_with_target(const char *_Nullable label,
766 dispatch_queue_attr_t _Nullable attr, dispatch_queue_t _Nullable target)
767 DISPATCH_ALIAS_V2(dispatch_queue_create_with_target);
768
769 /*!
770 * @function dispatch_queue_create
771 *
772 * @abstract
773 * Creates a new dispatch queue to which blocks may be submitted.
774 *
775 * @discussion
776 * Dispatch queues created with the DISPATCH_QUEUE_SERIAL or a NULL attribute
777 * invoke blocks serially in FIFO order.
778 *
779 * Dispatch queues created with the DISPATCH_QUEUE_CONCURRENT attribute may
780 * invoke blocks concurrently (similarly to the global concurrent queues, but
781 * potentially with more overhead), and support barrier blocks submitted with
782 * the dispatch barrier API, which e.g. enables the implementation of efficient
783 * reader-writer schemes.
784 *
785 * When a dispatch queue is no longer needed, it should be released with
786 * dispatch_release(). Note that any pending blocks submitted to a queue will
787 * hold a reference to that queue. Therefore a queue will not be deallocated
788 * until all pending blocks have finished.
789 *
790 * Passing the result of the dispatch_queue_attr_make_with_qos_class() function
791 * to the attr parameter of this function allows a quality of service class and
792 * relative priority to be specified for the newly created queue.
793 * The quality of service class so specified takes precedence over the quality
794 * of service class of the newly created dispatch queue's target queue (if any)
795 * as long that does not result in a lower QOS class and relative priority.
796 *
797 * When no quality of service class is specified, the target queue of a newly
798 * created dispatch queue is the default priority global concurrent queue.
799 *
800 * @param label
801 * A string label to attach to the queue.
802 * This parameter is optional and may be NULL.
803 *
804 * @param attr
805 * A predefined attribute such as DISPATCH_QUEUE_SERIAL,
806 * DISPATCH_QUEUE_CONCURRENT, or the result of a call to
807 * a dispatch_queue_attr_make_with_* function.
808 *
809 * @result
810 * The newly created dispatch queue.
811 */
812 API_AVAILABLE(macos(10.6), ios(4.0))
813 DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
814 DISPATCH_NOTHROW
815 dispatch_queue_t
816 dispatch_queue_create(const char *_Nullable label,
817 dispatch_queue_attr_t _Nullable attr);
818
819 /*!
820 * @const DISPATCH_CURRENT_QUEUE_LABEL
821 * @discussion Constant to pass to the dispatch_queue_get_label() function to
822 * retrieve the label of the current queue.
823 */
824 #define DISPATCH_CURRENT_QUEUE_LABEL NULL
825
826 /*!
827 * @function dispatch_queue_get_label
828 *
829 * @abstract
830 * Returns the label of the given queue, as specified when the queue was
831 * created, or the empty string if a NULL label was specified.
832 *
833 * Passing DISPATCH_CURRENT_QUEUE_LABEL will return the label of the current
834 * queue.
835 *
836 * @param queue
837 * The queue to query, or DISPATCH_CURRENT_QUEUE_LABEL.
838 *
839 * @result
840 * The label of the queue.
841 */
842 API_AVAILABLE(macos(10.6), ios(4.0))
843 DISPATCH_EXPORT DISPATCH_PURE DISPATCH_WARN_RESULT DISPATCH_NOTHROW
844 const char *
845 dispatch_queue_get_label(dispatch_queue_t _Nullable queue);
846
847 /*!
848 * @function dispatch_queue_get_qos_class
849 *
850 * @abstract
851 * Returns the QOS class and relative priority of the given queue.
852 *
853 * @discussion
854 * If the given queue was created with an attribute value returned from
855 * dispatch_queue_attr_make_with_qos_class(), this function returns the QOS
856 * class and relative priority specified at that time; for any other attribute
857 * value it returns a QOS class of QOS_CLASS_UNSPECIFIED and a relative
858 * priority of 0.
859 *
860 * If the given queue is one of the global queues, this function returns its
861 * assigned QOS class value as documented under dispatch_get_global_queue() and
862 * a relative priority of 0; in the case of the main queue it returns the QOS
863 * value provided by qos_class_main() and a relative priority of 0.
864 *
865 * @param queue
866 * The queue to query.
867 *
868 * @param relative_priority_ptr
869 * A pointer to an int variable to be filled with the relative priority offset
870 * within the QOS class, or NULL.
871 *
872 * @return
873 * A QOS class value:
874 * - QOS_CLASS_USER_INTERACTIVE
875 * - QOS_CLASS_USER_INITIATED
876 * - QOS_CLASS_DEFAULT
877 * - QOS_CLASS_UTILITY
878 * - QOS_CLASS_BACKGROUND
879 * - QOS_CLASS_UNSPECIFIED
880 */
881 API_AVAILABLE(macos(10.10), ios(8.0))
882 DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_NONNULL1 DISPATCH_NOTHROW
883 dispatch_qos_class_t
884 dispatch_queue_get_qos_class(dispatch_queue_t queue,
885 int *_Nullable relative_priority_ptr);
886
887 /*!
888 * @function dispatch_set_target_queue
889 *
890 * @abstract
891 * Sets the target queue for the given object.
892 *
893 * @discussion
894 * An object's target queue is responsible for processing the object.
895 *
896 * When no quality of service class and relative priority is specified for a
897 * dispatch queue at the time of creation, a dispatch queue's quality of service
898 * class is inherited from its target queue. The dispatch_get_global_queue()
899 * function may be used to obtain a target queue of a specific quality of
900 * service class, however the use of dispatch_queue_attr_make_with_qos_class()
901 * is recommended instead.
902 *
903 * Blocks submitted to a serial queue whose target queue is another serial
904 * queue will not be invoked concurrently with blocks submitted to the target
905 * queue or to any other queue with that same target queue.
906 *
907 * The result of introducing a cycle into the hierarchy of target queues is
908 * undefined.
909 *
910 * A dispatch source's target queue specifies where its event handler and
911 * cancellation handler blocks will be submitted.
912 *
913 * A dispatch I/O channel's target queue specifies where where its I/O
914 * operations are executed. If the channel's target queue's priority is set to
915 * DISPATCH_QUEUE_PRIORITY_BACKGROUND, then the I/O operations performed by
916 * dispatch_io_read() or dispatch_io_write() on that queue will be
917 * throttled when there is I/O contention.
918 *
919 * For all other dispatch object types, the only function of the target queue
920 * is to determine where an object's finalizer function is invoked.
921 *
922 * In general, changing the target queue of an object is an asynchronous
923 * operation that doesn't take effect immediately, and doesn't affect blocks
924 * already associated with the specified object.
925 *
926 * However, if an object is inactive at the time dispatch_set_target_queue() is
927 * called, then the target queue change takes effect immediately, and will
928 * affect blocks already associated with the specified object. After an
929 * initially inactive object has been activated, calling
930 * dispatch_set_target_queue() results in an assertion and the process being
931 * terminated.
932 *
933 * If a dispatch queue is active and targeted by other dispatch objects,
934 * changing its target queue results in undefined behavior.
935 *
936 * @param object
937 * The object to modify.
938 * The result of passing NULL in this parameter is undefined.
939 *
940 * @param queue
941 * The new target queue for the object. The queue is retained, and the
942 * previous target queue, if any, is released.
943 * If queue is DISPATCH_TARGET_QUEUE_DEFAULT, set the object's target queue
944 * to the default target queue for the given object type.
945 */
946 API_AVAILABLE(macos(10.6), ios(4.0))
947 DISPATCH_EXPORT DISPATCH_NOTHROW
948 void
949 dispatch_set_target_queue(dispatch_object_t object,
950 dispatch_queue_t _Nullable queue);
951
952 /*!
953 * @function dispatch_main
954 *
955 * @abstract
956 * Execute blocks submitted to the main queue.
957 *
958 * @discussion
959 * This function "parks" the main thread and waits for blocks to be submitted
960 * to the main queue. This function never returns.
961 *
962 * Applications that call NSApplicationMain() or CFRunLoopRun() on the
963 * main thread do not need to call dispatch_main().
964 */
965 API_AVAILABLE(macos(10.6), ios(4.0))
966 DISPATCH_EXPORT DISPATCH_NOTHROW DISPATCH_NORETURN
967 void
968 dispatch_main(void);
969
970 /*!
971 * @function dispatch_after
972 *
973 * @abstract
974 * Schedule a block for execution on a given queue at a specified time.
975 *
976 * @discussion
977 * Passing DISPATCH_TIME_NOW as the "when" parameter is supported, but not as
978 * optimal as calling dispatch_async() instead. Passing DISPATCH_TIME_FOREVER
979 * is undefined.
980 *
981 * @param when
982 * A temporal milestone returned by dispatch_time() or dispatch_walltime().
983 *
984 * @param queue
985 * A queue to which the given block will be submitted at the specified time.
986 * The result of passing NULL in this parameter is undefined.
987 *
988 * @param block
989 * The block of code to execute.
990 * The result of passing NULL in this parameter is undefined.
991 */
992 #ifdef __BLOCKS__
993 API_AVAILABLE(macos(10.6), ios(4.0))
994 DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NONNULL3 DISPATCH_NOTHROW
995 void
996 dispatch_after(dispatch_time_t when,
997 dispatch_queue_t queue,
998 dispatch_block_t block);
999 #endif
1000
1001 /*!
1002 * @function dispatch_after_f
1003 *
1004 * @abstract
1005 * Schedule a function for execution on a given queue at a specified time.
1006 *
1007 * @discussion
1008 * See dispatch_after() for details.
1009 *
1010 * @param when
1011 * A temporal milestone returned by dispatch_time() or dispatch_walltime().
1012 *
1013 * @param queue
1014 * A queue to which the given function will be submitted at the specified time.
1015 * The result of passing NULL in this parameter is undefined.
1016 *
1017 * @param context
1018 * The application-defined context parameter to pass to the function.
1019 *
1020 * @param work
1021 * The application-defined function to invoke on the target queue. The first
1022 * parameter passed to this function is the context provided to
1023 * dispatch_after_f().
1024 * The result of passing NULL in this parameter is undefined.
1025 */
1026 API_AVAILABLE(macos(10.6), ios(4.0))
1027 DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NONNULL4 DISPATCH_NOTHROW
1028 void
1029 dispatch_after_f(dispatch_time_t when,
1030 dispatch_queue_t queue,
1031 void *_Nullable context,
1032 dispatch_function_t work);
1033
1034 /*!
1035 * @functiongroup Dispatch Barrier API
1036 * The dispatch barrier API is a mechanism for submitting barrier blocks to a
1037 * dispatch queue, analogous to the dispatch_async()/dispatch_sync() API.
1038 * It enables the implementation of efficient reader/writer schemes.
1039 * Barrier blocks only behave specially when submitted to queues created with
1040 * the DISPATCH_QUEUE_CONCURRENT attribute; on such a queue, a barrier block
1041 * will not run until all blocks submitted to the queue earlier have completed,
1042 * and any blocks submitted to the queue after a barrier block will not run
1043 * until the barrier block has completed.
1044 * When submitted to a a global queue or to a queue not created with the
1045 * DISPATCH_QUEUE_CONCURRENT attribute, barrier blocks behave identically to
1046 * blocks submitted with the dispatch_async()/dispatch_sync() API.
1047 */
1048
1049 /*!
1050 * @function dispatch_barrier_async
1051 *
1052 * @abstract
1053 * Submits a barrier block for asynchronous execution on a dispatch queue.
1054 *
1055 * @discussion
1056 * Submits a block to a dispatch queue like dispatch_async(), but marks that
1057 * block as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT queues).
1058 *
1059 * See dispatch_async() for details.
1060 *
1061 * @param queue
1062 * The target dispatch queue to which the block is submitted.
1063 * The system will hold a reference on the target queue until the block
1064 * has finished.
1065 * The result of passing NULL in this parameter is undefined.
1066 *
1067 * @param block
1068 * The block to submit to the target dispatch queue. This function performs
1069 * Block_copy() and Block_release() on behalf of callers.
1070 * The result of passing NULL in this parameter is undefined.
1071 */
1072 #ifdef __BLOCKS__
1073 API_AVAILABLE(macos(10.7), ios(4.3))
1074 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
1075 void
1076 dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
1077 #endif
1078
1079 /*!
1080 * @function dispatch_barrier_async_f
1081 *
1082 * @abstract
1083 * Submits a barrier function for asynchronous execution on a dispatch queue.
1084 *
1085 * @discussion
1086 * Submits a function to a dispatch queue like dispatch_async_f(), but marks
1087 * that function as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT
1088 * queues).
1089 *
1090 * See dispatch_async_f() for details.
1091 *
1092 * @param queue
1093 * The target dispatch queue to which the function is submitted.
1094 * The system will hold a reference on the target queue until the function
1095 * has returned.
1096 * The result of passing NULL in this parameter is undefined.
1097 *
1098 * @param context
1099 * The application-defined context parameter to pass to the function.
1100 *
1101 * @param work
1102 * The application-defined function to invoke on the target queue. The first
1103 * parameter passed to this function is the context provided to
1104 * dispatch_barrier_async_f().
1105 * The result of passing NULL in this parameter is undefined.
1106 */
1107 API_AVAILABLE(macos(10.7), ios(4.3))
1108 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
1109 void
1110 dispatch_barrier_async_f(dispatch_queue_t queue,
1111 void *_Nullable context,
1112 dispatch_function_t work);
1113
1114 /*!
1115 * @function dispatch_barrier_sync
1116 *
1117 * @abstract
1118 * Submits a barrier block for synchronous execution on a dispatch queue.
1119 *
1120 * @discussion
1121 * Submits a block to a dispatch queue like dispatch_sync(), but marks that
1122 * block as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT queues).
1123 *
1124 * See dispatch_sync() for details.
1125 *
1126 * @param queue
1127 * The target dispatch queue to which the block is submitted.
1128 * The result of passing NULL in this parameter is undefined.
1129 *
1130 * @param block
1131 * The block to be invoked on the target dispatch queue.
1132 * The result of passing NULL in this parameter is undefined.
1133 */
1134 #ifdef __BLOCKS__
1135 API_AVAILABLE(macos(10.7), ios(4.3))
1136 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
1137 void
1138 dispatch_barrier_sync(dispatch_queue_t queue,
1139 DISPATCH_NOESCAPE dispatch_block_t block);
1140 #endif
1141
1142 /*!
1143 * @function dispatch_barrier_sync_f
1144 *
1145 * @abstract
1146 * Submits a barrier function for synchronous execution on a dispatch queue.
1147 *
1148 * @discussion
1149 * Submits a function to a dispatch queue like dispatch_sync_f(), but marks that
1150 * fuction as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT queues).
1151 *
1152 * See dispatch_sync_f() for details.
1153 *
1154 * @param queue
1155 * The target dispatch queue to which the function is submitted.
1156 * The result of passing NULL in this parameter is undefined.
1157 *
1158 * @param context
1159 * The application-defined context parameter to pass to the function.
1160 *
1161 * @param work
1162 * The application-defined function to invoke on the target queue. The first
1163 * parameter passed to this function is the context provided to
1164 * dispatch_barrier_sync_f().
1165 * The result of passing NULL in this parameter is undefined.
1166 */
1167 API_AVAILABLE(macos(10.7), ios(4.3))
1168 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
1169 void
1170 dispatch_barrier_sync_f(dispatch_queue_t queue,
1171 void *_Nullable context,
1172 dispatch_function_t work);
1173
1174 /*!
1175 * @functiongroup Dispatch queue-specific contexts
1176 * This API allows different subsystems to associate context to a shared queue
1177 * without risk of collision and to retrieve that context from blocks executing
1178 * on that queue or any of its child queues in the target queue hierarchy.
1179 */
1180
1181 /*!
1182 * @function dispatch_queue_set_specific
1183 *
1184 * @abstract
1185 * Associates a subsystem-specific context with a dispatch queue, for a key
1186 * unique to the subsystem.
1187 *
1188 * @discussion
1189 * The specified destructor will be invoked with the context on the default
1190 * priority global concurrent queue when a new context is set for the same key,
1191 * or after all references to the queue have been released.
1192 *
1193 * @param queue
1194 * The dispatch queue to modify.
1195 * The result of passing NULL in this parameter is undefined.
1196 *
1197 * @param key
1198 * The key to set the context for, typically a pointer to a static variable
1199 * specific to the subsystem. Keys are only compared as pointers and never
1200 * dereferenced. Passing a string constant directly is not recommended.
1201 * The NULL key is reserved and attempts to set a context for it are ignored.
1202 *
1203 * @param context
1204 * The new subsystem-specific context for the object. This may be NULL.
1205 *
1206 * @param destructor
1207 * The destructor function pointer. This may be NULL and is ignored if context
1208 * is NULL.
1209 */
1210 API_AVAILABLE(macos(10.7), ios(5.0))
1211 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
1212 void
1213 dispatch_queue_set_specific(dispatch_queue_t queue, const void *key,
1214 void *_Nullable context, dispatch_function_t _Nullable destructor);
1215
1216 /*!
1217 * @function dispatch_queue_get_specific
1218 *
1219 * @abstract
1220 * Returns the subsystem-specific context associated with a dispatch queue, for
1221 * a key unique to the subsystem.
1222 *
1223 * @discussion
1224 * Returns the context for the specified key if it has been set on the specified
1225 * queue.
1226 *
1227 * @param queue
1228 * The dispatch queue to query.
1229 * The result of passing NULL in this parameter is undefined.
1230 *
1231 * @param key
1232 * The key to get the context for, typically a pointer to a static variable
1233 * specific to the subsystem. Keys are only compared as pointers and never
1234 * dereferenced. Passing a string constant directly is not recommended.
1235 *
1236 * @result
1237 * The context for the specified key or NULL if no context was found.
1238 */
1239 API_AVAILABLE(macos(10.7), ios(5.0))
1240 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_PURE DISPATCH_WARN_RESULT
1241 DISPATCH_NOTHROW
1242 void *_Nullable
1243 dispatch_queue_get_specific(dispatch_queue_t queue, const void *key);
1244
1245 /*!
1246 * @function dispatch_get_specific
1247 *
1248 * @abstract
1249 * Returns the current subsystem-specific context for a key unique to the
1250 * subsystem.
1251 *
1252 * @discussion
1253 * When called from a block executing on a queue, returns the context for the
1254 * specified key if it has been set on the queue, otherwise returns the result
1255 * of dispatch_get_specific() executed on the queue's target queue or NULL
1256 * if the current queue is a global concurrent queue.
1257 *
1258 * @param key
1259 * The key to get the context for, typically a pointer to a static variable
1260 * specific to the subsystem. Keys are only compared as pointers and never
1261 * dereferenced. Passing a string constant directly is not recommended.
1262 *
1263 * @result
1264 * The context for the specified key or NULL if no context was found.
1265 */
1266 API_AVAILABLE(macos(10.7), ios(5.0))
1267 DISPATCH_EXPORT DISPATCH_PURE DISPATCH_WARN_RESULT DISPATCH_NOTHROW
1268 void *_Nullable
1269 dispatch_get_specific(const void *key);
1270
1271 /*!
1272 * @functiongroup Dispatch assertion API
1273 *
1274 * This API asserts at runtime that code is executing in (or out of) the context
1275 * of a given queue. It can be used to check that a block accessing a resource
1276 * does so from the proper queue protecting the resource. It also can be used
1277 * to verify that a block that could cause a deadlock if run on a given queue
1278 * never executes on that queue.
1279 */
1280
1281 /*!
1282 * @function dispatch_assert_queue
1283 *
1284 * @abstract
1285 * Verifies that the current block is executing on a given dispatch queue.
1286 *
1287 * @discussion
1288 * Some code expects to be run on a specific dispatch queue. This function
1289 * verifies that that expectation is true.
1290 *
1291 * If the currently executing block was submitted to the specified queue or to
1292 * any queue targeting it (see dispatch_set_target_queue()), this function
1293 * returns.
1294 *
1295 * If the currently executing block was submitted with a synchronous API
1296 * (dispatch_sync(), dispatch_barrier_sync(), ...), the context of the
1297 * submitting block is also evaluated (recursively).
1298 * If a synchronously submitting block is found that was itself submitted to
1299 * the specified queue or to any queue targeting it, this function returns.
1300 *
1301 * Otherwise this function asserts: it logs an explanation to the system log and
1302 * terminates the application.
1303 *
1304 * Passing the result of dispatch_get_main_queue() to this function verifies
1305 * that the current block was submitted to the main queue, or to a queue
1306 * targeting it, or is running on the main thread (in any context).
1307 *
1308 * When dispatch_assert_queue() is called outside of the context of a
1309 * submitted block (for example from the context of a thread created manually
1310 * with pthread_create()) then this function will also assert and terminate
1311 * the application.
1312 *
1313 * The variant dispatch_assert_queue_debug() is compiled out when the
1314 * preprocessor macro NDEBUG is defined. (See also assert(3)).
1315 *
1316 * @param queue
1317 * The dispatch queue that the current block is expected to run on.
1318 * The result of passing NULL in this parameter is undefined.
1319 */
1320 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
1321 DISPATCH_EXPORT DISPATCH_NONNULL1
1322 void
1323 dispatch_assert_queue(dispatch_queue_t queue)
1324 DISPATCH_ALIAS_V2(dispatch_assert_queue);
1325
1326 /*!
1327 * @function dispatch_assert_queue_barrier
1328 *
1329 * @abstract
1330 * Verifies that the current block is executing on a given dispatch queue,
1331 * and that the block acts as a barrier on that queue.
1332 *
1333 * @discussion
1334 * This behaves exactly like dispatch_assert_queue(), with the additional check
1335 * that the current block acts as a barrier on the specified queue, which is
1336 * always true if the specified queue is serial (see DISPATCH_BLOCK_BARRIER or
1337 * dispatch_barrier_async() for details).
1338 *
1339 * The variant dispatch_assert_queue_barrier_debug() is compiled out when the
1340 * preprocessor macro NDEBUG is defined. (See also assert()).
1341 *
1342 * @param queue
1343 * The dispatch queue that the current block is expected to run as a barrier on.
1344 * The result of passing NULL in this parameter is undefined.
1345 */
1346 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
1347 DISPATCH_EXPORT DISPATCH_NONNULL1
1348 void
1349 dispatch_assert_queue_barrier(dispatch_queue_t queue);
1350
1351 /*!
1352 * @function dispatch_assert_queue_not
1353 *
1354 * @abstract
1355 * Verifies that the current block is not executing on a given dispatch queue.
1356 *
1357 * @discussion
1358 * This function is the equivalent of dispatch_queue_assert() with the test for
1359 * equality inverted. That means that it will terminate the application when
1360 * dispatch_queue_assert() would return, and vice-versa. See discussion there.
1361 *
1362 * The variant dispatch_assert_queue_not_debug() is compiled out when the
1363 * preprocessor macro NDEBUG is defined. (See also assert(3)).
1364 *
1365 * @param queue
1366 * The dispatch queue that the current block is expected not to run on.
1367 * The result of passing NULL in this parameter is undefined.
1368 */
1369 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
1370 DISPATCH_EXPORT DISPATCH_NONNULL1
1371 void
1372 dispatch_assert_queue_not(dispatch_queue_t queue)
1373 DISPATCH_ALIAS_V2(dispatch_assert_queue_not);
1374
1375 #ifdef NDEBUG
1376 #define dispatch_assert_queue_debug(q) ((void)(0 && (q)))
1377 #define dispatch_assert_queue_barrier_debug(q) ((void)(0 && (q)))
1378 #define dispatch_assert_queue_not_debug(q) ((void)(0 && (q)))
1379 #else
1380 #define dispatch_assert_queue_debug(q) dispatch_assert_queue(q)
1381 #define dispatch_assert_queue_barrier_debug(q) dispatch_assert_queue_barrier(q)
1382 #define dispatch_assert_queue_not_debug(q) dispatch_assert_queue_not(q)
1383 #endif
1384
1385 __END_DECLS
1386
1387 DISPATCH_ASSUME_NONNULL_END
1388
1389 #endif