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