zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

block.h (18680B) - Raw


      1 /*
      2  * Copyright (c) 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_BLOCK__
     22 #define __DISPATCH_BLOCK__
     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 #ifdef __BLOCKS__
     30 
     31 /*!
     32  * @group Dispatch block objects
     33  */
     34 
     35 DISPATCH_ASSUME_NONNULL_BEGIN
     36 DISPATCH_ASSUME_ABI_SINGLE_BEGIN
     37 
     38 __BEGIN_DECLS
     39 
     40 /*!
     41  * @typedef dispatch_block_flags_t
     42  * Flags to pass to the dispatch_block_create* functions.
     43  *
     44  * @const DISPATCH_BLOCK_BARRIER
     45  * Flag indicating that a dispatch block object should act as a barrier block
     46  * when submitted to a DISPATCH_QUEUE_CONCURRENT queue.
     47  * See dispatch_barrier_async() for details.
     48  * This flag has no effect when the dispatch block object is invoked directly.
     49  *
     50  * @const DISPATCH_BLOCK_DETACHED
     51  * Flag indicating that a dispatch block object should execute disassociated
     52  * from current execution context attributes such as os_activity_t
     53  * and properties of the current IPC request (if any). With regard to QoS class,
     54  * the behavior is the same as for DISPATCH_BLOCK_NO_QOS. If invoked directly,
     55  * the block object will remove the other attributes from the calling thread for
     56  * the duration of the block body (before applying attributes assigned to the
     57  * block object, if any). If submitted to a queue, the block object will be
     58  * executed with the attributes of the queue (or any attributes specifically
     59  * assigned to the block object).
     60  *
     61  * @const DISPATCH_BLOCK_ASSIGN_CURRENT
     62  * Flag indicating that a dispatch block object should be assigned the execution
     63  * context attributes that are current at the time the block object is created.
     64  * This applies to attributes such as QOS class, os_activity_t and properties of
     65  * the current IPC request (if any). If invoked directly, the block object will
     66  * apply these attributes to the calling thread for the duration of the block
     67  * body. If the block object is submitted to a queue, this flag replaces the
     68  * default behavior of associating the submitted block instance with the
     69  * execution context attributes that are current at the time of submission.
     70  * If a specific QOS class is assigned with DISPATCH_BLOCK_NO_QOS_CLASS or
     71  * dispatch_block_create_with_qos_class(), that QOS class takes precedence over
     72  * the QOS class assignment indicated by this flag.
     73  *
     74  * @const DISPATCH_BLOCK_NO_QOS_CLASS
     75  * Flag indicating that a dispatch block object should be not be assigned a QOS
     76  * class. If invoked directly, the block object will be executed with the QOS
     77  * class of the calling thread. If the block object is submitted to a queue,
     78  * this replaces the default behavior of associating the submitted block
     79  * instance with the QOS class current at the time of submission.
     80  * This flag is ignored if a specific QOS class is assigned with
     81  * dispatch_block_create_with_qos_class().
     82  *
     83  * @const DISPATCH_BLOCK_INHERIT_QOS_CLASS
     84  * Flag indicating that execution of a dispatch block object submitted to a
     85  * queue should prefer the QOS class assigned to the queue over the QOS class
     86  * assigned to the block (resp. associated with the block at the time of
     87  * submission). The latter will only be used if the queue in question does not
     88  * have an assigned QOS class, as long as doing so does not result in a QOS
     89  * class lower than the QOS class inherited from the queue's target queue.
     90  * This flag is the default when a dispatch block object is submitted to a queue
     91  * for asynchronous execution and has no effect when the dispatch block object
     92  * is invoked directly. It is ignored if DISPATCH_BLOCK_ENFORCE_QOS_CLASS is
     93  * also passed.
     94  *
     95  * @const DISPATCH_BLOCK_ENFORCE_QOS_CLASS
     96  * Flag indicating that execution of a dispatch block object submitted to a
     97  * queue should prefer the QOS class assigned to the block (resp. associated
     98  * with the block at the time of submission) over the QOS class assigned to the
     99  * queue, as long as doing so will not result in a lower QOS class.
    100  * This flag is the default when a dispatch block object is submitted to a queue
    101  * for synchronous execution or when the dispatch block object is invoked
    102  * directly.
    103  */
    104 DISPATCH_REFINED_FOR_SWIFT
    105 DISPATCH_OPTIONS(dispatch_block_flags, unsigned long,
    106 	DISPATCH_BLOCK_BARRIER
    107 			DISPATCH_ENUM_API_AVAILABLE(macos(10.10), ios(8.0))
    108 			DISPATCH_SWIFT_UNAVAILABLE("Use DispatchWorkItemFlags.barrier") = 0x1,
    109 	DISPATCH_BLOCK_DETACHED
    110 			DISPATCH_ENUM_API_AVAILABLE(macos(10.10), ios(8.0))
    111 			DISPATCH_SWIFT_UNAVAILABLE("Use DispatchWorkItemFlags.detached") = 0x2,
    112 	DISPATCH_BLOCK_ASSIGN_CURRENT
    113 			DISPATCH_ENUM_API_AVAILABLE(macos(10.10), ios(8.0))
    114 			DISPATCH_SWIFT_UNAVAILABLE("Use DispatchWorkItemFlags.assignCurrentContext") = 0x4,
    115 	DISPATCH_BLOCK_NO_QOS_CLASS
    116 			DISPATCH_ENUM_API_AVAILABLE(macos(10.10), ios(8.0))
    117 			DISPATCH_SWIFT_UNAVAILABLE("Use DispatchWorkItemFlags.noQoS") = 0x8,
    118 	DISPATCH_BLOCK_INHERIT_QOS_CLASS
    119 			DISPATCH_ENUM_API_AVAILABLE(macos(10.10), ios(8.0))
    120 			DISPATCH_SWIFT_UNAVAILABLE("Use DispatchWorkItemFlags.inheritQoS") = 0x10,
    121 	DISPATCH_BLOCK_ENFORCE_QOS_CLASS
    122 			DISPATCH_ENUM_API_AVAILABLE(macos(10.10), ios(8.0))
    123 			DISPATCH_SWIFT_UNAVAILABLE("Use DispatchWorkItemFlags.enforceQoS") = 0x20,
    124 );
    125 
    126 /*!
    127  * @function dispatch_block_create
    128  *
    129  * @abstract
    130  * Create a new dispatch block object on the heap from an existing block and
    131  * the given flags.
    132  *
    133  * @discussion
    134  * The provided block is Block_copy'ed to the heap and retained by the newly
    135  * created dispatch block object.
    136  *
    137  * The returned dispatch block object is intended to be submitted to a dispatch
    138  * queue with dispatch_async() and related functions, but may also be invoked
    139  * directly. Both operations can be performed an arbitrary number of times but
    140  * only the first completed execution of a dispatch block object can be waited
    141  * on with dispatch_block_wait() or observed with dispatch_block_notify().
    142  *
    143  * If the returned dispatch block object is submitted to a dispatch queue, the
    144  * submitted block instance will be associated with the QOS class current at the
    145  * time of submission, unless one of the following flags assigned a specific QOS
    146  * class (or no QOS class) at the time of block creation:
    147  *  - DISPATCH_BLOCK_ASSIGN_CURRENT
    148  *  - DISPATCH_BLOCK_NO_QOS_CLASS
    149  *  - DISPATCH_BLOCK_DETACHED
    150  * The QOS class the block object will be executed with also depends on the QOS
    151  * class assigned to the queue and which of the following flags was specified or
    152  * defaulted to:
    153  *  - DISPATCH_BLOCK_INHERIT_QOS_CLASS (default for asynchronous execution)
    154  *  - DISPATCH_BLOCK_ENFORCE_QOS_CLASS (default for synchronous execution)
    155  * See description of dispatch_block_flags_t for details.
    156  *
    157  * If the returned dispatch block object is submitted directly to a serial queue
    158  * and is configured to execute with a specific QOS class, the system will make
    159  * a best effort to apply the necessary QOS overrides to ensure that blocks
    160  * submitted earlier to the serial queue are executed at that same QOS class or
    161  * higher.
    162  *
    163  * @param flags
    164  * Configuration flags for the block object.
    165  * Passing a value that is not a bitwise OR of flags from dispatch_block_flags_t
    166  * results in NULL being returned.
    167  *
    168  * @param block
    169  * The block to create the dispatch block object from.
    170  *
    171  * @result
    172  * The newly created dispatch block object, or NULL.
    173  * When not building with Objective-C ARC, must be released with a -[release]
    174  * message or the Block_release() function.
    175  */
    176 API_AVAILABLE(macos(10.10), ios(8.0))
    177 DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_RETURNS_RETAINED_BLOCK
    178 DISPATCH_WARN_RESULT DISPATCH_NOTHROW
    179 DISPATCH_SWIFT_UNAVAILABLE("Use DispatchWorkItem()")
    180 dispatch_block_t
    181 dispatch_block_create(dispatch_block_flags_t flags, dispatch_block_t block);
    182 
    183 /*!
    184  * @function dispatch_block_create_with_qos_class
    185  *
    186  * @abstract
    187  * Create a new dispatch block object on the heap from an existing block and
    188  * the given flags, and assign it the specified QOS class and relative priority.
    189  *
    190  * @discussion
    191  * The provided block is Block_copy'ed to the heap and retained by the newly
    192  * created dispatch block object.
    193  *
    194  * The returned dispatch block object is intended to be submitted to a dispatch
    195  * queue with dispatch_async() and related functions, but may also be invoked
    196  * directly. Both operations can be performed an arbitrary number of times but
    197  * only the first completed execution of a dispatch block object can be waited
    198  * on with dispatch_block_wait() or observed with dispatch_block_notify().
    199  *
    200  * If invoked directly, the returned dispatch block object will be executed with
    201  * the assigned QOS class as long as that does not result in a lower QOS class
    202  * than what is current on the calling thread.
    203  *
    204  * If the returned dispatch block object is submitted to a dispatch queue, the
    205  * QOS class it will be executed with depends on the QOS class assigned to the
    206  * block, the QOS class assigned to the queue and which of the following flags
    207  * was specified or defaulted to:
    208  *  - DISPATCH_BLOCK_INHERIT_QOS_CLASS: default for asynchronous execution
    209  *  - DISPATCH_BLOCK_ENFORCE_QOS_CLASS: default for synchronous execution
    210  * See description of dispatch_block_flags_t for details.
    211  *
    212  * If the returned dispatch block object is submitted directly to a serial queue
    213  * and is configured to execute with a specific QOS class, the system will make
    214  * a best effort to apply the necessary QOS overrides to ensure that blocks
    215  * submitted earlier to the serial queue are executed at that same QOS class or
    216  * higher.
    217  *
    218  * @param flags
    219  * Configuration flags for the new block object.
    220  * Passing a value that is not a bitwise OR of flags from dispatch_block_flags_t
    221  * results in NULL being returned.
    222  *
    223  * @param qos_class
    224  * A QOS class value:
    225  *  - QOS_CLASS_USER_INTERACTIVE
    226  *  - QOS_CLASS_USER_INITIATED
    227  *  - QOS_CLASS_DEFAULT
    228  *  - QOS_CLASS_UTILITY
    229  *  - QOS_CLASS_BACKGROUND
    230  *  - QOS_CLASS_UNSPECIFIED
    231  * Passing QOS_CLASS_UNSPECIFIED is equivalent to specifying the
    232  * DISPATCH_BLOCK_NO_QOS_CLASS flag. Passing any other value results in NULL
    233  * being returned.
    234  *
    235  * @param relative_priority
    236  * A relative priority within the QOS class. This value is a negative
    237  * offset from the maximum supported scheduler priority for the given class.
    238  * Passing a value greater than zero or less than QOS_MIN_RELATIVE_PRIORITY
    239  * results in NULL being returned.
    240  *
    241  * @param block
    242  * The block to create the dispatch block object from.
    243  *
    244  * @result
    245  * The newly created dispatch block object, or NULL.
    246  * When not building with Objective-C ARC, must be released with a -[release]
    247  * message or the Block_release() function.
    248  */
    249 API_AVAILABLE(macos(10.10), ios(8.0))
    250 DISPATCH_EXPORT DISPATCH_NONNULL4 DISPATCH_RETURNS_RETAINED_BLOCK
    251 DISPATCH_WARN_RESULT DISPATCH_NOTHROW
    252 DISPATCH_SWIFT_UNAVAILABLE("Use DispatchWorkItem()")
    253 dispatch_block_t
    254 dispatch_block_create_with_qos_class(dispatch_block_flags_t flags,
    255 		dispatch_qos_class_t qos_class, int relative_priority,
    256 		dispatch_block_t block);
    257 
    258 /*!
    259  * @function dispatch_block_perform
    260  *
    261  * @abstract
    262  * Create, synchronously execute and release a dispatch block object from the
    263  * specified block and flags.
    264  *
    265  * @discussion
    266  * Behaves identically to the sequence
    267  * <code>
    268  * dispatch_block_t b = dispatch_block_create(flags, block);
    269  * b();
    270  * Block_release(b);
    271  * </code>
    272  * but may be implemented more efficiently internally by not requiring a copy
    273  * to the heap of the specified block or the allocation of a new block object.
    274  *
    275  * @param flags
    276  * Configuration flags for the temporary block object.
    277  * The result of passing a value that is not a bitwise OR of flags from
    278  * dispatch_block_flags_t is undefined.
    279  *
    280  * @param block
    281  * The block to create the temporary block object from.
    282  */
    283 API_AVAILABLE(macos(10.10), ios(8.0))
    284 DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NOTHROW
    285 DISPATCH_SWIFT_UNAVAILABLE("Use DispatchWorkItem.perform()")
    286 void
    287 dispatch_block_perform(dispatch_block_flags_t flags,
    288 		DISPATCH_NOESCAPE dispatch_block_t block);
    289 
    290 /*!
    291  * @function dispatch_block_wait
    292  *
    293  * @abstract
    294  * Wait synchronously until execution of the specified dispatch block object has
    295  * completed or until the specified timeout has elapsed.
    296  *
    297  * @discussion
    298  * This function will return immediately if execution of the block object has
    299  * already completed.
    300  *
    301  * It is not possible to wait for multiple executions of the same block object
    302  * with this interface; use dispatch_group_wait() for that purpose. A single
    303  * dispatch block object may either be waited on once and executed once,
    304  * or it may be executed any number of times. The behavior of any other
    305  * combination is undefined. Submission to a dispatch queue counts as an
    306  * execution, even if cancellation (dispatch_block_cancel) means the block's
    307  * code never runs.
    308  *
    309  * The result of calling this function from multiple threads simultaneously
    310  * with the same dispatch block object is undefined, but note that doing so
    311  * would violate the rules described in the previous paragraph.
    312  *
    313  * If this function returns indicating that the specified timeout has elapsed,
    314  * then that invocation does not count as the one allowed wait.
    315  *
    316  * If at the time this function is called, the specified dispatch block object
    317  * has been submitted directly to a serial queue, the system will make a best
    318  * effort to apply the necessary QOS overrides to ensure that the block and any
    319  * blocks submitted earlier to that serial queue are executed at the QOS class
    320  * (or higher) of the thread calling dispatch_block_wait().
    321  *
    322  * @param block
    323  * The dispatch block object to wait on.
    324  * The result of passing NULL or a block object not returned by one of the
    325  * dispatch_block_create* functions is undefined.
    326  *
    327  * @param timeout
    328  * When to timeout (see dispatch_time). As a convenience, there are the
    329  * DISPATCH_TIME_NOW and DISPATCH_TIME_FOREVER constants.
    330  *
    331  * @result
    332  * Returns zero on success (the dispatch block object completed within the
    333  * specified timeout) or non-zero on error (i.e. timed out).
    334  */
    335 API_AVAILABLE(macos(10.10), ios(8.0))
    336 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
    337 DISPATCH_SWIFT_UNAVAILABLE("Use DispatchWorkItem.wait(timeout:)")
    338 intptr_t
    339 dispatch_block_wait(dispatch_block_t block, dispatch_time_t timeout);
    340 
    341 /*!
    342  * @function dispatch_block_notify
    343  *
    344  * @abstract
    345  * Schedule a notification block to be submitted to a queue when the execution
    346  * of a specified dispatch block object has completed.
    347  *
    348  * @discussion
    349  * This function will submit the notification block immediately if execution of
    350  * the observed block object has already completed.
    351  *
    352  * It is not possible to be notified of multiple executions of the same block
    353  * object with this interface, use dispatch_group_notify() for that purpose.
    354  *
    355  * A single dispatch block object may either be observed one or more times
    356  * and executed once, or it may be executed any number of times. The behavior
    357  * of any other combination is undefined. Submission to a dispatch queue
    358  * counts as an execution, even if cancellation (dispatch_block_cancel) means
    359  * the block's code never runs.
    360  *
    361  * If multiple notification blocks are scheduled for a single block object,
    362  * there is no defined order in which the notification blocks will be submitted
    363  * to their associated queues.
    364  *
    365  * @param block
    366  * The dispatch block object to observe.
    367  * The result of passing NULL or a block object not returned by one of the
    368  * dispatch_block_create* functions is undefined.
    369  *
    370  * @param queue
    371  * The queue to which the supplied notification block will be submitted when
    372  * the observed block completes.
    373  *
    374  * @param notification_block
    375  * The notification block to submit when the observed block object completes.
    376  */
    377 API_AVAILABLE(macos(10.10), ios(8.0))
    378 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
    379 DISPATCH_SWIFT_UNAVAILABLE("Use DispatchWorkItem.notify(queue:execute:)")
    380 void
    381 dispatch_block_notify(dispatch_block_t block, dispatch_queue_t queue,
    382 		dispatch_block_t notification_block);
    383 
    384 /*!
    385  * @function dispatch_block_cancel
    386  *
    387  * @abstract
    388  * Asynchronously cancel the specified dispatch block object.
    389  *
    390  * @discussion
    391  * Cancellation causes any future execution of the dispatch block object to
    392  * return immediately, but does not affect any execution of the block object
    393  * that is already in progress.
    394  *
    395  * Release of any resources associated with the block object will be delayed
    396  * until execution of the block object is next attempted (or any execution
    397  * already in progress completes).
    398  *
    399  * NOTE: care needs to be taken to ensure that a block object that may be
    400  *       canceled does not capture any resources that require execution of the
    401  *       block body in order to be released (e.g. memory allocated with
    402  *       malloc(3) that the block body calls free(3) on). Such resources will
    403  *       be leaked if the block body is never executed due to cancellation.
    404  *
    405  * @param block
    406  * The dispatch block object to cancel.
    407  * The result of passing NULL or a block object not returned by one of the
    408  * dispatch_block_create* functions is undefined.
    409  */
    410 API_AVAILABLE(macos(10.10), ios(8.0))
    411 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
    412 DISPATCH_SWIFT_UNAVAILABLE("Use DispatchWorkItem.cancel()")
    413 void
    414 dispatch_block_cancel(dispatch_block_t block);
    415 
    416 /*!
    417  * @function dispatch_block_testcancel
    418  *
    419  * @abstract
    420  * Tests whether the given dispatch block object has been canceled.
    421  *
    422  * @param block
    423  * The dispatch block object to test.
    424  * The result of passing NULL or a block object not returned by one of the
    425  * dispatch_block_create* functions is undefined.
    426  *
    427  * @result
    428  * Non-zero if canceled and zero if not canceled.
    429  */
    430 API_AVAILABLE(macos(10.10), ios(8.0))
    431 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE
    432 DISPATCH_NOTHROW
    433 DISPATCH_SWIFT_UNAVAILABLE("Use DispatchWorkItem.isCancelled")
    434 intptr_t
    435 dispatch_block_testcancel(dispatch_block_t block);
    436 
    437 __END_DECLS
    438 
    439 DISPATCH_ASSUME_ABI_SINGLE_END
    440 DISPATCH_ASSUME_NONNULL_END
    441 
    442 #endif // __BLOCKS__
    443 
    444 #endif // __DISPATCH_BLOCK__