master
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
35DISPATCH_ASSUME_NONNULL_BEGIN
36DISPATCH_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 */
104DISPATCH_REFINED_FOR_SWIFT
105DISPATCH_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 */
176API_AVAILABLE(macos(10.10), ios(8.0))
177DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_RETURNS_RETAINED_BLOCK
178DISPATCH_WARN_RESULT DISPATCH_NOTHROW
179DISPATCH_SWIFT_UNAVAILABLE("Use DispatchWorkItem()")
180dispatch_block_t
181dispatch_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 */
249API_AVAILABLE(macos(10.10), ios(8.0))
250DISPATCH_EXPORT DISPATCH_NONNULL4 DISPATCH_RETURNS_RETAINED_BLOCK
251DISPATCH_WARN_RESULT DISPATCH_NOTHROW
252DISPATCH_SWIFT_UNAVAILABLE("Use DispatchWorkItem()")
253dispatch_block_t
254dispatch_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 */
283API_AVAILABLE(macos(10.10), ios(8.0))
284DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NOTHROW
285DISPATCH_SWIFT_UNAVAILABLE("Use DispatchWorkItem.perform()")
286void
287dispatch_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 */
335API_AVAILABLE(macos(10.10), ios(8.0))
336DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
337DISPATCH_SWIFT_UNAVAILABLE("Use DispatchWorkItem.wait(timeout:)")
338intptr_t
339dispatch_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 */
377API_AVAILABLE(macos(10.10), ios(8.0))
378DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
379DISPATCH_SWIFT_UNAVAILABLE("Use DispatchWorkItem.notify(queue:execute:)")
380void
381dispatch_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 */
410API_AVAILABLE(macos(10.10), ios(8.0))
411DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
412DISPATCH_SWIFT_UNAVAILABLE("Use DispatchWorkItem.cancel()")
413void
414dispatch_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 */
430API_AVAILABLE(macos(10.10), ios(8.0))
431DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE
432DISPATCH_NOTHROW
433DISPATCH_SWIFT_UNAVAILABLE("Use DispatchWorkItem.isCancelled")
434intptr_t
435dispatch_block_testcancel(dispatch_block_t block);
436
437__END_DECLS
438
439DISPATCH_ASSUME_ABI_SINGLE_END
440DISPATCH_ASSUME_NONNULL_END
441
442#endif // __BLOCKS__
443
444#endif // __DISPATCH_BLOCK__