2 * Copyright (c) 2008-2012 Apple Inc. All rights reserved.
4 * @APPLE_APACHE_LICENSE_HEADER_START@
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @APPLE_APACHE_LICENSE_HEADER_END@
21 #ifndef __DISPATCH_OBJECT__
22 #define __DISPATCH_OBJECT__
24 #ifndef __DISPATCH_INDIRECT__
25 #error "Please #include <dispatch/dispatch.h> instead of this file directly."
26 #include <dispatch/base.h> // for HeaderDoc
29 DISPATCH_ASSUME_NONNULL_BEGIN
32 * @typedef dispatch_object_t
35 * Abstract base type for all dispatch objects.
36 * The details of the type definition are language-specific.
39 * Dispatch objects are reference counted via calls to dispatch_retain() and
43 #if OS_OBJECT_USE_OBJC
45 * By default, dispatch objects are declared as Objective-C types when building
46 * with an Objective-C compiler. This allows them to participate in ARC, in RR
47 * management by the Blocks runtime and in leaks checking by the static
48 * analyzer, and enables them to be added to Cocoa collections.
49 * See <os/object.h> for details.
51 OS_OBJECT_DECL_CLASS(dispatch_object
);
54 #define DISPATCH_DECL(name) OS_OBJECT_DECL_SUBCLASS_SWIFT(name, dispatch_object)
55 #else // OS_OBJECT_SWIFT3
56 #define DISPATCH_DECL(name) OS_OBJECT_DECL_SUBCLASS(name, dispatch_object)
58 DISPATCH_INLINE DISPATCH_ALWAYS_INLINE DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
60 _dispatch_object_validate(dispatch_object_t object
) {
61 void *isa
= *(void* volatile*)(OS_OBJECT_BRIDGE
void*)object
;
64 #endif // OS_OBJECT_SWIFT3
66 #define DISPATCH_GLOBAL_OBJECT(type, object) ((OS_OBJECT_BRIDGE type)&(object))
67 #define DISPATCH_RETURNS_RETAINED OS_OBJECT_RETURNS_RETAINED
68 #elif defined(__cplusplus) && !defined(__DISPATCH_BUILDING_DISPATCH__)
70 * Dispatch objects are NOT C++ objects. Nevertheless, we can at least keep C++
71 * aware of type compatibility.
73 typedef struct dispatch_object_s
{
77 dispatch_object_s(const dispatch_object_s
&);
78 void operator=(const dispatch_object_s
&);
80 #define DISPATCH_DECL(name) \
81 typedef struct name##_s : public dispatch_object_s {} *name##_t
82 #define DISPATCH_GLOBAL_OBJECT(type, object) (&(object))
83 #define DISPATCH_RETURNS_RETAINED
86 struct _os_object_s
*_os_obj
;
87 struct dispatch_object_s
*_do
;
88 struct dispatch_continuation_s
*_dc
;
89 struct dispatch_queue_s
*_dq
;
90 struct dispatch_queue_attr_s
*_dqa
;
91 struct dispatch_group_s
*_dg
;
92 struct dispatch_source_s
*_ds
;
93 struct dispatch_mach_s
*_dm
;
94 struct dispatch_mach_msg_s
*_dmsg
;
95 struct dispatch_timer_aggregate_s
*_dta
;
96 struct dispatch_source_attr_s
*_dsa
;
97 struct dispatch_semaphore_s
*_dsema
;
98 struct dispatch_data_s
*_ddata
;
99 struct dispatch_io_s
*_dchannel
;
100 struct dispatch_operation_s
*_doperation
;
101 struct dispatch_disk_s
*_ddisk
;
102 } dispatch_object_t
__attribute__((__transparent_union__
));
104 #define DISPATCH_DECL(name) typedef struct name##_s *name##_t
106 #define DISPATCH_GLOBAL_OBJECT(t, x) (&(x))
108 #define DISPATCH_RETURNS_RETAINED
111 #if OS_OBJECT_SWIFT3 && OS_OBJECT_USE_OBJC
112 #define DISPATCH_SOURCE_TYPE_DECL(name) \
113 DISPATCH_EXPORT struct dispatch_source_type_s \
114 _dispatch_source_type_##name; \
115 OS_OBJECT_DECL_PROTOCOL(dispatch_source_##name, <OS_dispatch_source>); \
116 OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL( \
117 dispatch_source, dispatch_source_##name)
118 #define DISPATCH_SOURCE_DECL(name) \
119 DISPATCH_DECL(name); \
120 OS_OBJECT_DECL_PROTOCOL(name, <NSObject>); \
121 OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL(name, name)
122 #ifndef DISPATCH_DATA_DECL
123 #define DISPATCH_DATA_DECL(name) OS_OBJECT_DECL_SWIFT(name)
124 #endif // DISPATCH_DATA_DECL
125 #elif !TARGET_OS_WIN32
127 #define DISPATCH_SOURCE_DECL(name) \
130 #define DISPATCH_DATA_DECL(name) DISPATCH_DECL(name)
132 #define DISPATCH_SOURCE_TYPE_DECL(name) \
133 DISPATCH_EXPORT const struct dispatch_source_type_s \
134 _dispatch_source_type_##name
136 #define DISPATCH_SOURCE_DECL(name) \
138 #define DISPATCH_SOURCE_TYPE_DECL(name) \
139 DISPATCH_EXPORT struct dispatch_source_type_s _dispatch_source_type_##name
140 #define DISPATCH_DATA_DECL(name) DISPATCH_DECL(name)
145 * @typedef dispatch_block_t
148 * The type of blocks submitted to dispatch queues, which take no arguments
149 * and have no return value.
152 * When not building with Objective-C ARC, a block object allocated on or
153 * copied to the heap must be released with a -[release] message or the
154 * Block_release() function.
156 * The declaration of a block literal allocates storage on the stack.
157 * Therefore, this is an invalid construct:
159 * dispatch_block_t block;
161 * block = ^{ printf("true\n"); };
163 * block = ^{ printf("false\n"); };
165 * block(); // unsafe!!!
168 * What is happening behind the scenes:
171 * struct Block __tmp_1 = ...; // setup details
174 * struct Block __tmp_2 = ...; // setup details
179 * As the example demonstrates, the address of a stack variable is escaping the
180 * scope in which it is allocated. That is a classic C bug.
182 * Instead, the block literal must be copied to the heap with the Block_copy()
183 * function or by sending it a -[copy] message.
185 typedef void (^dispatch_block_t
)(void);
191 * @function dispatch_retain
194 * Increment the reference count of a dispatch object.
197 * Calls to dispatch_retain() must be balanced with calls to
198 * dispatch_release().
201 * The object to retain.
202 * The result of passing NULL in this parameter is undefined.
204 __OSX_AVAILABLE_STARTING(__MAC_10_6
,__IPHONE_4_0
)
205 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
206 DISPATCH_SWIFT_UNAVAILABLE("Can't be used with ARC")
208 dispatch_retain(dispatch_object_t object
);
209 #if OS_OBJECT_USE_OBJC_RETAIN_RELEASE
210 #undef dispatch_retain
211 #define dispatch_retain(object) \
212 __extension__({ dispatch_object_t _o = (object); \
213 _dispatch_object_validate(_o); (void)[_o retain]; })
217 * @function dispatch_release
220 * Decrement the reference count of a dispatch object.
223 * A dispatch object is asynchronously deallocated once all references are
224 * released (i.e. the reference count becomes zero). The system does not
225 * guarantee that a given client is the last or only reference to a given
229 * The object to release.
230 * The result of passing NULL in this parameter is undefined.
232 __OSX_AVAILABLE_STARTING(__MAC_10_6
,__IPHONE_4_0
)
233 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
234 DISPATCH_SWIFT_UNAVAILABLE("Can't be used with ARC")
236 dispatch_release(dispatch_object_t object
);
237 #if OS_OBJECT_USE_OBJC_RETAIN_RELEASE
238 #undef dispatch_release
239 #define dispatch_release(object) \
240 __extension__({ dispatch_object_t _o = (object); \
241 _dispatch_object_validate(_o); [_o release]; })
245 * @function dispatch_get_context
248 * Returns the application defined context of the object.
251 * The result of passing NULL in this parameter is undefined.
254 * The context of the object; may be NULL.
256 __OSX_AVAILABLE_STARTING(__MAC_10_6
,__IPHONE_4_0
)
257 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_PURE DISPATCH_WARN_RESULT
260 dispatch_get_context(dispatch_object_t object
);
263 * @function dispatch_set_context
266 * Associates an application defined context with the object.
269 * The result of passing NULL in this parameter is undefined.
272 * The new client defined context for the object. This may be NULL.
275 __OSX_AVAILABLE_STARTING(__MAC_10_6
,__IPHONE_4_0
)
276 DISPATCH_EXPORT DISPATCH_NOTHROW
278 dispatch_set_context(dispatch_object_t object
, void *_Nullable context
);
281 * @function dispatch_set_finalizer_f
284 * Set the finalizer function for a dispatch object.
287 * The dispatch object to modify.
288 * The result of passing NULL in this parameter is undefined.
291 * The finalizer function pointer.
294 * A dispatch object's finalizer will be invoked on the object's target queue
295 * after all references to the object have been released. This finalizer may be
296 * used by the application to release any resources associated with the object,
297 * such as freeing the object's context.
298 * The context parameter passed to the finalizer function is the current
299 * context of the dispatch object at the time the finalizer call is made.
301 __OSX_AVAILABLE_STARTING(__MAC_10_6
,__IPHONE_4_0
)
302 DISPATCH_EXPORT DISPATCH_NOTHROW
304 dispatch_set_finalizer_f(dispatch_object_t object
,
305 dispatch_function_t _Nullable finalizer
);
308 * @function dispatch_activate
311 * Activates the specified dispatch object.
314 * Dispatch objects such as queues and sources may be created in an inactive
315 * state. Objects in this state have to be activated before any blocks
316 * associated with them will be invoked.
318 * The target queue of inactive objects can be changed using
319 * dispatch_set_target_queue(). Change of target queue is no longer permitted
320 * once an initially inactive object has been activated.
322 * Calling dispatch_activate() on an active object has no effect.
323 * Releasing the last reference count on an inactive object is undefined.
326 * The object to be activated.
327 * The result of passing NULL in this parameter is undefined.
329 __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0)
330 __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0)
331 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
333 dispatch_activate(dispatch_object_t object
);
336 * @function dispatch_suspend
339 * Suspends the invocation of blocks on a dispatch object.
342 * A suspended object will not invoke any blocks associated with it. The
343 * suspension of an object will occur after any running block associated with
344 * the object completes.
346 * Calls to dispatch_suspend() must be balanced with calls
347 * to dispatch_resume().
350 * The object to be suspended.
351 * The result of passing NULL in this parameter is undefined.
353 __OSX_AVAILABLE_STARTING(__MAC_10_6
,__IPHONE_4_0
)
354 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
356 dispatch_suspend(dispatch_object_t object
);
359 * @function dispatch_resume
362 * Resumes the invocation of blocks on a dispatch object.
365 * Dispatch objects can be suspended with dispatch_suspend(), which increments
366 * an internal suspension count. dispatch_resume() is the inverse operation,
367 * and consumes suspension counts. When the last suspension count is consumed,
368 * blocks associated with the object will be invoked again.
370 * For backward compatibility reasons, dispatch_resume() on an inactive and not
371 * otherwise suspended dispatch source object has the same effect as calling
372 * dispatch_activate(). For new code, using dispatch_activate() is preferred.
374 * If the specified object has zero suspension count and is not an inactive
375 * source, this function will result in an assertion and the process being
379 * The object to be resumed.
380 * The result of passing NULL in this parameter is undefined.
382 __OSX_AVAILABLE_STARTING(__MAC_10_6
,__IPHONE_4_0
)
383 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
385 dispatch_resume(dispatch_object_t object
);
389 * @function dispatch_wait
392 * Wait synchronously for an object or until the specified timeout has elapsed.
395 * Type-generic macro that maps to dispatch_block_wait, dispatch_group_wait or
396 * dispatch_semaphore_wait, depending on the type of the first argument.
397 * See documentation for these functions for more details.
398 * This function is unavailable for any other object type.
401 * The object to wait on.
402 * The result of passing NULL in this parameter is undefined.
405 * When to timeout (see dispatch_time). As a convenience, there are the
406 * DISPATCH_TIME_NOW and DISPATCH_TIME_FOREVER constants.
409 * Returns zero on success or non-zero on error (i.e. timed out).
412 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
414 dispatch_wait(void *object
, dispatch_time_t timeout
);
415 #if __has_extension(c_generic_selections)
416 #define dispatch_wait(object, timeout) \
418 dispatch_block_t:dispatch_block_wait, \
419 dispatch_group_t:dispatch_group_wait, \
420 dispatch_semaphore_t:dispatch_semaphore_wait \
421 )((object),(timeout))
425 * @function dispatch_notify
428 * Schedule a notification block to be submitted to a queue when the execution
429 * of a specified object has completed.
432 * Type-generic macro that maps to dispatch_block_notify or
433 * dispatch_group_notify, depending on the type of the first argument.
434 * See documentation for these functions for more details.
435 * This function is unavailable for any other object type.
438 * The object to observe.
439 * The result of passing NULL in this parameter is undefined.
442 * The queue to which the supplied notification block will be submitted when
443 * the observed object completes.
445 * @param notification_block
446 * The block to submit when the observed object completes.
449 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
451 dispatch_notify(void *object
, dispatch_object_t queue
,
452 dispatch_block_t notification_block
);
453 #if __has_extension(c_generic_selections)
454 #define dispatch_notify(object, queue, notification_block) \
456 dispatch_block_t:dispatch_block_notify, \
457 dispatch_group_t:dispatch_group_notify \
458 )((object),(queue), (notification_block))
462 * @function dispatch_cancel
465 * Cancel the specified object.
468 * Type-generic macro that maps to dispatch_block_cancel or
469 * dispatch_source_cancel, depending on the type of the first argument.
470 * See documentation for these functions for more details.
471 * This function is unavailable for any other object type.
474 * The object to cancel.
475 * The result of passing NULL in this parameter is undefined.
478 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
480 dispatch_cancel(void *object
);
481 #if __has_extension(c_generic_selections)
482 #define dispatch_cancel(object) \
484 dispatch_block_t:dispatch_block_cancel, \
485 dispatch_source_t:dispatch_source_cancel \
490 * @function dispatch_testcancel
493 * Test whether the specified object has been canceled
496 * Type-generic macro that maps to dispatch_block_testcancel or
497 * dispatch_source_testcancel, depending on the type of the first argument.
498 * See documentation for these functions for more details.
499 * This function is unavailable for any other object type.
502 * The object to test.
503 * The result of passing NULL in this parameter is undefined.
506 * Non-zero if canceled and zero if not canceled.
509 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE
512 dispatch_testcancel(void *object
);
513 #if __has_extension(c_generic_selections)
514 #define dispatch_testcancel(object) \
516 dispatch_block_t:dispatch_block_testcancel, \
517 dispatch_source_t:dispatch_source_testcancel \
523 * @function dispatch_debug
526 * Programmatically log debug information about a dispatch object.
529 * Programmatically log debug information about a dispatch object. By default,
530 * the log output is sent to syslog at notice level. In the debug version of
531 * the library, the log output is sent to a file in /var/tmp.
532 * The log output destination can be configured via the LIBDISPATCH_LOG
533 * environment variable, valid values are: YES, NO, syslog, stderr, file.
535 * This function is deprecated and will be removed in a future release.
536 * Objective-C callers may use -debugDescription instead.
539 * The object to introspect.
542 * The message to log above and beyond the introspection.
544 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6
,__MAC_10_9
,__IPHONE_4_0
,__IPHONE_6_0
)
545 DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NOTHROW
546 __attribute__((__format__(printf
,2,3)))
548 dispatch_debug(dispatch_object_t object
, const char *message
, ...);
550 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6
,__MAC_10_9
,__IPHONE_4_0
,__IPHONE_6_0
)
551 DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NOTHROW
552 __attribute__((__format__(printf
,2,0)))
554 dispatch_debugv(dispatch_object_t object
, const char *message
, va_list ap
);
558 DISPATCH_ASSUME_NONNULL_END