queue.h (68139B) - Raw
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 DISPATCH_ASSUME_NONNULL_BEGIN 30 DISPATCH_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 */ 70 DISPATCH_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 */ 102 DISPATCH_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 */ 121 API_AVAILABLE(macos(14.0), ios(17.0), tvos(17.0), watchos(10.0)) 122 DISPATCH_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 */ 148 API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) 149 DISPATCH_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 */ 171 DISPATCH_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 */ 201 API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) 202 DISPATCH_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__ 235 API_AVAILABLE(macos(10.6), ios(4.0)) 236 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 237 DISPATCH_REFINED_FOR_SWIFT 238 void 239 dispatch_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 */ 266 API_AVAILABLE(macos(10.6), ios(4.0)) 267 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW 268 DISPATCH_SWIFT_UNAVAILABLE("Use DispatchQueue.async(self:execute:)") 269 void 270 dispatch_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__ 310 API_AVAILABLE(macos(10.6), ios(4.0)) 311 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 312 DISPATCH_SWIFT_NAME(DispatchQueue.sync(self:execute:)) 313 void 314 dispatch_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 */ 339 API_AVAILABLE(macos(10.6), ios(4.0)) 340 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW 341 DISPATCH_SWIFT_UNAVAILABLE("Use DispatchQueue.sync(self:execute:)") 342 void 343 dispatch_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__ 407 API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) 408 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 409 DISPATCH_SWIFT_NAME(DispatchQueue.asyncAndWait(self:execute:)) 410 void 411 dispatch_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 */ 437 API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) 438 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW 439 DISPATCH_SWIFT_UNAVAILABLE("Use DispatchQueue.asyncAndWait(self:execute:)") 440 void 441 dispatch_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__ 510 API_AVAILABLE(macos(10.6), ios(4.0)) 511 DISPATCH_EXPORT DISPATCH_NONNULL3 DISPATCH_NOTHROW 512 DISPATCH_REFINED_FOR_SWIFT 513 void 514 dispatch_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 */ 546 API_AVAILABLE(macos(10.6), ios(4.0)) 547 DISPATCH_EXPORT DISPATCH_NONNULL4 DISPATCH_NOTHROW 548 DISPATCH_SWIFT_UNAVAILABLE("Use DispatchQueue.concurrentPerform(iterations:execute:).") 549 void 550 dispatch_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 */ 583 API_DEPRECATED("unsupported interface", macos(10.6,10.9), ios(4.0,6.0)) 584 DISPATCH_EXPORT DISPATCH_PURE DISPATCH_WARN_RESULT DISPATCH_NOTHROW 585 dispatch_queue_t 586 dispatch_get_current_queue(void); 587 588 API_AVAILABLE(macos(10.6), ios(4.0)) 589 DISPATCH_EXPORT 590 struct 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 */ 616 DISPATCH_INLINE DISPATCH_ALWAYS_INLINE DISPATCH_CONST DISPATCH_NOTHROW 617 DISPATCH_SWIFT_UNAVAILABLE("Use getter:DispatchQueue.main()") 618 dispatch_queue_main_t 619 dispatch_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 657 DISPATCH_SWIFT_UNAVAILABLE("Use DispatchQueue.GlobalQueuePriority") 658 typedef 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 */ 697 API_AVAILABLE(macos(10.6), ios(4.0)) 698 DISPATCH_EXPORT DISPATCH_CONST DISPATCH_WARN_RESULT DISPATCH_NOTHROW 699 DISPATCH_REFINED_FOR_SWIFT 700 dispatch_queue_global_t 701 dispatch_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 */ 709 DISPATCH_REFINED_FOR_SWIFT 710 DISPATCH_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) 748 API_AVAILABLE(macos(10.7), ios(4.3)) 749 DISPATCH_EXPORT 750 struct 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 */ 794 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) 795 DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_PURE DISPATCH_NOTHROW 796 DISPATCH_REFINED_FOR_SWIFT 797 dispatch_queue_attr_t 798 dispatch_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 */ 851 DISPATCH_REFINED_FOR_SWIFT 852 DISPATCH_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 */ 901 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) 902 DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_PURE DISPATCH_NOTHROW 903 DISPATCH_REFINED_FOR_SWIFT 904 dispatch_queue_attr_t 905 dispatch_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 */ 966 API_AVAILABLE(macos(10.10), ios(8.0)) 967 DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_PURE DISPATCH_NOTHROW 968 DISPATCH_REFINED_FOR_SWIFT 969 dispatch_queue_attr_t 970 dispatch_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 */ 1032 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) 1033 DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT 1034 DISPATCH_NOTHROW 1035 DISPATCH_REFINED_FOR_SWIFT DISPATCH_SWIFT_NAME(DispatchQueue.init(__label:attr:queue:)) 1036 dispatch_queue_t 1037 dispatch_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 */ 1086 API_AVAILABLE(macos(10.6), ios(4.0)) 1087 DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT 1088 DISPATCH_NOTHROW 1089 DISPATCH_REFINED_FOR_SWIFT DISPATCH_SWIFT_NAME(DispatchQueue.init(__label:attr:)) 1090 dispatch_queue_t 1091 dispatch_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 */ 1117 API_AVAILABLE(macos(10.6), ios(4.0)) 1118 DISPATCH_EXPORT DISPATCH_PURE DISPATCH_WARN_RESULT DISPATCH_NOTHROW 1119 DISPATCH_REFINED_FOR_SWIFT 1120 const char * 1121 dispatch_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 */ 1157 API_AVAILABLE(macos(10.10), ios(8.0)) 1158 DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_NONNULL1 DISPATCH_NOTHROW 1159 DISPATCH_REFINED_FOR_SWIFT 1160 dispatch_qos_class_t 1161 dispatch_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 */ 1225 API_AVAILABLE(macos(10.6), ios(4.0)) 1226 DISPATCH_EXPORT DISPATCH_NOTHROW 1227 DISPATCH_SWIFT_NAME(DispatchObject.setTarget(self:queue:)) 1228 void 1229 dispatch_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 */ 1245 API_AVAILABLE(macos(10.6), ios(4.0)) 1246 DISPATCH_EXPORT DISPATCH_NOTHROW DISPATCH_NORETURN 1247 DISPATCH_SWIFT_NAME(dispatchMain()) 1248 void 1249 dispatch_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__ 1274 API_AVAILABLE(macos(10.6), ios(4.0)) 1275 DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NONNULL3 DISPATCH_NOTHROW 1276 DISPATCH_REFINED_FOR_SWIFT 1277 void 1278 dispatch_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 */ 1307 API_AVAILABLE(macos(10.6), ios(4.0)) 1308 DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NONNULL4 DISPATCH_NOTHROW 1309 DISPATCH_SWIFT_UNAVAILABLE("Use DispatchQueue.asyncAfter(self:deadline:qos:flags:execute:)") 1310 void 1311 dispatch_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__ 1354 API_AVAILABLE(macos(10.7), ios(4.3)) 1355 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 1356 DISPATCH_REFINED_FOR_SWIFT 1357 void 1358 dispatch_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 */ 1390 API_AVAILABLE(macos(10.7), ios(4.3)) 1391 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW 1392 DISPATCH_SWIFT_UNAVAILABLE("Use DispatchQueue.async(self:group:qos:flags:execute:)") 1393 void 1394 dispatch_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__ 1419 API_AVAILABLE(macos(10.7), ios(4.3)) 1420 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 1421 DISPATCH_REFINED_FOR_SWIFT 1422 void 1423 dispatch_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 */ 1452 API_AVAILABLE(macos(10.7), ios(4.3)) 1453 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW 1454 DISPATCH_SWIFT_UNAVAILABLE("Use DispatchQueue.sync(self:flags:execute:)") 1455 void 1456 dispatch_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__ 1481 API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) 1482 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 1483 DISPATCH_SWIFT_UNAVAILABLE("Unavailable in Swift") 1484 void 1485 dispatch_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 */ 1515 API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) 1516 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW 1517 DISPATCH_SWIFT_UNAVAILABLE("Unavailable in Swift") 1518 void 1519 dispatch_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 */ 1558 API_AVAILABLE(macos(10.7), ios(5.0)) 1559 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW 1560 DISPATCH_REFINED_FOR_SWIFT 1561 void 1562 dispatch_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 */ 1588 API_AVAILABLE(macos(10.7), ios(5.0)) 1589 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_PURE DISPATCH_WARN_RESULT 1590 DISPATCH_NOTHROW 1591 DISPATCH_REFINED_FOR_SWIFT 1592 void *_Nullable 1593 dispatch_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 */ 1616 API_AVAILABLE(macos(10.7), ios(5.0)) 1617 DISPATCH_EXPORT DISPATCH_PURE DISPATCH_WARN_RESULT DISPATCH_NOTHROW 1618 DISPATCH_REFINED_FOR_SWIFT 1619 void *_Nullable 1620 dispatch_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 */ 1671 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) 1672 DISPATCH_EXPORT DISPATCH_NONNULL1 1673 DISPATCH_REFINED_FOR_SWIFT 1674 void 1675 dispatch_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 */ 1698 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) 1699 DISPATCH_EXPORT DISPATCH_NONNULL1 1700 DISPATCH_REFINED_FOR_SWIFT 1701 void 1702 dispatch_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 */ 1722 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) 1723 DISPATCH_EXPORT DISPATCH_NONNULL1 1724 DISPATCH_REFINED_FOR_SWIFT 1725 void 1726 dispatch_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 */ 1796 API_AVAILABLE(macos(14.4), ios(17.4), visionos(1.1)) 1797 API_UNAVAILABLE(tvos, watchos, driverkit) 1798 DISPATCH_EXPORT 1799 int 1800 dispatch_allow_send_signals(int preserve_signum); 1801 1802 __END_DECLS 1803 1804 DISPATCH_ASSUME_ABI_SINGLE_END 1805 DISPATCH_ASSUME_NONNULL_END 1806 1807 #endif