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
  29DISPATCH_ASSUME_NONNULL_BEGIN
  30DISPATCH_ASSUME_ABI_SINGLE_BEGIN
  31
  32/*!
  33 * @header
  34 *
  35 * Dispatch is an abstract model for expressing concurrency via simple but
  36 * powerful API.
  37 *
  38 * At the core, dispatch provides serial FIFO queues to which blocks may be
  39 * submitted. Blocks submitted to these dispatch queues are invoked on a pool
  40 * of threads fully managed by the system. No guarantee is made regarding
  41 * which thread a block will be invoked on; however, it is guaranteed that only
  42 * one block submitted to the FIFO dispatch queue will be invoked at a time.
  43 *
  44 * When multiple queues have blocks to be processed, the system is free to
  45 * allocate additional threads to invoke the blocks concurrently. When the
  46 * queues become empty, these threads are automatically released.
  47 */
  48
  49/*!
  50 * @typedef dispatch_queue_t
  51 *
  52 * @abstract
  53 * Dispatch queues invoke workitems submitted to them.
  54 *
  55 * @discussion
  56 * Dispatch queues come in many flavors, the most common one being the dispatch
  57 * serial queue (See dispatch_queue_serial_t).
  58 *
  59 * The system manages a pool of threads which process dispatch queues and invoke
  60 * workitems submitted to them.
  61 *
  62 * Conceptually a dispatch queue may have its own thread of execution, and
  63 * interaction between queues is highly asynchronous.
  64 *
  65 * Dispatch queues are reference counted via calls to dispatch_retain() and
  66 * dispatch_release(). Pending workitems submitted to a queue also hold a
  67 * reference to the queue until they have finished. Once all references to a
  68 * queue have been released, the queue will be deallocated by the system.
  69 */
  70DISPATCH_DECL_FACTORY_CLASS_SWIFT(dispatch_queue, DispatchQueue);
  71
  72/*!
  73 * @typedef dispatch_queue_global_t
  74 *
  75 * @abstract
  76 * Dispatch global concurrent queues are an abstraction around the system thread
  77 * pool which invokes workitems that are submitted to dispatch queues.
  78 *
  79 * @discussion
  80 * Dispatch global concurrent queues provide buckets of priorities on top of the
  81 * thread pool the system manages. The system will decide how many threads
  82 * to allocate to this pool depending on demand and system load. In particular,
  83 * the system tries to maintain a good level of concurrency for this resource,
  84 * and will create new threads when too many existing worker threads block in
  85 * system calls.
  86 *
  87 * The global concurrent queues are a shared resource and as such it is the
  88 * responsiblity of every user of this resource to not submit an unbounded
  89 * amount of work to this pool, especially work that may block, as this can
  90 * cause the system to spawn very large numbers of threads (aka. thread
  91 * explosion).
  92 *
  93 * Work items submitted to the global concurrent queues have no ordering
  94 * guarantee with respect to the order of submission, and workitems submitted
  95 * to these queues may be invoked concurrently.
  96 *
  97 * Dispatch global concurrent queues are well-known global objects that are
  98 * returned by dispatch_get_global_queue(). These objects cannot be modified.
  99 * Calls to dispatch_suspend(), dispatch_resume(), dispatch_set_context(), etc.,
 100 * will have no effect when used with queues of this type.
 101 */
 102DISPATCH_DECL_SUBCLASS(dispatch_queue_global, dispatch_queue);
 103
 104/*!
 105 * @typedef dispatch_queue_serial_executor_t
 106 *
 107 * @abstract
 108 * An abstract class of dispatch queues which conform to the serial executor
 109 * protocol.
 110 *
 111 * @discussion
 112 * A serial executor in Swift Concurrency represents a mutual exclusion context.
 113 * Queues with a singular owner, which invoke only one workItem at a time
 114 * provide such a mutual exclusion context and are serial executors.
 115 *
 116 * Subclasses of this abstract class can be therefore be setup as Custom
 117 * Executors for Swift Actors.
 118 *
 119 * See dispatch_queue_serial_t and dispatch_workloop_t.
 120 */
 121API_AVAILABLE(macos(14.0), ios(17.0), tvos(17.0), watchos(10.0))
 122DISPATCH_DECL_SUBCLASS_SWIFT(dispatch_queue_serial_executor, dispatch_queue, _DispatchSerialExecutorQueue);
 123
 124/*!
 125 * @typedef dispatch_queue_serial_t
 126 *
 127 * @abstract
 128 * Dispatch serial queues invoke workitems submitted to them serially in FIFO
 129 * order.
 130 *
 131 * @discussion
 132 * Dispatch serial queues are lightweight objects to which workitems may be
 133 * submitted to be invoked in FIFO order. A serial queue will only invoke one
 134 * workitem at a time, but independent serial queues may each invoke their work
 135 * items concurrently with respect to each other.
 136 *
 137 * Serial queues can target each other (See dispatch_set_target_queue()). The
 138 * serial queue at the bottom of a queue hierarchy provides an exclusion
 139 * context: at most one workitem submitted to any of the queues in such
 140 * a hiearchy will run at any given time.
 141 *
 142 * Such hierarchies provide a natural construct to organize an application
 143 * subsystem around.
 144 *
 145 * Serial queues are created by passing a dispatch queue attribute derived from
 146 * DISPATCH_QUEUE_SERIAL to dispatch_queue_create_with_target().
 147 */
 148API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
 149DISPATCH_DECL_SERIAL_EXECUTOR_SWIFT(dispatch_queue_serial, DispatchSerialQueue);
 150
 151/*!
 152 * @typedef dispatch_queue_main_t
 153 *
 154 * @abstract
 155 * The type of the default queue that is bound to the main thread.
 156 *
 157 * @discussion
 158 * The main queue is a serial queue (See dispatch_queue_serial_t) which is bound
 159 * to the main thread of an application.
 160 *
 161 * In order to invoke workitems submitted to the main queue, the application
 162 * must call dispatch_main(), NSApplicationMain(), or use a CFRunLoop on the
 163 * main thread.
 164 *
 165 * The main queue is a well known global object that is made automatically on
 166 * behalf of the main thread during process initialization and is returned by
 167 * dispatch_get_main_queue(). This object cannot be modified.  Calls to
 168 * dispatch_suspend(), dispatch_resume(), dispatch_set_context(), etc., will
 169 * have no effect when used on the main queue.
 170 */
 171DISPATCH_DECL_SUBCLASS(dispatch_queue_main, dispatch_queue_serial);
 172
 173/*!
 174 * @typedef dispatch_queue_concurrent_t
 175 *
 176 * @abstract
 177 * Dispatch concurrent queues invoke workitems submitted to them concurrently,
 178 * and admit a notion of barrier workitems.
 179 *
 180 * @discussion
 181 * Dispatch concurrent queues are lightweight objects to which regular and
 182 * barrier workitems may be submited. Barrier workitems are invoked in
 183 * exclusion of any other kind of workitem in FIFO order.
 184 *
 185 * Regular workitems can be invoked concurrently for the same concurrent queue,
 186 * in any order. However, regular workitems will not be invoked before any
 187 * barrier workitem submited ahead of them has been invoked.
 188 *
 189 * In other words, if a serial queue is equivalent to a mutex in the Dispatch
 190 * world, a concurrent queue is equivalent to a reader-writer lock, where
 191 * regular items are readers and barriers are writers.
 192 *
 193 * Concurrent queues are created by passing a dispatch queue attribute derived
 194 * from DISPATCH_QUEUE_CONCURRENT to dispatch_queue_create_with_target().
 195 *
 196 * Caveat:
 197 * Dispatch concurrent queues at this time do not implement priority inversion
 198 * avoidance when lower priority regular workitems (readers) are being invoked
 199 * and are preventing a higher priority barrier (writer) from being invoked.
 200 */
 201API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
 202DISPATCH_DECL_SUBCLASS_SWIFT(dispatch_queue_concurrent, dispatch_queue, DispatchConcurrentQueue);
 203
 204__BEGIN_DECLS
 205
 206/*!
 207 * @function dispatch_async
 208 *
 209 * @abstract
 210 * Submits a block for asynchronous execution on a dispatch queue.
 211 *
 212 * @discussion
 213 * The dispatch_async() function is the fundamental mechanism for submitting
 214 * blocks to a dispatch queue.
 215 *
 216 * Calls to dispatch_async() always return immediately after the block has
 217 * been submitted, and never wait for the block to be invoked.
 218 *
 219 * The target queue determines whether the block will be invoked serially or
 220 * concurrently with respect to other blocks submitted to that same queue.
 221 * Serial queues are processed concurrently with respect to each other.
 222 *
 223 * @param queue
 224 * The target dispatch queue to which the block is submitted.
 225 * The system will hold a reference on the target queue until the block
 226 * has finished.
 227 * The result of passing NULL in this parameter is undefined.
 228 *
 229 * @param block
 230 * The block to submit to the target dispatch queue. This function performs
 231 * Block_copy() and Block_release() on behalf of callers.
 232 * The result of passing NULL in this parameter is undefined.
 233 */
 234#ifdef __BLOCKS__
 235API_AVAILABLE(macos(10.6), ios(4.0))
 236DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
 237DISPATCH_REFINED_FOR_SWIFT
 238void
 239dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
 240#endif
 241
 242/*!
 243 * @function dispatch_async_f
 244 *
 245 * @abstract
 246 * Submits a function for asynchronous execution on a dispatch queue.
 247 *
 248 * @discussion
 249 * See dispatch_async() for details.
 250 *
 251 * @param queue
 252 * The target dispatch queue to which the function is submitted.
 253 * The system will hold a reference on the target queue until the function
 254 * has returned.
 255 * The result of passing NULL in this parameter is undefined.
 256 *
 257 * @param context
 258 * The application-defined context parameter to pass to the function.
 259 *
 260 * @param work
 261 * The application-defined function to invoke on the target queue. The first
 262 * parameter passed to this function is the context provided to
 263 * dispatch_async_f().
 264 * The result of passing NULL in this parameter is undefined.
 265 */
 266API_AVAILABLE(macos(10.6), ios(4.0))
 267DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
 268DISPATCH_SWIFT_UNAVAILABLE("Use DispatchQueue.async(self:execute:)")
 269void
 270dispatch_async_f(dispatch_queue_t queue,
 271		void *_Nullable context, dispatch_function_t work);
 272
 273/*!
 274 * @function dispatch_sync
 275 *
 276 * @abstract
 277 * Submits a block for synchronous execution on a dispatch queue.
 278 *
 279 * @discussion
 280 * Submits a workitem to a dispatch queue like dispatch_async(), however
 281 * dispatch_sync() will not return until the workitem has finished.
 282 *
 283 * Work items submitted to a queue with dispatch_sync() do not observe certain
 284 * queue attributes of that queue when invoked (such as autorelease frequency
 285 * and QOS class).
 286 *
 287 * Calls to dispatch_sync() targeting the current queue will result
 288 * in dead-lock. Use of dispatch_sync() is also subject to the same
 289 * multi-party dead-lock problems that may result from the use of a mutex.
 290 * Use of dispatch_async() is preferred.
 291 *
 292 * Unlike dispatch_async(), no retain is performed on the target queue. Because
 293 * calls to this function are synchronous, the dispatch_sync() "borrows" the
 294 * reference of the caller.
 295 *
 296 * As an optimization, dispatch_sync() invokes the workitem on the thread which
 297 * submitted the workitem, except when the passed queue is the main queue or
 298 * a queue targetting it (See dispatch_queue_main_t,
 299 * dispatch_set_target_queue()).
 300 *
 301 * @param queue
 302 * The target dispatch queue to which the block is submitted.
 303 * The result of passing NULL in this parameter is undefined.
 304 *
 305 * @param block
 306 * The block to be invoked on the target dispatch queue.
 307 * The result of passing NULL in this parameter is undefined.
 308 */
 309#ifdef __BLOCKS__
 310API_AVAILABLE(macos(10.6), ios(4.0))
 311DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
 312DISPATCH_SWIFT_NAME(DispatchQueue.sync(self:execute:))
 313void
 314dispatch_sync(dispatch_queue_t queue, DISPATCH_NOESCAPE dispatch_block_t block);
 315#endif
 316
 317/*!
 318 * @function dispatch_sync_f
 319 *
 320 * @abstract
 321 * Submits a function for synchronous execution on a dispatch queue.
 322 *
 323 * @discussion
 324 * See dispatch_sync() for details.
 325 *
 326 * @param queue
 327 * The target dispatch queue to which the function is submitted.
 328 * The result of passing NULL in this parameter is undefined.
 329 *
 330 * @param context
 331 * The application-defined context parameter to pass to the function.
 332 *
 333 * @param work
 334 * The application-defined function to invoke on the target queue. The first
 335 * parameter passed to this function is the context provided to
 336 * dispatch_sync_f().
 337 * The result of passing NULL in this parameter is undefined.
 338 */
 339API_AVAILABLE(macos(10.6), ios(4.0))
 340DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
 341DISPATCH_SWIFT_UNAVAILABLE("Use DispatchQueue.sync(self:execute:)")
 342void
 343dispatch_sync_f(dispatch_queue_t queue,
 344		void *_Nullable context, dispatch_function_t work);
 345
 346/*!
 347 * @function dispatch_async_and_wait
 348 *
 349 * @abstract
 350 * Submits a block for synchronous execution on a dispatch queue.
 351 *
 352 * @discussion
 353 * Submits a workitem to a dispatch queue like dispatch_async(), however
 354 * dispatch_async_and_wait() will not return until the workitem has finished.
 355 *
 356 * Like functions of the dispatch_sync family, dispatch_async_and_wait() is
 357 * subject to dead-lock (See dispatch_sync() for details).
 358 *
 359 * However, dispatch_async_and_wait() differs from functions of the
 360 * dispatch_sync family in two fundamental ways: how it respects queue
 361 * attributes and how it chooses the execution context invoking the workitem.
 362 *
 363 * <b>Differences with dispatch_sync()</b>
 364 *
 365 * Work items submitted to a queue with dispatch_async_and_wait() observe all
 366 * queue attributes of that queue when invoked (including autorelease frequency
 367 * or QOS class).
 368 *
 369 * When the runtime has brought up a thread to invoke the asynchronous workitems
 370 * already submitted to the specified queue, that servicing thread will also be
 371 * used to execute synchronous work submitted to the queue with
 372 * dispatch_async_and_wait().
 373 *
 374 * However, if the runtime has not brought up a thread to service the specified
 375 * queue (because it has no workitems enqueued, or only synchronous workitems),
 376 * then dispatch_async_and_wait() will invoke the workitem on the calling thread,
 377 * similar to the behaviour of functions in the dispatch_sync family.
 378 *
 379 * As an exception, if the queue the work is submitted to doesn't target
 380 * a global concurrent queue (for example because it targets the main queue),
 381 * then the workitem will never be invoked by the thread calling
 382 * dispatch_async_and_wait().
 383 *
 384 * In other words, dispatch_async_and_wait() is similar to submitting
 385 * a dispatch_block_create()d workitem to a queue and then waiting on it, as
 386 * shown in the code example below. However, dispatch_async_and_wait() is
 387 * significantly more efficient when a new thread is not required to execute
 388 * the workitem (as it will use the stack of the submitting thread instead of
 389 * requiring heap allocations).
 390 *
 391 * <code>
 392 *     dispatch_block_t b = dispatch_block_create(0, block);
 393 *     dispatch_async(queue, b);
 394 *     dispatch_block_wait(b, DISPATCH_TIME_FOREVER);
 395 *     Block_release(b);
 396 * </code>
 397 *
 398 * @param queue
 399 * The target dispatch queue to which the block is submitted.
 400 * The result of passing NULL in this parameter is undefined.
 401 *
 402 * @param block
 403 * The block to be invoked on the target dispatch queue.
 404 * The result of passing NULL in this parameter is undefined.
 405 */
 406#ifdef __BLOCKS__
 407API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
 408DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
 409DISPATCH_SWIFT_NAME(DispatchQueue.asyncAndWait(self:execute:))
 410void
 411dispatch_async_and_wait(dispatch_queue_t queue,
 412		DISPATCH_NOESCAPE dispatch_block_t block);
 413#endif
 414
 415/*!
 416 * @function dispatch_async_and_wait_f
 417 *
 418 * @abstract
 419 * Submits a function for synchronous execution on a dispatch queue.
 420 *
 421 * @discussion
 422 * See dispatch_async_and_wait() for details.
 423 *
 424 * @param queue
 425 * The target dispatch queue to which the function is submitted.
 426 * The result of passing NULL in this parameter is undefined.
 427 *
 428 * @param context
 429 * The application-defined context parameter to pass to the function.
 430 *
 431 * @param work
 432 * The application-defined function to invoke on the target queue. The first
 433 * parameter passed to this function is the context provided to
 434 * dispatch_async_and_wait_f().
 435 * The result of passing NULL in this parameter is undefined.
 436 */
 437API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
 438DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
 439DISPATCH_SWIFT_UNAVAILABLE("Use DispatchQueue.asyncAndWait(self:execute:)")
 440void
 441dispatch_async_and_wait_f(dispatch_queue_t queue,
 442		void *_Nullable context, dispatch_function_t work);
 443
 444
 445#if defined(__APPLE__) && \
 446		(defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \
 447		__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0) || \
 448		(defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \
 449		__MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_9)
 450#define DISPATCH_APPLY_AUTO_AVAILABLE 0
 451#define DISPATCH_APPLY_QUEUE_ARG_NULLABILITY _Nonnull
 452#else
 453#define DISPATCH_APPLY_AUTO_AVAILABLE 1
 454#define DISPATCH_APPLY_QUEUE_ARG_NULLABILITY _Nullable
 455#endif
 456
 457/*!
 458 * @constant DISPATCH_APPLY_AUTO
 459 *
 460 * @abstract
 461 * Constant to pass to dispatch_apply() or dispatch_apply_f() to request that
 462 * the system automatically use worker threads that match the configuration of
 463 * the current thread as closely as possible.
 464 *
 465 * @discussion
 466 * When submitting a block for parallel invocation, passing this constant as the
 467 * queue argument will automatically use the global concurrent queue that
 468 * matches the Quality of Service of the caller most closely.
 469 *
 470 * No assumptions should be made about which global concurrent queue will
 471 * actually be used.
 472 *
 473 * Using this constant deploys backward to macOS 10.9, iOS 7.0 and any tvOS or
 474 * watchOS version.
 475 */
 476#if DISPATCH_APPLY_AUTO_AVAILABLE
 477#define DISPATCH_APPLY_AUTO ((dispatch_queue_t _Nonnull)0)
 478#endif
 479
 480/*!
 481 * @function dispatch_apply
 482 *
 483 * @abstract
 484 * Submits a block to a dispatch queue for parallel invocation.
 485 *
 486 * @discussion
 487 * Submits a block to a dispatch queue for parallel invocation. This function
 488 * waits for the task block to complete before returning. If the specified queue
 489 * is concurrent, the block may be invoked concurrently, and it must therefore
 490 * be reentrant safe.
 491 *
 492 * Each invocation of the block will be passed the current index of iteration.
 493 *
 494 * @param iterations
 495 * The number of iterations to perform.
 496 *
 497 * @param queue
 498 * The dispatch queue to which the block is submitted.
 499 * The preferred value to pass is DISPATCH_APPLY_AUTO to automatically use
 500 * a queue appropriate for the calling thread.
 501 *
 502 * @param block
 503 * The block to be invoked the specified number of iterations.
 504 * The result of passing NULL in this parameter is undefined.
 505 * This function performs a Block_copy() and Block_release() of the input block
 506 * on behalf of the callers. To elide the additional block allocation,
 507 * dispatch_apply_f may be used instead.
 508 */
 509#ifdef __BLOCKS__
 510API_AVAILABLE(macos(10.6), ios(4.0))
 511DISPATCH_EXPORT DISPATCH_NONNULL3 DISPATCH_NOTHROW
 512DISPATCH_REFINED_FOR_SWIFT
 513void
 514dispatch_apply(size_t iterations,
 515		dispatch_queue_t DISPATCH_APPLY_QUEUE_ARG_NULLABILITY queue,
 516		DISPATCH_NOESCAPE void (^block)(size_t iteration));
 517#endif
 518
 519/*!
 520 * @function dispatch_apply_f
 521 *
 522 * @abstract
 523 * Submits a function to a dispatch queue for parallel invocation.
 524 *
 525 * @discussion
 526 * See dispatch_apply() for details.
 527 *
 528 * @param iterations
 529 * The number of iterations to perform.
 530 *
 531 * @param queue
 532 * The dispatch queue to which the function is submitted.
 533 * The preferred value to pass is DISPATCH_APPLY_AUTO to automatically use
 534 * a queue appropriate for the calling thread.
 535 *
 536 * @param context
 537 * The application-defined context parameter to pass to the function.
 538 *
 539 * @param work
 540 * The application-defined function to invoke on the specified queue. The first
 541 * parameter passed to this function is the context provided to
 542 * dispatch_apply_f(). The second parameter passed to this function is the
 543 * current index of iteration.
 544 * The result of passing NULL in this parameter is undefined.
 545 */
 546API_AVAILABLE(macos(10.6), ios(4.0))
 547DISPATCH_EXPORT DISPATCH_NONNULL4 DISPATCH_NOTHROW
 548DISPATCH_SWIFT_UNAVAILABLE("Use DispatchQueue.concurrentPerform(iterations:execute:).")
 549void
 550dispatch_apply_f(size_t iterations,
 551		dispatch_queue_t DISPATCH_APPLY_QUEUE_ARG_NULLABILITY queue,
 552		void *_Nullable context, void (*work)(void *_Nullable context, size_t iteration));
 553
 554/*!
 555 * @function dispatch_get_current_queue
 556 *
 557 * @abstract
 558 * Returns the queue on which the currently executing block is running.
 559 *
 560 * @discussion
 561 * Returns the queue on which the currently executing block is running.
 562 *
 563 * When dispatch_get_current_queue() is called outside of the context of a
 564 * submitted block, it will return the default concurrent queue.
 565 *
 566 * Recommended for debugging and logging purposes only:
 567 * The code must not make any assumptions about the queue returned, unless it
 568 * is one of the global queues or a queue the code has itself created.
 569 * The code must not assume that synchronous execution onto a queue is safe
 570 * from deadlock if that queue is not the one returned by
 571 * dispatch_get_current_queue().
 572 *
 573 * When dispatch_get_current_queue() is called on the main thread, it may
 574 * or may not return the same value as dispatch_get_main_queue(). Comparing
 575 * the two is not a valid way to test whether code is executing on the
 576 * main thread (see dispatch_assert_queue() and dispatch_assert_queue_not()).
 577 *
 578 * This function is deprecated and will be removed in a future release.
 579 *
 580 * @result
 581 * Returns the current queue.
 582 */
 583API_DEPRECATED("unsupported interface", macos(10.6,10.9), ios(4.0,6.0))
 584DISPATCH_EXPORT DISPATCH_PURE DISPATCH_WARN_RESULT DISPATCH_NOTHROW
 585dispatch_queue_t
 586dispatch_get_current_queue(void);
 587
 588API_AVAILABLE(macos(10.6), ios(4.0))
 589DISPATCH_EXPORT
 590struct dispatch_queue_s _dispatch_main_q;
 591
 592/*!
 593 * @function dispatch_get_main_queue
 594 *
 595 * @abstract
 596 * Returns the default queue that is bound to the main thread.
 597 *
 598 * @discussion
 599 * In order to invoke blocks submitted to the main queue, the application must
 600 * call dispatch_main(), NSApplicationMain(), or use a CFRunLoop on the main
 601 * thread.
 602 *
 603 * The main queue is meant to be used in application context to interact with
 604 * the main thread and the main runloop.
 605 *
 606 * Because the main queue doesn't behave entirely like a regular serial queue,
 607 * it may have unwanted side-effects when used in processes that are not UI apps
 608 * (daemons). For such processes, the main queue should be avoided.
 609 *
 610 * @see dispatch_queue_main_t
 611 *
 612 * @result
 613 * Returns the main queue. This queue is created automatically on behalf of
 614 * the main thread before main() is called.
 615 */
 616DISPATCH_INLINE DISPATCH_ALWAYS_INLINE DISPATCH_CONST DISPATCH_NOTHROW
 617DISPATCH_SWIFT_UNAVAILABLE("Use getter:DispatchQueue.main()")
 618dispatch_queue_main_t
 619dispatch_get_main_queue(void)
 620{
 621	return DISPATCH_GLOBAL_OBJECT(dispatch_queue_main_t, _dispatch_main_q);
 622}
 623
 624/*!
 625 * @typedef dispatch_queue_priority_t
 626 * Type of dispatch_queue_priority
 627 *
 628 * @constant DISPATCH_QUEUE_PRIORITY_HIGH
 629 * Items dispatched to the queue will run at high priority,
 630 * i.e. the queue will be scheduled for execution before
 631 * any default priority or low priority queue.
 632 *
 633 * @constant DISPATCH_QUEUE_PRIORITY_DEFAULT
 634 * Items dispatched to the queue will run at the default
 635 * priority, i.e. the queue will be scheduled for execution
 636 * after all high priority queues have been scheduled, but
 637 * before any low priority queues have been scheduled.
 638 *
 639 * @constant DISPATCH_QUEUE_PRIORITY_LOW
 640 * Items dispatched to the queue will run at low priority,
 641 * i.e. the queue will be scheduled for execution after all
 642 * default priority and high priority queues have been
 643 * scheduled.
 644 *
 645 * @constant DISPATCH_QUEUE_PRIORITY_BACKGROUND
 646 * Items dispatched to the queue will run at background priority, i.e. the queue
 647 * will be scheduled for execution after all higher priority queues have been
 648 * scheduled and the system will run items on this queue on a thread with
 649 * background status as per setpriority(2) (i.e. disk I/O is throttled and the
 650 * thread's scheduling priority is set to lowest value).
 651 */
 652#define DISPATCH_QUEUE_PRIORITY_HIGH 2
 653#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
 654#define DISPATCH_QUEUE_PRIORITY_LOW (-2)
 655#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
 656
 657DISPATCH_SWIFT_UNAVAILABLE("Use DispatchQueue.GlobalQueuePriority")
 658typedef long dispatch_queue_priority_t;
 659
 660/*!
 661 * @function dispatch_get_global_queue
 662 *
 663 * @abstract
 664 * Returns a well-known global concurrent queue of a given quality of service
 665 * class.
 666 *
 667 * @discussion
 668 * See dispatch_queue_global_t.
 669 *
 670 * @param identifier
 671 * A quality of service class defined in qos_class_t or a priority defined in
 672 * dispatch_queue_priority_t.
 673 *
 674 * It is recommended to use quality of service class values to identify the
 675 * well-known global concurrent queues:
 676 *  - QOS_CLASS_USER_INTERACTIVE
 677 *  - QOS_CLASS_USER_INITIATED
 678 *  - QOS_CLASS_DEFAULT
 679 *  - QOS_CLASS_UTILITY
 680 *  - QOS_CLASS_BACKGROUND
 681 *
 682 * The global concurrent queues may still be identified by their priority,
 683 * which map to the following QOS classes:
 684 *  - DISPATCH_QUEUE_PRIORITY_HIGH:         QOS_CLASS_USER_INITIATED
 685 *  - DISPATCH_QUEUE_PRIORITY_DEFAULT:      QOS_CLASS_DEFAULT
 686 *  - DISPATCH_QUEUE_PRIORITY_LOW:          QOS_CLASS_UTILITY
 687 *  - DISPATCH_QUEUE_PRIORITY_BACKGROUND:   QOS_CLASS_BACKGROUND
 688 *
 689 * @param flags
 690 * Reserved for future use. Passing any value other than zero may result in
 691 * a NULL return value.
 692 *
 693 * @result
 694 * Returns the requested global queue or NULL if the requested global queue
 695 * does not exist.
 696 */
 697API_AVAILABLE(macos(10.6), ios(4.0))
 698DISPATCH_EXPORT DISPATCH_CONST DISPATCH_WARN_RESULT DISPATCH_NOTHROW
 699DISPATCH_REFINED_FOR_SWIFT
 700dispatch_queue_global_t
 701dispatch_get_global_queue(intptr_t identifier, uintptr_t flags);
 702
 703/*!
 704 * @typedef dispatch_queue_attr_t
 705 *
 706 * @abstract
 707 * Attribute for dispatch queues.
 708 */
 709DISPATCH_REFINED_FOR_SWIFT
 710DISPATCH_DECL(dispatch_queue_attr);
 711
 712/*!
 713 * @const DISPATCH_QUEUE_SERIAL
 714 *
 715 * @discussion
 716 * An attribute that can be used to create a dispatch queue that invokes blocks
 717 * serially in FIFO order.
 718 *
 719 * See dispatch_queue_serial_t.
 720 */
 721#define DISPATCH_QUEUE_SERIAL NULL
 722
 723/*!
 724 * @const DISPATCH_QUEUE_SERIAL_INACTIVE
 725 *
 726 * @discussion
 727 * An attribute that can be used to create a dispatch queue that invokes blocks
 728 * serially in FIFO order, and that is initially inactive.
 729 *
 730 * See dispatch_queue_attr_make_initially_inactive().
 731 */
 732#define DISPATCH_QUEUE_SERIAL_INACTIVE \
 733		dispatch_queue_attr_make_initially_inactive(DISPATCH_QUEUE_SERIAL)
 734
 735/*!
 736 * @const DISPATCH_QUEUE_CONCURRENT
 737 *
 738 * @discussion
 739 * An attribute that can be used to create a dispatch queue that may invoke
 740 * blocks concurrently and supports barrier blocks submitted with the dispatch
 741 * barrier API.
 742 *
 743 * See dispatch_queue_concurrent_t.
 744 */
 745#define DISPATCH_QUEUE_CONCURRENT \
 746		DISPATCH_GLOBAL_OBJECT(dispatch_queue_attr_t, \
 747		_dispatch_queue_attr_concurrent)
 748API_AVAILABLE(macos(10.7), ios(4.3))
 749DISPATCH_EXPORT
 750struct dispatch_queue_attr_s _dispatch_queue_attr_concurrent;
 751
 752/*!
 753 * @const DISPATCH_QUEUE_CONCURRENT_INACTIVE
 754 *
 755 * @discussion
 756 * An attribute that can be used to create a dispatch queue that may invoke
 757 * blocks concurrently and supports barrier blocks submitted with the dispatch
 758 * barrier API, and that is initially inactive.
 759 *
 760 * See dispatch_queue_attr_make_initially_inactive().
 761 */
 762#define DISPATCH_QUEUE_CONCURRENT_INACTIVE \
 763		dispatch_queue_attr_make_initially_inactive(DISPATCH_QUEUE_CONCURRENT)
 764
 765/*!
 766 * @function dispatch_queue_attr_make_initially_inactive
 767 *
 768 * @abstract
 769 * Returns an attribute value which may be provided to dispatch_queue_create()
 770 * or dispatch_queue_create_with_target(), in order to make the created queue
 771 * initially inactive.
 772 *
 773 * @discussion
 774 * Dispatch queues may be created in an inactive state. Queues in this state
 775 * have to be activated before any blocks associated with them will be invoked.
 776 *
 777 * A queue in inactive state cannot be deallocated, dispatch_activate() must be
 778 * called before the last reference to a queue created with this attribute is
 779 * released.
 780 *
 781 * The target queue of a queue in inactive state can be changed using
 782 * dispatch_set_target_queue(). Change of target queue is no longer permitted
 783 * once an initially inactive queue has been activated.
 784 *
 785 * @param attr
 786 * A queue attribute value to be combined with the initially inactive attribute.
 787 *
 788 * @return
 789 * Returns an attribute value which may be provided to dispatch_queue_create()
 790 * and dispatch_queue_create_with_target().
 791 * The new value combines the attributes specified by the 'attr' parameter with
 792 * the initially inactive attribute.
 793 */
 794API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
 795DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_PURE DISPATCH_NOTHROW
 796DISPATCH_REFINED_FOR_SWIFT
 797dispatch_queue_attr_t
 798dispatch_queue_attr_make_initially_inactive(
 799		dispatch_queue_attr_t _Nullable attr);
 800
 801/*!
 802 * @const DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL
 803 *
 804 * @discussion
 805 * A dispatch queue created with this attribute invokes blocks serially in FIFO
 806 * order, and surrounds execution of any block submitted asynchronously to it
 807 * with the equivalent of a individual Objective-C <code>@autoreleasepool</code>
 808 * scope.
 809 *
 810 * See dispatch_queue_attr_make_with_autorelease_frequency().
 811 */
 812#define DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL \
 813		dispatch_queue_attr_make_with_autorelease_frequency(\
 814				DISPATCH_QUEUE_SERIAL, DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM)
 815
 816/*!
 817 * @const DISPATCH_QUEUE_CONCURRENT_WITH_AUTORELEASE_POOL
 818 *
 819 * @discussion
 820 * A dispatch queue created with this attribute may invokes blocks concurrently
 821 * and supports barrier blocks submitted with the dispatch barrier API. It also
 822 * surrounds execution of any block submitted asynchronously to it with the
 823 * equivalent of a individual Objective-C <code>@autoreleasepool</code>
 824 *
 825 * See dispatch_queue_attr_make_with_autorelease_frequency().
 826 */
 827#define DISPATCH_QUEUE_CONCURRENT_WITH_AUTORELEASE_POOL \
 828		dispatch_queue_attr_make_with_autorelease_frequency(\
 829				DISPATCH_QUEUE_CONCURRENT, DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM)
 830
 831/*!
 832 * @typedef dispatch_autorelease_frequency_t
 833 * Values to pass to the dispatch_queue_attr_make_with_autorelease_frequency()
 834 * function.
 835 *
 836 * @const DISPATCH_AUTORELEASE_FREQUENCY_INHERIT
 837 * Dispatch queues with this autorelease frequency inherit the behavior from
 838 * their target queue. This is the default behavior for manually created queues.
 839 *
 840 * @const DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM
 841 * Dispatch queues with this autorelease frequency push and pop an autorelease
 842 * pool around the execution of every block that was submitted to it
 843 * asynchronously.
 844 * @see dispatch_queue_attr_make_with_autorelease_frequency().
 845 *
 846 * @const DISPATCH_AUTORELEASE_FREQUENCY_NEVER
 847 * Dispatch queues with this autorelease frequency never set up an individual
 848 * autorelease pool around the execution of a block that is submitted to it
 849 * asynchronously. This is the behavior of the global concurrent queues.
 850 */
 851DISPATCH_REFINED_FOR_SWIFT
 852DISPATCH_ENUM(dispatch_autorelease_frequency, unsigned long,
 853	DISPATCH_AUTORELEASE_FREQUENCY_INHERIT DISPATCH_ENUM_API_AVAILABLE(
 854			macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
 855			DISPATCH_SWIFT_UNAVAILABLE("Use DispatchQueue.AutoreleaseFrequency.inherit") = 0,
 856	DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM DISPATCH_ENUM_API_AVAILABLE(
 857			macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
 858			DISPATCH_SWIFT_UNAVAILABLE("Use DispatchQueue.AutoreleaseFrequency.workItem") = 1,
 859	DISPATCH_AUTORELEASE_FREQUENCY_NEVER DISPATCH_ENUM_API_AVAILABLE(
 860			macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
 861			DISPATCH_SWIFT_UNAVAILABLE("Use DispatchQueue.AutoreleaseFrequency.never") = 2,
 862);
 863
 864/*!
 865 * @function dispatch_queue_attr_make_with_autorelease_frequency
 866 *
 867 * @abstract
 868 * Returns a dispatch queue attribute value with the autorelease frequency
 869 * set to the specified value.
 870 *
 871 * @discussion
 872 * When a queue uses the per-workitem autorelease frequency (either directly
 873 * or inherited from its target queue), any block submitted asynchronously to
 874 * this queue (via dispatch_async(), dispatch_barrier_async(),
 875 * dispatch_group_notify(), etc...) is executed as if surrounded by a individual
 876 * Objective-C <code>@autoreleasepool</code> scope.
 877 *
 878 * Autorelease frequency has no effect on blocks that are submitted
 879 * synchronously to a queue (via dispatch_sync(), dispatch_barrier_sync()).
 880 *
 881 * The global concurrent queues have the DISPATCH_AUTORELEASE_FREQUENCY_NEVER
 882 * behavior. Manually created dispatch queues use
 883 * DISPATCH_AUTORELEASE_FREQUENCY_INHERIT by default.
 884 *
 885 * Queues created with this attribute cannot change target queues after having
 886 * been activated. See dispatch_set_target_queue() and dispatch_activate().
 887 *
 888 * @param attr
 889 * A queue attribute value to be combined with the specified autorelease
 890 * frequency or NULL.
 891 *
 892 * @param frequency
 893 * The requested autorelease frequency.
 894 *
 895 * @return
 896 * Returns an attribute value which may be provided to dispatch_queue_create()
 897 * or NULL if an invalid autorelease frequency was requested.
 898 * This new value combines the attributes specified by the 'attr' parameter and
 899 * the chosen autorelease frequency.
 900 */
 901API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
 902DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_PURE DISPATCH_NOTHROW
 903DISPATCH_REFINED_FOR_SWIFT
 904dispatch_queue_attr_t
 905dispatch_queue_attr_make_with_autorelease_frequency(
 906		dispatch_queue_attr_t _Nullable attr,
 907		dispatch_autorelease_frequency_t frequency);
 908
 909/*!
 910 * @function dispatch_queue_attr_make_with_qos_class
 911 *
 912 * @abstract
 913 * Returns an attribute value which may be provided to dispatch_queue_create()
 914 * or dispatch_queue_create_with_target(), in order to assign a QOS class and
 915 * relative priority to the queue.
 916 *
 917 * @discussion
 918 * When specified in this manner, the QOS class and relative priority take
 919 * precedence over those inherited from the dispatch queue's target queue (if
 920 * any) as long that does not result in a lower QOS class and relative priority.
 921 *
 922 * The global queue priorities map to the following QOS classes:
 923 *  - DISPATCH_QUEUE_PRIORITY_HIGH:         QOS_CLASS_USER_INITIATED
 924 *  - DISPATCH_QUEUE_PRIORITY_DEFAULT:      QOS_CLASS_DEFAULT
 925 *  - DISPATCH_QUEUE_PRIORITY_LOW:          QOS_CLASS_UTILITY
 926 *  - DISPATCH_QUEUE_PRIORITY_BACKGROUND:   QOS_CLASS_BACKGROUND
 927 *
 928 * Example:
 929 * <code>
 930 *	dispatch_queue_t queue;
 931 *	dispatch_queue_attr_t attr;
 932 *	attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL,
 933 *			QOS_CLASS_UTILITY, 0);
 934 *	queue = dispatch_queue_create("com.example.myqueue", attr);
 935 * </code>
 936 *
 937 * The QOS class and relative priority set this way on a queue have no effect on
 938 * blocks that are submitted synchronously to a queue (via dispatch_sync(),
 939 * dispatch_barrier_sync()).
 940 *
 941 * @param attr
 942 * A queue attribute value to be combined with the QOS class, or NULL.
 943 *
 944 * @param qos_class
 945 * A QOS class value:
 946 *  - QOS_CLASS_USER_INTERACTIVE
 947 *  - QOS_CLASS_USER_INITIATED
 948 *  - QOS_CLASS_DEFAULT
 949 *  - QOS_CLASS_UTILITY
 950 *  - QOS_CLASS_BACKGROUND
 951 * Passing any other value results in NULL being returned.
 952 *
 953 * @param relative_priority
 954 * A relative priority within the QOS class. This value is a negative
 955 * offset from the maximum supported scheduler priority for the given class.
 956 * Passing a value greater than zero or less than QOS_MIN_RELATIVE_PRIORITY
 957 * results in NULL being returned.
 958 *
 959 * @return
 960 * Returns an attribute value which may be provided to dispatch_queue_create()
 961 * and dispatch_queue_create_with_target(), or NULL if an invalid QOS class was
 962 * requested.
 963 * The new value combines the attributes specified by the 'attr' parameter and
 964 * the new QOS class and relative priority.
 965 */
 966API_AVAILABLE(macos(10.10), ios(8.0))
 967DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_PURE DISPATCH_NOTHROW
 968DISPATCH_REFINED_FOR_SWIFT
 969dispatch_queue_attr_t
 970dispatch_queue_attr_make_with_qos_class(dispatch_queue_attr_t _Nullable attr,
 971		dispatch_qos_class_t qos_class, int relative_priority);
 972
 973/*!
 974 * @const DISPATCH_TARGET_QUEUE_DEFAULT
 975 * @discussion Constant to pass to the dispatch_queue_create_with_target(),
 976 * dispatch_set_target_queue() and dispatch_source_create() functions to
 977 * indicate that the default target queue for the object type in question
 978 * should be used.
 979 */
 980#define DISPATCH_TARGET_QUEUE_DEFAULT NULL
 981
 982/*!
 983 * @function dispatch_queue_create_with_target
 984 *
 985 * @abstract
 986 * Creates a new dispatch queue with a specified target queue.
 987 *
 988 * @discussion
 989 * Dispatch queues created with the DISPATCH_QUEUE_SERIAL or a NULL attribute
 990 * invoke blocks serially in FIFO order.
 991 *
 992 * Dispatch queues created with the DISPATCH_QUEUE_CONCURRENT attribute may
 993 * invoke blocks concurrently (similarly to the global concurrent queues, but
 994 * potentially with more overhead), and support barrier blocks submitted with
 995 * the dispatch barrier API, which e.g. enables the implementation of efficient
 996 * reader-writer schemes.
 997 *
 998 * When a dispatch queue is no longer needed, it should be released with
 999 * dispatch_release(). Note that any pending blocks submitted asynchronously to
1000 * a queue will hold a reference to that queue. Therefore a queue will not be
1001 * deallocated until all pending blocks have finished.
1002 *
1003 * When using a dispatch queue attribute @a attr specifying a QoS class (derived
1004 * from the result of dispatch_queue_attr_make_with_qos_class()), passing the
1005 * result of dispatch_get_global_queue() in @a target will ignore the QoS class
1006 * of that global queue and will use the global queue with the QoS class
1007 * specified by attr instead.
1008 *
1009 * Queues created with dispatch_queue_create_with_target() cannot have their
1010 * target queue changed, unless created inactive (See
1011 * dispatch_queue_attr_make_initially_inactive()), in which case the target
1012 * queue can be changed until the newly created queue is activated with
1013 * dispatch_activate().
1014 *
1015 * @param label
1016 * A string label to attach to the queue.
1017 * This parameter is optional and may be NULL.
1018 *
1019 * @param attr
1020 * A predefined attribute such as DISPATCH_QUEUE_SERIAL,
1021 * DISPATCH_QUEUE_CONCURRENT, or the result of a call to
1022 * a dispatch_queue_attr_make_with_* function.
1023 *
1024 * @param target
1025 * The target queue for the newly created queue. The target queue is retained.
1026 * If this parameter is DISPATCH_TARGET_QUEUE_DEFAULT, sets the queue's target
1027 * queue to the default target queue for the given queue type.
1028 *
1029 * @result
1030 * The newly created dispatch queue.
1031 */
1032API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
1033DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
1034DISPATCH_NOTHROW
1035DISPATCH_REFINED_FOR_SWIFT DISPATCH_SWIFT_NAME(DispatchQueue.init(__label:attr:queue:))
1036dispatch_queue_t
1037dispatch_queue_create_with_target(const char *_Nullable DISPATCH_UNSAFE_INDEXABLE label,
1038		dispatch_queue_attr_t _Nullable attr, dispatch_queue_t _Nullable target)
1039		DISPATCH_ALIAS_V2(dispatch_queue_create_with_target);
1040
1041/*!
1042 * @function dispatch_queue_create
1043 *
1044 * @abstract
1045 * Creates a new dispatch queue to which blocks may be submitted.
1046 *
1047 * @discussion
1048 * Dispatch queues created with the DISPATCH_QUEUE_SERIAL or a NULL attribute
1049 * invoke blocks serially in FIFO order.
1050 *
1051 * Dispatch queues created with the DISPATCH_QUEUE_CONCURRENT attribute may
1052 * invoke blocks concurrently (similarly to the global concurrent queues, but
1053 * potentially with more overhead), and support barrier blocks submitted with
1054 * the dispatch barrier API, which e.g. enables the implementation of efficient
1055 * reader-writer schemes.
1056 *
1057 * When a dispatch queue is no longer needed, it should be released with
1058 * dispatch_release(). Note that any pending blocks submitted asynchronously to
1059 * a queue will hold a reference to that queue. Therefore a queue will not be
1060 * deallocated until all pending blocks have finished.
1061 *
1062 * Passing the result of the dispatch_queue_attr_make_with_qos_class() function
1063 * to the attr parameter of this function allows a quality of service class and
1064 * relative priority to be specified for the newly created queue.
1065 * The quality of service class so specified takes precedence over the quality
1066 * of service class of the newly created dispatch queue's target queue (if any)
1067 * as long that does not result in a lower QOS class and relative priority.
1068 *
1069 * When no quality of service class is specified, the target queue of a newly
1070 * created dispatch queue is the default priority global concurrent queue.
1071 *
1072 * Unless explicitly specified via the attribute, queues are created active.
1073 *
1074 * @param label
1075 * A string label to attach to the queue.
1076 * This parameter is optional and may be NULL.
1077 *
1078 * @param attr
1079 * A predefined attribute such as DISPATCH_QUEUE_SERIAL,
1080 * DISPATCH_QUEUE_CONCURRENT, or the result of a call to
1081 * a dispatch_queue_attr_make_with_* function.
1082 *
1083 * @result
1084 * The newly created dispatch queue.
1085 */
1086API_AVAILABLE(macos(10.6), ios(4.0))
1087DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
1088DISPATCH_NOTHROW
1089DISPATCH_REFINED_FOR_SWIFT DISPATCH_SWIFT_NAME(DispatchQueue.init(__label:attr:))
1090dispatch_queue_t
1091dispatch_queue_create(const char *_Nullable DISPATCH_UNSAFE_INDEXABLE label,
1092		dispatch_queue_attr_t _Nullable attr);
1093
1094/*!
1095 * @const DISPATCH_CURRENT_QUEUE_LABEL
1096 * @discussion Constant to pass to the dispatch_queue_get_label() function to
1097 * retrieve the label of the current queue.
1098 */
1099#define DISPATCH_CURRENT_QUEUE_LABEL NULL
1100
1101/*!
1102 * @function dispatch_queue_get_label
1103 *
1104 * @abstract
1105 * Returns the label of the given queue, as specified when the queue was
1106 * created, or the empty string if a NULL label was specified.
1107 *
1108 * Passing DISPATCH_CURRENT_QUEUE_LABEL will return the label of the current
1109 * queue.
1110 *
1111 * @param queue
1112 * The queue to query, or DISPATCH_CURRENT_QUEUE_LABEL.
1113 *
1114 * @result
1115 * The label of the queue.
1116 */
1117API_AVAILABLE(macos(10.6), ios(4.0))
1118DISPATCH_EXPORT DISPATCH_PURE DISPATCH_WARN_RESULT DISPATCH_NOTHROW
1119DISPATCH_REFINED_FOR_SWIFT
1120const char *
1121dispatch_queue_get_label(dispatch_queue_t _Nullable queue);
1122
1123/*!
1124 * @function dispatch_queue_get_qos_class
1125 *
1126 * @abstract
1127 * Returns the QOS class and relative priority of the given queue.
1128 *
1129 * @discussion
1130 * If the given queue was created with an attribute value returned from
1131 * dispatch_queue_attr_make_with_qos_class(), this function returns the QOS
1132 * class and relative priority specified at that time; for any other attribute
1133 * value it returns a QOS class of QOS_CLASS_UNSPECIFIED and a relative
1134 * priority of 0.
1135 *
1136 * If the given queue is one of the global queues, this function returns its
1137 * assigned QOS class value as documented under dispatch_get_global_queue() and
1138 * a relative priority of 0; in the case of the main queue it returns the QOS
1139 * value provided by qos_class_main() and a relative priority of 0.
1140 *
1141 * @param queue
1142 * The queue to query.
1143 *
1144 * @param relative_priority_ptr
1145 * A pointer to an int variable to be filled with the relative priority offset
1146 * within the QOS class, or NULL.
1147 *
1148 * @return
1149 * A QOS class value:
1150 *	- QOS_CLASS_USER_INTERACTIVE
1151 *	- QOS_CLASS_USER_INITIATED
1152 *	- QOS_CLASS_DEFAULT
1153 *	- QOS_CLASS_UTILITY
1154 *	- QOS_CLASS_BACKGROUND
1155 *	- QOS_CLASS_UNSPECIFIED
1156 */
1157API_AVAILABLE(macos(10.10), ios(8.0))
1158DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_NONNULL1 DISPATCH_NOTHROW
1159DISPATCH_REFINED_FOR_SWIFT
1160dispatch_qos_class_t
1161dispatch_queue_get_qos_class(dispatch_queue_t queue,
1162		int *_Nullable relative_priority_ptr);
1163
1164/*!
1165 * @function dispatch_set_target_queue
1166 *
1167 * @abstract
1168 * Sets the target queue for the given object.
1169 *
1170 * @discussion
1171 * An object's target queue is responsible for processing the object.
1172 *
1173 * When no quality of service class and relative priority is specified for a
1174 * dispatch queue at the time of creation, a dispatch queue's quality of service
1175 * class is inherited from its target queue. The dispatch_get_global_queue()
1176 * function may be used to obtain a target queue of a specific quality of
1177 * service class, however the use of dispatch_queue_attr_make_with_qos_class()
1178 * is recommended instead.
1179 *
1180 * Blocks submitted to a serial queue whose target queue is another serial
1181 * queue will not be invoked concurrently with blocks submitted to the target
1182 * queue or to any other queue with that same target queue.
1183 *
1184 * The result of introducing a cycle into the hierarchy of target queues is
1185 * undefined.
1186 *
1187 * A dispatch source's target queue specifies where its event handler and
1188 * cancellation handler blocks will be submitted.
1189 *
1190 * A dispatch I/O channel's target queue specifies where where its I/O
1191 * operations are executed. If the channel's target queue's priority is set to
1192 * DISPATCH_QUEUE_PRIORITY_BACKGROUND, then the I/O operations performed by
1193 * dispatch_io_read() or dispatch_io_write() on that queue will be
1194 * throttled when there is I/O contention.
1195 *
1196 * For all other dispatch object types, the only function of the target queue
1197 * is to determine where an object's finalizer function is invoked.
1198 *
1199 * In general, changing the target queue of an object is an asynchronous
1200 * operation that doesn't take effect immediately, and doesn't affect blocks
1201 * already associated with the specified object.
1202 *
1203 * However, if an object is inactive at the time dispatch_set_target_queue() is
1204 * called, then the target queue change takes effect immediately, and will
1205 * affect blocks already associated with the specified object. After an
1206 * initially inactive object has been activated, calling
1207 * dispatch_set_target_queue() results in an assertion and the process being
1208 * terminated.
1209 *
1210 * If a dispatch queue is active and targeted by other dispatch objects,
1211 * changing its target queue results in undefined behavior.  Instead, it is
1212 * recommended to create dispatch objects in an inactive state, set up the
1213 * relevant target queues and then activate them.
1214 *
1215 * @param object
1216 * The object to modify.
1217 * The result of passing NULL in this parameter is undefined.
1218 *
1219 * @param queue
1220 * The new target queue for the object. The queue is retained, and the
1221 * previous target queue, if any, is released.
1222 * If queue is DISPATCH_TARGET_QUEUE_DEFAULT, set the object's target queue
1223 * to the default target queue for the given object type.
1224 */
1225API_AVAILABLE(macos(10.6), ios(4.0))
1226DISPATCH_EXPORT DISPATCH_NOTHROW
1227DISPATCH_SWIFT_NAME(DispatchObject.setTarget(self:queue:))
1228void
1229dispatch_set_target_queue(dispatch_object_t object,
1230		dispatch_queue_t _Nullable queue);
1231
1232/*!
1233 * @function dispatch_main
1234 *
1235 * @abstract
1236 * Execute blocks submitted to the main queue.
1237 *
1238 * @discussion
1239 * This function "parks" the main thread and waits for blocks to be submitted
1240 * to the main queue. This function never returns.
1241 *
1242 * Applications that call NSApplicationMain() or CFRunLoopRun() on the
1243 * main thread do not need to call dispatch_main().
1244 */
1245API_AVAILABLE(macos(10.6), ios(4.0))
1246DISPATCH_EXPORT DISPATCH_NOTHROW DISPATCH_NORETURN
1247DISPATCH_SWIFT_NAME(dispatchMain())
1248void
1249dispatch_main(void);
1250
1251/*!
1252 * @function dispatch_after
1253 *
1254 * @abstract
1255 * Schedule a block for execution on a given queue at a specified time.
1256 *
1257 * @discussion
1258 * Passing DISPATCH_TIME_NOW as the "when" parameter is supported, but not as
1259 * optimal as calling dispatch_async() instead. Passing DISPATCH_TIME_FOREVER
1260 * is undefined.
1261 *
1262 * @param when
1263 * A temporal milestone returned by dispatch_time() or dispatch_walltime().
1264 *
1265 * @param queue
1266 * A queue to which the given block will be submitted at the specified time.
1267 * The result of passing NULL in this parameter is undefined.
1268 *
1269 * @param block
1270 * The block of code to execute.
1271 * The result of passing NULL in this parameter is undefined.
1272 */
1273#ifdef __BLOCKS__
1274API_AVAILABLE(macos(10.6), ios(4.0))
1275DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NONNULL3 DISPATCH_NOTHROW
1276DISPATCH_REFINED_FOR_SWIFT
1277void
1278dispatch_after(dispatch_time_t when, dispatch_queue_t queue,
1279		dispatch_block_t block);
1280#endif
1281
1282/*!
1283 * @function dispatch_after_f
1284 *
1285 * @abstract
1286 * Schedule a function for execution on a given queue at a specified time.
1287 *
1288 * @discussion
1289 * See dispatch_after() for details.
1290 *
1291 * @param when
1292 * A temporal milestone returned by dispatch_time() or dispatch_walltime().
1293 *
1294 * @param queue
1295 * A queue to which the given function will be submitted at the specified time.
1296 * The result of passing NULL in this parameter is undefined.
1297 *
1298 * @param context
1299 * The application-defined context parameter to pass to the function.
1300 *
1301 * @param work
1302 * The application-defined function to invoke on the target queue. The first
1303 * parameter passed to this function is the context provided to
1304 * dispatch_after_f().
1305 * The result of passing NULL in this parameter is undefined.
1306 */
1307API_AVAILABLE(macos(10.6), ios(4.0))
1308DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NONNULL4 DISPATCH_NOTHROW
1309DISPATCH_SWIFT_UNAVAILABLE("Use DispatchQueue.asyncAfter(self:deadline:qos:flags:execute:)")
1310void
1311dispatch_after_f(dispatch_time_t when, dispatch_queue_t queue,
1312		void *_Nullable context, dispatch_function_t work);
1313
1314/*!
1315 * @functiongroup Dispatch Barrier API
1316 * The dispatch barrier API is a mechanism for submitting barrier blocks to a
1317 * dispatch queue, analogous to the dispatch_async()/dispatch_sync() API.
1318 * It enables the implementation of efficient reader/writer schemes.
1319 * Barrier blocks only behave specially when submitted to queues created with
1320 * the DISPATCH_QUEUE_CONCURRENT attribute; on such a queue, a barrier block
1321 * will not run until all blocks submitted to the queue earlier have completed,
1322 * and any blocks submitted to the queue after a barrier block will not run
1323 * until the barrier block has completed.
1324 * When submitted to a a global queue or to a queue not created with the
1325 * DISPATCH_QUEUE_CONCURRENT attribute, barrier blocks behave identically to
1326 * blocks submitted with the dispatch_async()/dispatch_sync() API.
1327 */
1328
1329/*!
1330 * @function dispatch_barrier_async
1331 *
1332 * @abstract
1333 * Submits a barrier block for asynchronous execution on a dispatch queue.
1334 *
1335 * @discussion
1336 * Submits a block to a dispatch queue like dispatch_async(), but marks that
1337 * block as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT queues).
1338 *
1339 * See dispatch_async() for details and "Dispatch Barrier API" for a description
1340 * of the barrier semantics.
1341 *
1342 * @param queue
1343 * The target dispatch queue to which the block is submitted.
1344 * The system will hold a reference on the target queue until the block
1345 * has finished.
1346 * The result of passing NULL in this parameter is undefined.
1347 *
1348 * @param block
1349 * The block to submit to the target dispatch queue. This function performs
1350 * Block_copy() and Block_release() on behalf of callers.
1351 * The result of passing NULL in this parameter is undefined.
1352 */
1353#ifdef __BLOCKS__
1354API_AVAILABLE(macos(10.7), ios(4.3))
1355DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
1356DISPATCH_REFINED_FOR_SWIFT
1357void
1358dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
1359#endif
1360
1361/*!
1362 * @function dispatch_barrier_async_f
1363 *
1364 * @abstract
1365 * Submits a barrier function for asynchronous execution on a dispatch queue.
1366 *
1367 * @discussion
1368 * Submits a function to a dispatch queue like dispatch_async_f(), but marks
1369 * that function as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT
1370 * queues).
1371 *
1372 * See dispatch_async_f() for details and "Dispatch Barrier API" for a
1373 * description of the barrier semantics.
1374 *
1375 * @param queue
1376 * The target dispatch queue to which the function is submitted.
1377 * The system will hold a reference on the target queue until the function
1378 * has returned.
1379 * The result of passing NULL in this parameter is undefined.
1380 *
1381 * @param context
1382 * The application-defined context parameter to pass to the function.
1383 *
1384 * @param work
1385 * The application-defined function to invoke on the target queue. The first
1386 * parameter passed to this function is the context provided to
1387 * dispatch_barrier_async_f().
1388 * The result of passing NULL in this parameter is undefined.
1389 */
1390API_AVAILABLE(macos(10.7), ios(4.3))
1391DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
1392DISPATCH_SWIFT_UNAVAILABLE("Use DispatchQueue.async(self:group:qos:flags:execute:)")
1393void
1394dispatch_barrier_async_f(dispatch_queue_t queue,
1395		void *_Nullable context, dispatch_function_t work);
1396
1397/*!
1398 * @function dispatch_barrier_sync
1399 *
1400 * @abstract
1401 * Submits a barrier block for synchronous execution on a dispatch queue.
1402 *
1403 * @discussion
1404 * Submits a block to a dispatch queue like dispatch_sync(), but marks that
1405 * block as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT queues).
1406 *
1407 * See dispatch_sync() for details and "Dispatch Barrier API" for a description
1408 * of the barrier semantics.
1409 *
1410 * @param queue
1411 * The target dispatch queue to which the block is submitted.
1412 * The result of passing NULL in this parameter is undefined.
1413 *
1414 * @param block
1415 * The block to be invoked on the target dispatch queue.
1416 * The result of passing NULL in this parameter is undefined.
1417 */
1418#ifdef __BLOCKS__
1419API_AVAILABLE(macos(10.7), ios(4.3))
1420DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
1421DISPATCH_REFINED_FOR_SWIFT
1422void
1423dispatch_barrier_sync(dispatch_queue_t queue,
1424		DISPATCH_NOESCAPE dispatch_block_t block);
1425#endif
1426
1427/*!
1428 * @function dispatch_barrier_sync_f
1429 *
1430 * @abstract
1431 * Submits a barrier function for synchronous execution on a dispatch queue.
1432 *
1433 * @discussion
1434 * Submits a function to a dispatch queue like dispatch_sync_f(), but marks that
1435 * fuction as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT queues).
1436 *
1437 * See dispatch_sync_f() for details.
1438 *
1439 * @param queue
1440 * The target dispatch queue to which the function is submitted.
1441 * The result of passing NULL in this parameter is undefined.
1442 *
1443 * @param context
1444 * The application-defined context parameter to pass to the function.
1445 *
1446 * @param work
1447 * The application-defined function to invoke on the target queue. The first
1448 * parameter passed to this function is the context provided to
1449 * dispatch_barrier_sync_f().
1450 * The result of passing NULL in this parameter is undefined.
1451 */
1452API_AVAILABLE(macos(10.7), ios(4.3))
1453DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
1454DISPATCH_SWIFT_UNAVAILABLE("Use DispatchQueue.sync(self:flags:execute:)")
1455void
1456dispatch_barrier_sync_f(dispatch_queue_t queue,
1457		void *_Nullable context, dispatch_function_t work);
1458
1459/*!
1460 * @function dispatch_barrier_async_and_wait
1461 *
1462 * @abstract
1463 * Submits a block for synchronous execution on a dispatch queue.
1464 *
1465 * @discussion
1466 * Submits a block to a dispatch queue like dispatch_async_and_wait(), but marks
1467 * that block as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT
1468 * queues).
1469 *
1470 * See "Dispatch Barrier API" for a description of the barrier semantics.
1471 *
1472 * @param queue
1473 * The target dispatch queue to which the block is submitted.
1474 * The result of passing NULL in this parameter is undefined.
1475 *
1476 * @param work
1477 * The application-defined block to invoke on the target queue.
1478 * The result of passing NULL in this parameter is undefined.
1479 */
1480#ifdef __BLOCKS__
1481API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
1482DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
1483DISPATCH_SWIFT_UNAVAILABLE("Unavailable in Swift")
1484void
1485dispatch_barrier_async_and_wait(dispatch_queue_t queue,
1486		DISPATCH_NOESCAPE dispatch_block_t block);
1487#endif
1488
1489/*!
1490 * @function dispatch_barrier_async_and_wait_f
1491 *
1492 * @abstract
1493 * Submits a function for synchronous execution on a dispatch queue.
1494 *
1495 * @discussion
1496 * Submits a function to a dispatch queue like dispatch_async_and_wait_f(), but
1497 * marks that function as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT
1498 * queues).
1499 *
1500 * See "Dispatch Barrier API" for a description of the barrier semantics.
1501 *
1502 * @param queue
1503 * The target dispatch queue to which the function is submitted.
1504 * The result of passing NULL in this parameter is undefined.
1505 *
1506 * @param context
1507 * The application-defined context parameter to pass to the function.
1508 *
1509 * @param work
1510 * The application-defined function to invoke on the target queue. The first
1511 * parameter passed to this function is the context provided to
1512 * dispatch_barrier_async_and_wait_f().
1513 * The result of passing NULL in this parameter is undefined.
1514 */
1515API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
1516DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
1517DISPATCH_SWIFT_UNAVAILABLE("Unavailable in Swift")
1518void
1519dispatch_barrier_async_and_wait_f(dispatch_queue_t queue,
1520		void *_Nullable context, dispatch_function_t work);
1521
1522/*!
1523 * @functiongroup Dispatch queue-specific contexts
1524 * This API allows different subsystems to associate context to a shared queue
1525 * without risk of collision and to retrieve that context from blocks executing
1526 * on that queue or any of its child queues in the target queue hierarchy.
1527 */
1528
1529/*!
1530 * @function dispatch_queue_set_specific
1531 *
1532 * @abstract
1533 * Associates a subsystem-specific context with a dispatch queue, for a key
1534 * unique to the subsystem.
1535 *
1536 * @discussion
1537 * The specified destructor will be invoked with the context on the default
1538 * priority global concurrent queue when a new context is set for the same key,
1539 * or after all references to the queue have been released.
1540 *
1541 * @param queue
1542 * The dispatch queue to modify.
1543 * The result of passing NULL in this parameter is undefined.
1544 *
1545 * @param key
1546 * The key to set the context for, typically a pointer to a static variable
1547 * specific to the subsystem. Keys are only compared as pointers and never
1548 * dereferenced. Passing a string constant directly is not recommended.
1549 * The NULL key is reserved and attempts to set a context for it are ignored.
1550 *
1551 * @param context
1552 * The new subsystem-specific context for the object. This may be NULL.
1553 *
1554 * @param destructor
1555 * The destructor function pointer. This may be NULL and is ignored if context
1556 * is NULL.
1557 */
1558API_AVAILABLE(macos(10.7), ios(5.0))
1559DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
1560DISPATCH_REFINED_FOR_SWIFT
1561void
1562dispatch_queue_set_specific(dispatch_queue_t queue, const void *key,
1563		void *_Nullable context, dispatch_function_t _Nullable destructor);
1564
1565/*!
1566 * @function dispatch_queue_get_specific
1567 *
1568 * @abstract
1569 * Returns the subsystem-specific context associated with a dispatch queue, for
1570 * a key unique to the subsystem.
1571 *
1572 * @discussion
1573 * Returns the context for the specified key if it has been set on the specified
1574 * queue.
1575 *
1576 * @param queue
1577 * The dispatch queue to query.
1578 * The result of passing NULL in this parameter is undefined.
1579 *
1580 * @param key
1581 * The key to get the context for, typically a pointer to a static variable
1582 * specific to the subsystem. Keys are only compared as pointers and never
1583 * dereferenced. Passing a string constant directly is not recommended.
1584 *
1585 * @result
1586 * The context for the specified key or NULL if no context was found.
1587 */
1588API_AVAILABLE(macos(10.7), ios(5.0))
1589DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_PURE DISPATCH_WARN_RESULT
1590DISPATCH_NOTHROW
1591DISPATCH_REFINED_FOR_SWIFT
1592void *_Nullable
1593dispatch_queue_get_specific(dispatch_queue_t queue, const void *key);
1594
1595/*!
1596 * @function dispatch_get_specific
1597 *
1598 * @abstract
1599 * Returns the current subsystem-specific context for a key unique to the
1600 * subsystem.
1601 *
1602 * @discussion
1603 * When called from a block executing on a queue, returns the context for the
1604 * specified key if it has been set on the queue, otherwise returns the result
1605 * of dispatch_get_specific() executed on the queue's target queue or NULL
1606 * if the current queue is a global concurrent queue.
1607 *
1608 * @param key
1609 * The key to get the context for, typically a pointer to a static variable
1610 * specific to the subsystem. Keys are only compared as pointers and never
1611 * dereferenced. Passing a string constant directly is not recommended.
1612 *
1613 * @result
1614 * The context for the specified key or NULL if no context was found.
1615 */
1616API_AVAILABLE(macos(10.7), ios(5.0))
1617DISPATCH_EXPORT DISPATCH_PURE DISPATCH_WARN_RESULT DISPATCH_NOTHROW
1618DISPATCH_REFINED_FOR_SWIFT
1619void *_Nullable
1620dispatch_get_specific(const void *key);
1621
1622/*!
1623 * @functiongroup Dispatch assertion API
1624 *
1625 * This API asserts at runtime that code is executing in (or out of) the context
1626 * of a given queue. It can be used to check that a block accessing a resource
1627 * does so from the proper queue protecting the resource. It also can be used
1628 * to verify that a block that could cause a deadlock if run on a given queue
1629 * never executes on that queue.
1630 */
1631
1632/*!
1633 * @function dispatch_assert_queue
1634 *
1635 * @abstract
1636 * Verifies that the current block is executing on a given dispatch queue.
1637 *
1638 * @discussion
1639 * Some code expects to be run on a specific dispatch queue. This function
1640 * verifies that that expectation is true.
1641 *
1642 * If the currently executing block was submitted to the specified queue or to
1643 * any queue targeting it (see dispatch_set_target_queue()), this function
1644 * returns.
1645 *
1646 * If the currently executing block was submitted with a synchronous API
1647 * (dispatch_sync(), dispatch_barrier_sync(), ...), the context of the
1648 * submitting block is also evaluated (recursively).
1649 * If a synchronously submitting block is found that was itself submitted to
1650 * the specified queue or to any queue targeting it, this function returns.
1651 *
1652 * Otherwise this function asserts: it logs an explanation to the system log and
1653 * terminates the application.
1654 *
1655 * Passing the result of dispatch_get_main_queue() to this function verifies
1656 * that the current block was submitted to the main queue, or to a queue
1657 * targeting it, or is running on the main thread (in any context).
1658 *
1659 * When dispatch_assert_queue() is called outside of the context of a
1660 * submitted block (for example from the context of a thread created manually
1661 * with pthread_create()) then this function will also assert and terminate
1662 * the application.
1663 *
1664 * The variant dispatch_assert_queue_debug() is compiled out when the
1665 * preprocessor macro NDEBUG is defined. (See also assert(3)).
1666 *
1667 * @param queue
1668 * The dispatch queue that the current block is expected to run on.
1669 * The result of passing NULL in this parameter is undefined.
1670 */
1671API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
1672DISPATCH_EXPORT DISPATCH_NONNULL1
1673DISPATCH_REFINED_FOR_SWIFT
1674void
1675dispatch_assert_queue(dispatch_queue_t queue)
1676		DISPATCH_ALIAS_V2(dispatch_assert_queue);
1677
1678/*!
1679 * @function dispatch_assert_queue_barrier
1680 *
1681 * @abstract
1682 * Verifies that the current block is executing on a given dispatch queue,
1683 * and that the block acts as a barrier on that queue.
1684 *
1685 * @discussion
1686 * This behaves exactly like dispatch_assert_queue(), with the additional check
1687 * that the current block acts as a barrier on the specified queue, which is
1688 * always true if the specified queue is serial (see DISPATCH_BLOCK_BARRIER or
1689 * dispatch_barrier_async() for details).
1690 *
1691 * The variant dispatch_assert_queue_barrier_debug() is compiled out when the
1692 * preprocessor macro NDEBUG is defined. (See also assert()).
1693 *
1694 * @param queue
1695 * The dispatch queue that the current block is expected to run as a barrier on.
1696 * The result of passing NULL in this parameter is undefined.
1697 */
1698API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
1699DISPATCH_EXPORT DISPATCH_NONNULL1
1700DISPATCH_REFINED_FOR_SWIFT
1701void
1702dispatch_assert_queue_barrier(dispatch_queue_t queue);
1703
1704/*!
1705 * @function dispatch_assert_queue_not
1706 *
1707 * @abstract
1708 * Verifies that the current block is not executing on a given dispatch queue.
1709 *
1710 * @discussion
1711 * This function is the equivalent of dispatch_assert_queue() with the test for
1712 * equality inverted. That means that it will terminate the application when
1713 * dispatch_assert_queue() would return, and vice-versa. See discussion there.
1714 *
1715 * The variant dispatch_assert_queue_not_debug() is compiled out when the
1716 * preprocessor macro NDEBUG is defined. (See also assert(3)).
1717 *
1718 * @param queue
1719 * The dispatch queue that the current block is expected not to run on.
1720 * The result of passing NULL in this parameter is undefined.
1721 */
1722API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
1723DISPATCH_EXPORT DISPATCH_NONNULL1
1724DISPATCH_REFINED_FOR_SWIFT
1725void
1726dispatch_assert_queue_not(dispatch_queue_t queue)
1727		DISPATCH_ALIAS_V2(dispatch_assert_queue_not);
1728
1729#ifdef NDEBUG
1730#define dispatch_assert_queue_debug(q) ((void)(0 && (q)))
1731#define dispatch_assert_queue_barrier_debug(q) ((void)(0 && (q)))
1732#define dispatch_assert_queue_not_debug(q) ((void)(0 && (q)))
1733#else
1734#define dispatch_assert_queue_debug(q) dispatch_assert_queue(q)
1735#define dispatch_assert_queue_barrier_debug(q) dispatch_assert_queue_barrier(q)
1736#define dispatch_assert_queue_not_debug(q) dispatch_assert_queue_not(q)
1737#endif
1738
1739/* @function dispatch_allow_send_signals
1740 *
1741 * @discussion
1742 * This function provides the calling process an ability to send signals to
1743 * it's pthread worker threads created to service incoming work to dispatch,
1744 * including those which were already created prior to this function call
1745 * and those who may be created in the future. After a call to this function
1746 * returns successfully, this ability is retained for the lifetime of the
1747 * calling process.
1748 * Regular UNIX calls still need to be used to manipulate signal mask of
1749 * each individual pthread worker thread to allow delivery of a specific
1750 * signal to that thread.
1751 *
1752 * @param preserve_signum
1753 * Dispatch and its kernel runtime subsystem manages a pool of pthread
1754 * worker threads which are reused for handling incoming work to dispatch.
1755 * The signal number specified here is used internally by this subsystem to
1756 * preserve sigmask of the pthread worker threads across their reuse.
1757 *
1758 * In other words, if a pthread worker thread unblocks delivery of
1759 * @preserve_signum using regular UNIX calls after a call to this
1760 * function using the same @preserve_signum returns successfully,
1761 * that @preserve_signum remains unblocked across that thread's
1762 * reuse until it is further modified by regular UNIX calls.
1763 * Therefore, it avoids the need to call regular UNIX calls to
1764 * unblock delivery of @preserve_signum every time that thread
1765 * is reused. The specific signal @preserve_signum can be sent
1766 * to that specific pthread worker thread using pthread_kill().
1767 *
1768 * The following code illustrates an expected usage of this API.
1769 *
1770 * <code>
1771 *
1772 * // Enable sending signals to dispatch pthread worker threads.
1773 * int ret = dispatch_allow_send_signals(sig);
1774 * // Validate ret.
1775 *
1776 * dispatch_async(q, ^{
1777 *     // Unblock sig for this worker thread if not already done.
1778 *     // Such a state could be saved in TSD or globally.
1779 *     mask = sigmask(sig);
1780 *     pthread_sigmask(SIG_UNBLOCK, &mask, NULL);
1781 *     // busy with some work. Can receive signal sig.
1782 *     // If this worker thread is re-used later, it does not
1783 *     // not need to call pthread_sigmask again to unblock delivery
1784 *     // of signal sig.
1785 * }
1786 *
1787 * This function returns 0 upon success and -1 with an errno otherwise.
1788 * Possible error codes are as below :
1789 *
1790 * EINVAL     : @preserve_signum is prohibited and is not allowed to be preserved
1791 *              across the thread's reuse.
1792 * ENOTSUP    : The underlying kernel does not support this functionality.
1793 *
1794 * </code>
1795 */
1796API_AVAILABLE(macos(14.4), ios(17.4), visionos(1.1))
1797API_UNAVAILABLE(tvos, watchos, driverkit)
1798DISPATCH_EXPORT
1799int
1800dispatch_allow_send_signals(int preserve_signum);
1801
1802__END_DECLS
1803
1804DISPATCH_ASSUME_ABI_SINGLE_END
1805DISPATCH_ASSUME_NONNULL_END
1806
1807#endif