1/* 2 * Copyright (c) 2008-2012 Apple Inc. All rights reserved. 3 * 4 * @APPLE_APACHE_LICENSE_HEADER_START@ 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 * 18 * @APPLE_APACHE_LICENSE_HEADER_END@ 19 */ 20 21#ifndef __DISPATCH_QUEUE__ 22#define __DISPATCH_QUEUE__ 23 24#ifndef __DISPATCH_INDIRECT__ 25#error "Please #include <dispatch/dispatch.h> instead of this file directly." 26#include <dispatch/base.h> // for HeaderDoc 27#endif 28 29/*! 30 * @header 31 * 32 * Dispatch is an abstract model for expressing concurrency via simple but 33 * powerful API. 34 * 35 * At the core, dispatch provides serial FIFO queues to which blocks may be 36 * submitted. Blocks submitted to these dispatch queues are invoked on a pool 37 * of threads fully managed by the system. No guarantee is made regarding 38 * which thread a block will be invoked on; however, it is guaranteed that only 39 * one block submitted to the FIFO dispatch queue will be invoked at a time. 40 * 41 * When multiple queues have blocks to be processed, the system is free to 42 * allocate additional threads to invoke the blocks concurrently. When the 43 * queues become empty, these threads are automatically released. 44 */ 45 46/*! 47 * @typedef dispatch_queue_t 48 * 49 * @abstract 50 * Dispatch queues invoke blocks submitted to them serially in FIFO order. A 51 * queue will only invoke one block at a time, but independent queues may each 52 * invoke their blocks concurrently with respect to each other. 53 * 54 * @discussion 55 * Dispatch queues are lightweight objects to which blocks may be submitted. 56 * The system manages a pool of threads which process dispatch queues and 57 * invoke blocks submitted to them. 58 * 59 * Conceptually a dispatch queue may have its own thread of execution, and 60 * interaction between queues is highly asynchronous. 61 * 62 * Dispatch queues are reference counted via calls to dispatch_retain() and 63 * dispatch_release(). Pending blocks submitted to a queue also hold a 64 * reference to the queue until they have finished. Once all references to a 65 * queue have been released, the queue will be deallocated by the system. 66 */ 67DISPATCH_DECL(dispatch_queue); 68 69/*! 70 * @typedef dispatch_queue_attr_t 71 * 72 * @abstract 73 * Attribute for dispatch queues. 74 */ 75DISPATCH_DECL(dispatch_queue_attr); 76 77/*! 78 * @typedef dispatch_block_t 79 * 80 * @abstract 81 * The prototype of blocks submitted to dispatch queues, which take no 82 * arguments and have no return value. 83 * 84 * @discussion 85 * The declaration of a block allocates storage on the stack. Therefore, this 86 * is an invalid construct: 87 * 88 * dispatch_block_t block; 89 * 90 * if (x) { 91 * block = ^{ printf("true\n"); }; 92 * } else { 93 * block = ^{ printf("false\n"); }; 94 * } 95 * block(); // unsafe!!! 96 * 97 * What is happening behind the scenes: 98 * 99 * if (x) { 100 * struct Block __tmp_1 = ...; // setup details 101 * block = &__tmp_1; 102 * } else { 103 * struct Block __tmp_2 = ...; // setup details 104 * block = &__tmp_2; 105 * } 106 * 107 * As the example demonstrates, the address of a stack variable is escaping the 108 * scope in which it is allocated. That is a classic C bug. 109 */ 110#ifdef __BLOCKS__ 111typedef void (^dispatch_block_t)(void); 112#endif 113 114__BEGIN_DECLS 115 116/*! 117 * @function dispatch_async 118 * 119 * @abstract 120 * Submits a block for asynchronous execution on a dispatch queue. 121 * 122 * @discussion 123 * The dispatch_async() function is the fundamental mechanism for submitting 124 * blocks to a dispatch queue. 125 * 126 * Calls to dispatch_async() always return immediately after the block has 127 * been submitted, and never wait for the block to be invoked. 128 * 129 * The target queue determines whether the block will be invoked serially or 130 * concurrently with respect to other blocks submitted to that same queue. 131 * Serial queues are processed concurrently with respect to each other. 132 * 133 * @param queue 134 * The target dispatch queue to which the block is submitted. 135 * The system will hold a reference on the target queue until the block 136 * has finished. 137 * The result of passing NULL in this parameter is undefined. 138 * 139 * @param block 140 * The block to submit to the target dispatch queue. This function performs 141 * Block_copy() and Block_release() on behalf of callers. 142 * The result of passing NULL in this parameter is undefined. 143 */ 144#ifdef __BLOCKS__ 145__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 146DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 147void 148dispatch_async(dispatch_queue_t queue, dispatch_block_t block); 149#endif 150 151/*! 152 * @function dispatch_async_f 153 * 154 * @abstract 155 * Submits a function for asynchronous execution on a dispatch queue. 156 * 157 * @discussion 158 * See dispatch_async() for details. 159 * 160 * @param queue 161 * The target dispatch queue to which the function is submitted. 162 * The system will hold a reference on the target queue until the function 163 * has returned. 164 * The result of passing NULL in this parameter is undefined. 165 * 166 * @param context 167 * The application-defined context parameter to pass to the function. 168 * 169 * @param work 170 * The application-defined function to invoke on the target queue. The first 171 * parameter passed to this function is the context provided to 172 * dispatch_async_f(). 173 * The result of passing NULL in this parameter is undefined. 174 */ 175__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 176DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW 177void 178dispatch_async_f(dispatch_queue_t queue, 179 void *context, 180 dispatch_function_t work); 181 182/*! 183 * @function dispatch_sync 184 * 185 * @abstract 186 * Submits a block for synchronous execution on a dispatch queue. 187 * 188 * @discussion 189 * Submits a block to a dispatch queue like dispatch_async(), however 190 * dispatch_sync() will not return until the block has finished. 191 * 192 * Calls to dispatch_sync() targeting the current queue will result 193 * in dead-lock. Use of dispatch_sync() is also subject to the same 194 * multi-party dead-lock problems that may result from the use of a mutex. 195 * Use of dispatch_async() is preferred. 196 * 197 * Unlike dispatch_async(), no retain is performed on the target queue. Because 198 * calls to this function are synchronous, the dispatch_sync() "borrows" the 199 * reference of the caller. 200 * 201 * As an optimization, dispatch_sync() invokes the block on the current 202 * thread when possible. 203 * 204 * @param queue 205 * The target dispatch queue to which the block is submitted. 206 * The result of passing NULL in this parameter is undefined. 207 * 208 * @param block 209 * The block to be invoked on the target dispatch queue. 210 * The result of passing NULL in this parameter is undefined. 211 */ 212#ifdef __BLOCKS__ 213__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 214DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 215void 216dispatch_sync(dispatch_queue_t queue, dispatch_block_t block); 217#endif 218 219/*! 220 * @function dispatch_sync_f 221 * 222 * @abstract 223 * Submits a function for synchronous execution on a dispatch queue. 224 * 225 * @discussion 226 * See dispatch_sync() for details. 227 * 228 * @param queue 229 * The target dispatch queue to which the function is submitted. 230 * The result of passing NULL in this parameter is undefined. 231 * 232 * @param context 233 * The application-defined context parameter to pass to the function. 234 * 235 * @param work 236 * The application-defined function to invoke on the target queue. The first 237 * parameter passed to this function is the context provided to 238 * dispatch_sync_f(). 239 * The result of passing NULL in this parameter is undefined. 240 */ 241__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 242DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW 243void 244dispatch_sync_f(dispatch_queue_t queue, 245 void *context, 246 dispatch_function_t work); 247 248/*! 249 * @function dispatch_apply 250 * 251 * @abstract 252 * Submits a block to a dispatch queue for multiple invocations. 253 * 254 * @discussion 255 * Submits a block to a dispatch queue for multiple invocations. This function 256 * waits for the task block to complete before returning. If the target queue 257 * is concurrent, the block may be invoked concurrently, and it must therefore 258 * be reentrant safe. 259 * 260 * Each invocation of the block will be passed the current index of iteration. 261 * 262 * @param iterations 263 * The number of iterations to perform. 264 * 265 * @param queue 266 * The target dispatch queue to which the block is submitted. 267 * The result of passing NULL in this parameter is undefined. 268 * 269 * @param block 270 * The block to be invoked the specified number of iterations. 271 * The result of passing NULL in this parameter is undefined. 272 */ 273#ifdef __BLOCKS__ 274__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 275DISPATCH_EXPORT DISPATCH_NONNULL3 DISPATCH_NOTHROW 276void 277dispatch_apply(size_t iterations, dispatch_queue_t queue, 278 void (^block)(size_t)); 279#endif 280 281/*! 282 * @function dispatch_apply_f 283 * 284 * @abstract 285 * Submits a function to a dispatch queue for multiple invocations. 286 * 287 * @discussion 288 * See dispatch_apply() for details. 289 * 290 * @param iterations 291 * The number of iterations to perform. 292 * 293 * @param queue 294 * The target dispatch queue to which the function is submitted. 295 * The result of passing NULL in this parameter is undefined. 296 * 297 * @param context 298 * The application-defined context parameter to pass to the function. 299 * 300 * @param work 301 * The application-defined function to invoke on the target queue. The first 302 * parameter passed to this function is the context provided to 303 * dispatch_apply_f(). The second parameter passed to this function is the 304 * current index of iteration. 305 * The result of passing NULL in this parameter is undefined. 306 */ 307__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 308DISPATCH_EXPORT DISPATCH_NONNULL4 DISPATCH_NOTHROW 309void 310dispatch_apply_f(size_t iterations, dispatch_queue_t queue, 311 void *context, 312 void (*work)(void *, size_t)); 313 314/*! 315 * @function dispatch_get_current_queue 316 * 317 * @abstract 318 * Returns the queue on which the currently executing block is running. 319 * 320 * @discussion 321 * Returns the queue on which the currently executing block is running. 322 * 323 * When dispatch_get_current_queue() is called outside of the context of a 324 * submitted block, it will return the default concurrent queue. 325 * 326 * Recommended for debugging and logging purposes only: 327 * The code must not make any assumptions about the queue returned, unless it 328 * is one of the global queues or a queue the code has itself created. 329 * The code must not assume that synchronous execution onto a queue is safe 330 * from deadlock if that queue is not the one returned by 331 * dispatch_get_current_queue(). 332 * 333 * When dispatch_get_current_queue() is called on the main thread, it may 334 * or may not return the same value as dispatch_get_main_queue(). Comparing 335 * the two is not a valid way to test whether code is executing on the 336 * main thread. 337 * 338 * This function is deprecated and will be removed in a future release. 339 * 340 * @result 341 * Returns the current queue. 342 */ 343__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6,__MAC_10_9,__IPHONE_4_0,__IPHONE_6_0) 344DISPATCH_EXPORT DISPATCH_PURE DISPATCH_WARN_RESULT DISPATCH_NOTHROW 345dispatch_queue_t 346dispatch_get_current_queue(void); 347 348/*! 349 * @function dispatch_get_main_queue 350 * 351 * @abstract 352 * Returns the default queue that is bound to the main thread. 353 * 354 * @discussion 355 * In order to invoke blocks submitted to the main queue, the application must 356 * call dispatch_main(), NSApplicationMain(), or use a CFRunLoop on the main 357 * thread. 358 * 359 * @result 360 * Returns the main queue. This queue is created automatically on behalf of 361 * the main thread before main() is called. 362 */ 363__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 364DISPATCH_EXPORT struct dispatch_queue_s _dispatch_main_q; 365#define dispatch_get_main_queue() \ 366 DISPATCH_GLOBAL_OBJECT(dispatch_queue_t, _dispatch_main_q) 367 368/*! 369 * @typedef dispatch_queue_priority_t 370 * Type of dispatch_queue_priority 371 * 372 * @constant DISPATCH_QUEUE_PRIORITY_HIGH 373 * Items dispatched to the queue will run at high priority, 374 * i.e. the queue will be scheduled for execution before 375 * any default priority or low priority queue. 376 * 377 * @constant DISPATCH_QUEUE_PRIORITY_DEFAULT 378 * Items dispatched to the queue will run at the default 379 * priority, i.e. the queue will be scheduled for execution 380 * after all high priority queues have been scheduled, but 381 * before any low priority queues have been scheduled. 382 * 383 * @constant DISPATCH_QUEUE_PRIORITY_LOW 384 * Items dispatched to the queue will run at low priority, 385 * i.e. the queue will be scheduled for execution after all 386 * default priority and high priority queues have been 387 * scheduled. 388 * 389 * @constant DISPATCH_QUEUE_PRIORITY_BACKGROUND 390 * Items dispatched to the queue will run at background priority, i.e. the queue 391 * will be scheduled for execution after all higher priority queues have been 392 * scheduled and the system will run items on this queue on a thread with 393 * background status as per setpriority(2) (i.e. disk I/O is throttled and the 394 * thread's scheduling priority is set to lowest value). 395 */ 396#define DISPATCH_QUEUE_PRIORITY_HIGH 2 397#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 398#define DISPATCH_QUEUE_PRIORITY_LOW (-2) 399#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN 400 401typedef long dispatch_queue_priority_t; 402 403/*! 404 * @function dispatch_get_global_queue 405 * 406 * @abstract 407 * Returns a well-known global concurrent queue of a given priority level. 408 * 409 * @discussion 410 * The well-known global concurrent queues may not be modified. Calls to 411 * dispatch_suspend(), dispatch_resume(), dispatch_set_context(), etc., will 412 * have no effect when used with queues returned by this function. 413 * 414 * @param priority 415 * A priority defined in dispatch_queue_priority_t 416 * 417 * @param flags 418 * Reserved for future use. Passing any value other than zero may result in 419 * a NULL return value. 420 * 421 * @result 422 * Returns the requested global queue. 423 */ 424__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 425DISPATCH_EXPORT DISPATCH_CONST DISPATCH_WARN_RESULT DISPATCH_NOTHROW 426dispatch_queue_t 427dispatch_get_global_queue(dispatch_queue_priority_t priority, 428 unsigned long flags); 429 430/*! 431 * @const DISPATCH_QUEUE_SERIAL 432 * @discussion A dispatch queue that invokes blocks serially in FIFO order. 433 */ 434#define DISPATCH_QUEUE_SERIAL NULL 435 436/*! 437 * @const DISPATCH_QUEUE_CONCURRENT 438 * @discussion A dispatch queue that may invoke blocks concurrently and supports 439 * barrier blocks submitted with the dispatch barrier API. 440 */ 441#define DISPATCH_QUEUE_CONCURRENT \ 442 DISPATCH_GLOBAL_OBJECT(dispatch_queue_attr_t, \ 443 _dispatch_queue_attr_concurrent) 444__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_3) 445DISPATCH_EXPORT 446struct dispatch_queue_attr_s _dispatch_queue_attr_concurrent; 447 448/*! 449 * @function dispatch_queue_create 450 * 451 * @abstract 452 * Creates a new dispatch queue to which blocks may be submitted. 453 * 454 * @discussion 455 * Dispatch queues created with the DISPATCH_QUEUE_SERIAL or a NULL attribute 456 * invoke blocks serially in FIFO order. 457 * 458 * Dispatch queues created with the DISPATCH_QUEUE_CONCURRENT attribute may 459 * invoke blocks concurrently (similarly to the global concurrent queues, but 460 * potentially with more overhead), and support barrier blocks submitted with 461 * the dispatch barrier API, which e.g. enables the implementation of efficient 462 * reader-writer schemes. 463 * 464 * When a dispatch queue is no longer needed, it should be released with 465 * dispatch_release(). Note that any pending blocks submitted to a queue will 466 * hold a reference to that queue. Therefore a queue will not be deallocated 467 * until all pending blocks have finished. 468 * 469 * The target queue of a newly created dispatch queue is the default priority 470 * global concurrent queue. 471 * 472 * @param label 473 * A string label to attach to the queue. 474 * This parameter is optional and may be NULL. 475 * 476 * @param attr 477 * DISPATCH_QUEUE_SERIAL or DISPATCH_QUEUE_CONCURRENT. 478 * 479 * @result 480 * The newly created dispatch queue. 481 */ 482__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 483DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT 484DISPATCH_NOTHROW 485dispatch_queue_t 486dispatch_queue_create(const char *label, dispatch_queue_attr_t attr); 487 488/*! 489 * @const DISPATCH_CURRENT_QUEUE_LABEL 490 * @discussion Constant to pass to the dispatch_queue_get_label() function to 491 * retrieve the label of the current queue. 492 */ 493#define DISPATCH_CURRENT_QUEUE_LABEL NULL 494 495/*! 496 * @function dispatch_queue_get_label 497 * 498 * @abstract 499 * Returns the label of the given queue, as specified when the queue was 500 * created, or the empty string if a NULL label was specified. 501 * 502 * Passing DISPATCH_CURRENT_QUEUE_LABEL will return the label of the current 503 * queue. 504 * 505 * @param queue 506 * The queue to query, or DISPATCH_CURRENT_QUEUE_LABEL. 507 * 508 * @result 509 * The label of the queue. 510 */ 511__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 512DISPATCH_EXPORT DISPATCH_PURE DISPATCH_WARN_RESULT DISPATCH_NOTHROW 513const char * 514dispatch_queue_get_label(dispatch_queue_t queue); 515 516/*! 517 * @const DISPATCH_TARGET_QUEUE_DEFAULT 518 * @discussion Constant to pass to the dispatch_set_target_queue() and 519 * dispatch_source_create() functions to indicate that the default target queue 520 * for the given object type should be used. 521 */ 522#define DISPATCH_TARGET_QUEUE_DEFAULT NULL 523 524/*! 525 * @function dispatch_set_target_queue 526 * 527 * @abstract 528 * Sets the target queue for the given object. 529 * 530 * @discussion 531 * An object's target queue is responsible for processing the object. 532 * 533 * A dispatch queue's priority is inherited from its target queue. Use the 534 * dispatch_get_global_queue() function to obtain suitable target queue 535 * of the desired priority. 536 * 537 * Blocks submitted to a serial queue whose target queue is another serial 538 * queue will not be invoked concurrently with blocks submitted to the target 539 * queue or to any other queue with that same target queue. 540 * 541 * The result of introducing a cycle into the hierarchy of target queues is 542 * undefined. 543 * 544 * A dispatch source's target queue specifies where its event handler and 545 * cancellation handler blocks will be submitted. 546 * 547 * A dispatch I/O channel's target queue specifies where where its I/O 548 * operations are executed. If the channel's target queue's priority is set to 549 * DISPATCH_QUEUE_PRIORITY_BACKGROUND, then the I/O operations performed by 550 * dispatch_io_read() or dispatch_io_write() on that queue will be 551 * throttled when there is I/O contention. 552 * 553 * For all other dispatch object types, the only function of the target queue 554 * is to determine where an object's finalizer function is invoked. 555 * 556 * @param object 557 * The object to modify. 558 * The result of passing NULL in this parameter is undefined. 559 * 560 * @param queue 561 * The new target queue for the object. The queue is retained, and the 562 * previous target queue, if any, is released. 563 * If queue is DISPATCH_TARGET_QUEUE_DEFAULT, set the object's target queue 564 * to the default target queue for the given object type. 565 */ 566__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 567DISPATCH_EXPORT DISPATCH_NOTHROW // DISPATCH_NONNULL1 568void 569dispatch_set_target_queue(dispatch_object_t object, dispatch_queue_t queue); 570 571/*! 572 * @function dispatch_main 573 * 574 * @abstract 575 * Execute blocks submitted to the main queue. 576 * 577 * @discussion 578 * This function "parks" the main thread and waits for blocks to be submitted 579 * to the main queue. This function never returns. 580 * 581 * Applications that call NSApplicationMain() or CFRunLoopRun() on the 582 * main thread do not need to call dispatch_main(). 583 */ 584__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 585DISPATCH_EXPORT DISPATCH_NOTHROW DISPATCH_NORETURN 586void 587dispatch_main(void); 588 589/*! 590 * @function dispatch_after 591 * 592 * @abstract 593 * Schedule a block for execution on a given queue at a specified time. 594 * 595 * @discussion 596 * Passing DISPATCH_TIME_NOW as the "when" parameter is supported, but not as 597 * optimal as calling dispatch_async() instead. Passing DISPATCH_TIME_FOREVER 598 * is undefined. 599 * 600 * @param when 601 * A temporal milestone returned by dispatch_time() or dispatch_walltime(). 602 * 603 * @param queue 604 * A queue to which the given block will be submitted at the specified time. 605 * The result of passing NULL in this parameter is undefined. 606 * 607 * @param block 608 * The block of code to execute. 609 * The result of passing NULL in this parameter is undefined. 610 */ 611#ifdef __BLOCKS__ 612__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 613DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NONNULL3 DISPATCH_NOTHROW 614void 615dispatch_after(dispatch_time_t when, 616 dispatch_queue_t queue, 617 dispatch_block_t block); 618#endif 619 620/*! 621 * @function dispatch_after_f 622 * 623 * @abstract 624 * Schedule a function for execution on a given queue at a specified time. 625 * 626 * @discussion 627 * See dispatch_after() for details. 628 * 629 * @param when 630 * A temporal milestone returned by dispatch_time() or dispatch_walltime(). 631 * 632 * @param queue 633 * A queue to which the given function will be submitted at the specified time. 634 * The result of passing NULL in this parameter is undefined. 635 * 636 * @param context 637 * The application-defined context parameter to pass to the function. 638 * 639 * @param work 640 * The application-defined function to invoke on the target queue. The first 641 * parameter passed to this function is the context provided to 642 * dispatch_after_f(). 643 * The result of passing NULL in this parameter is undefined. 644 */ 645__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 646DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NONNULL4 DISPATCH_NOTHROW 647void 648dispatch_after_f(dispatch_time_t when, 649 dispatch_queue_t queue, 650 void *context, 651 dispatch_function_t work); 652 653/*! 654 * @functiongroup Dispatch Barrier API 655 * The dispatch barrier API is a mechanism for submitting barrier blocks to a 656 * dispatch queue, analogous to the dispatch_async()/dispatch_sync() API. 657 * It enables the implementation of efficient reader/writer schemes. 658 * Barrier blocks only behave specially when submitted to queues created with 659 * the DISPATCH_QUEUE_CONCURRENT attribute; on such a queue, a barrier block 660 * will not run until all blocks submitted to the queue earlier have completed, 661 * and any blocks submitted to the queue after a barrier block will not run 662 * until the barrier block has completed. 663 * When submitted to a a global queue or to a queue not created with the 664 * DISPATCH_QUEUE_CONCURRENT attribute, barrier blocks behave identically to 665 * blocks submitted with the dispatch_async()/dispatch_sync() API. 666 */ 667 668/*! 669 * @function dispatch_barrier_async 670 * 671 * @abstract 672 * Submits a barrier block for asynchronous execution on a dispatch queue. 673 * 674 * @discussion 675 * Submits a block to a dispatch queue like dispatch_async(), but marks that 676 * block as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT queues). 677 * 678 * See dispatch_async() for details. 679 * 680 * @param queue 681 * The target dispatch queue to which the block is submitted. 682 * The system will hold a reference on the target queue until the block 683 * has finished. 684 * The result of passing NULL in this parameter is undefined. 685 * 686 * @param block 687 * The block to submit to the target dispatch queue. This function performs 688 * Block_copy() and Block_release() on behalf of callers. 689 * The result of passing NULL in this parameter is undefined. 690 */ 691#ifdef __BLOCKS__ 692__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_3) 693DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 694void 695dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block); 696#endif 697 698/*! 699 * @function dispatch_barrier_async_f 700 * 701 * @abstract 702 * Submits a barrier function for asynchronous execution on a dispatch queue. 703 * 704 * @discussion 705 * Submits a function to a dispatch queue like dispatch_async_f(), but marks 706 * that function as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT 707 * queues). 708 * 709 * See dispatch_async_f() for details. 710 * 711 * @param queue 712 * The target dispatch queue to which the function is submitted. 713 * The system will hold a reference on the target queue until the function 714 * has returned. 715 * The result of passing NULL in this parameter is undefined. 716 * 717 * @param context 718 * The application-defined context parameter to pass to the function. 719 * 720 * @param work 721 * The application-defined function to invoke on the target queue. The first 722 * parameter passed to this function is the context provided to 723 * dispatch_barrier_async_f(). 724 * The result of passing NULL in this parameter is undefined. 725 */ 726__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_3) 727DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW 728void 729dispatch_barrier_async_f(dispatch_queue_t queue, 730 void *context, 731 dispatch_function_t work); 732 733/*! 734 * @function dispatch_barrier_sync 735 * 736 * @abstract 737 * Submits a barrier block for synchronous execution on a dispatch queue. 738 * 739 * @discussion 740 * Submits a block to a dispatch queue like dispatch_sync(), but marks that 741 * block as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT queues). 742 * 743 * See dispatch_sync() for details. 744 * 745 * @param queue 746 * The target dispatch queue to which the block is submitted. 747 * The result of passing NULL in this parameter is undefined. 748 * 749 * @param block 750 * The block to be invoked on the target dispatch queue. 751 * The result of passing NULL in this parameter is undefined. 752 */ 753#ifdef __BLOCKS__ 754__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_3) 755DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 756void 757dispatch_barrier_sync(dispatch_queue_t queue, dispatch_block_t block); 758#endif 759 760/*! 761 * @function dispatch_barrier_sync_f 762 * 763 * @abstract 764 * Submits a barrier function for synchronous execution on a dispatch queue. 765 * 766 * @discussion 767 * Submits a function to a dispatch queue like dispatch_sync_f(), but marks that 768 * fuction as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT queues). 769 * 770 * See dispatch_sync_f() for details. 771 * 772 * @param queue 773 * The target dispatch queue to which the function is submitted. 774 * The result of passing NULL in this parameter is undefined. 775 * 776 * @param context 777 * The application-defined context parameter to pass to the function. 778 * 779 * @param work 780 * The application-defined function to invoke on the target queue. The first 781 * parameter passed to this function is the context provided to 782 * dispatch_barrier_sync_f(). 783 * The result of passing NULL in this parameter is undefined. 784 */ 785__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_4_3) 786DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW 787void 788dispatch_barrier_sync_f(dispatch_queue_t queue, 789 void *context, 790 dispatch_function_t work); 791 792/*! 793 * @functiongroup Dispatch queue-specific contexts 794 * This API allows different subsystems to associate context to a shared queue 795 * without risk of collision and to retrieve that context from blocks executing 796 * on that queue or any of its child queues in the target queue hierarchy. 797 */ 798 799/*! 800 * @function dispatch_queue_set_specific 801 * 802 * @abstract 803 * Associates a subsystem-specific context with a dispatch queue, for a key 804 * unique to the subsystem. 805 * 806 * @discussion 807 * The specified destructor will be invoked with the context on the default 808 * priority global concurrent queue when a new context is set for the same key, 809 * or after all references to the queue have been released. 810 * 811 * @param queue 812 * The dispatch queue to modify. 813 * The result of passing NULL in this parameter is undefined. 814 * 815 * @param key 816 * The key to set the context for, typically a pointer to a static variable 817 * specific to the subsystem. Keys are only compared as pointers and never 818 * dereferenced. Passing a string constant directly is not recommended. 819 * The NULL key is reserved and attemps to set a context for it are ignored. 820 * 821 * @param context 822 * The new subsystem-specific context for the object. This may be NULL. 823 * 824 * @param destructor 825 * The destructor function pointer. This may be NULL and is ignored if context 826 * is NULL. 827 */ 828__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0) 829DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL2 DISPATCH_NOTHROW 830void 831dispatch_queue_set_specific(dispatch_queue_t queue, const void *key, 832 void *context, dispatch_function_t destructor); 833 834/*! 835 * @function dispatch_queue_get_specific 836 * 837 * @abstract 838 * Returns the subsystem-specific context associated with a dispatch queue, for 839 * a key unique to the subsystem. 840 * 841 * @discussion 842 * Returns the context for the specified key if it has been set on the specified 843 * queue. 844 * 845 * @param queue 846 * The dispatch queue to query. 847 * The result of passing NULL in this parameter is undefined. 848 * 849 * @param key 850 * The key to get the context for, typically a pointer to a static variable 851 * specific to the subsystem. Keys are only compared as pointers and never 852 * dereferenced. Passing a string constant directly is not recommended. 853 * 854 * @result 855 * The context for the specified key or NULL if no context was found. 856 */ 857__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0) 858DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_PURE DISPATCH_WARN_RESULT 859DISPATCH_NOTHROW 860void * 861dispatch_queue_get_specific(dispatch_queue_t queue, const void *key); 862 863/*! 864 * @function dispatch_get_specific 865 * 866 * @abstract 867 * Returns the current subsystem-specific context for a key unique to the 868 * subsystem. 869 * 870 * @discussion 871 * When called from a block executing on a queue, returns the context for the 872 * specified key if it has been set on the queue, otherwise returns the result 873 * of dispatch_get_specific() executed on the queue's target queue or NULL 874 * if the current queue is a global concurrent queue. 875 * 876 * @param key 877 * The key to get the context for, typically a pointer to a static variable 878 * specific to the subsystem. Keys are only compared as pointers and never 879 * dereferenced. Passing a string constant directly is not recommended. 880 * 881 * @result 882 * The context for the specified key or NULL if no context was found. 883 */ 884__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0) 885DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_PURE DISPATCH_WARN_RESULT 886DISPATCH_NOTHROW 887void * 888dispatch_get_specific(const void *key); 889 890__END_DECLS 891 892#endif 893