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_OBJECT__ 22#define __DISPATCH_OBJECT__ 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 * @typedef dispatch_object_t 31 * 32 * @abstract 33 * Abstract base type for all dispatch objects. 34 * The details of the type definition are language-specific. 35 * 36 * @discussion 37 * Dispatch objects are reference counted via calls to dispatch_retain() and 38 * dispatch_release(). 39 */ 40 41#if OS_OBJECT_USE_OBJC 42/* 43 * By default, dispatch objects are declared as Objective-C types when building 44 * with an Objective-C compiler. This allows them to participate in ARC, in RR 45 * management by the Blocks runtime and in leaks checking by the static 46 * analyzer, and enables them to be added to Cocoa collections. 47 * See <os/object.h> for details. 48 */ 49OS_OBJECT_DECL(dispatch_object); 50#define DISPATCH_DECL(name) OS_OBJECT_DECL_SUBCLASS(name, dispatch_object) 51#define DISPATCH_GLOBAL_OBJECT(type, object) ((OS_OBJECT_BRIDGE type)&(object)) 52#define DISPATCH_RETURNS_RETAINED OS_OBJECT_RETURNS_RETAINED 53DISPATCH_INLINE DISPATCH_ALWAYS_INLINE DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 54void 55_dispatch_object_validate(dispatch_object_t object) { 56 void *isa = *(void* volatile*)(OS_OBJECT_BRIDGE void*)object; 57 (void)isa; 58} 59#elif defined(__cplusplus) 60/* 61 * Dispatch objects are NOT C++ objects. Nevertheless, we can at least keep C++ 62 * aware of type compatibility. 63 */ 64typedef struct dispatch_object_s { 65private: 66 dispatch_object_s(); 67 ~dispatch_object_s(); 68 dispatch_object_s(const dispatch_object_s &); 69 void operator=(const dispatch_object_s &); 70} *dispatch_object_t; 71#define DISPATCH_DECL(name) \ 72 typedef struct name##_s : public dispatch_object_s {} *name##_t 73#define DISPATCH_GLOBAL_OBJECT(type, object) (&(object)) 74#define DISPATCH_RETURNS_RETAINED 75#else /* Plain C */ 76typedef union { 77 struct _os_object_s *_os_obj; 78 struct dispatch_object_s *_do; 79 struct dispatch_continuation_s *_dc; 80 struct dispatch_queue_s *_dq; 81 struct dispatch_queue_attr_s *_dqa; 82 struct dispatch_group_s *_dg; 83 struct dispatch_source_s *_ds; 84 struct dispatch_mach_s *_dm; 85 struct dispatch_mach_msg_s *_dmsg; 86 struct dispatch_timer_aggregate_s *_dta; 87 struct dispatch_source_attr_s *_dsa; 88 struct dispatch_semaphore_s *_dsema; 89 struct dispatch_data_s *_ddata; 90 struct dispatch_io_s *_dchannel; 91 struct dispatch_operation_s *_doperation; 92 struct dispatch_disk_s *_ddisk; 93} dispatch_object_t __attribute__((__transparent_union__)); 94/*! @parseOnly */ 95#define DISPATCH_DECL(name) typedef struct name##_s *name##_t 96/*! @parseOnly */ 97#define DISPATCH_GLOBAL_OBJECT(t, x) (&(x)) 98/*! @parseOnly */ 99#define DISPATCH_RETURNS_RETAINED 100#endif 101 102/*! 103 * @typedef dispatch_block_t 104 * 105 * @abstract 106 * The type of blocks submitted to dispatch queues, which take no arguments 107 * and have no return value. 108 * 109 * @discussion 110 * When not building with Objective-C ARC, a block object allocated on or 111 * copied to the heap must be released with a -[release] message or the 112 * Block_release() function. 113 * 114 * The declaration of a block literal allocates storage on the stack. 115 * Therefore, this is an invalid construct: 116 * <code> 117 * dispatch_block_t block; 118 * if (x) { 119 * block = ^{ printf("true\n"); }; 120 * } else { 121 * block = ^{ printf("false\n"); }; 122 * } 123 * block(); // unsafe!!! 124 * </code> 125 * 126 * What is happening behind the scenes: 127 * <code> 128 * if (x) { 129 * struct Block __tmp_1 = ...; // setup details 130 * block = &__tmp_1; 131 * } else { 132 * struct Block __tmp_2 = ...; // setup details 133 * block = &__tmp_2; 134 * } 135 * </code> 136 * 137 * As the example demonstrates, the address of a stack variable is escaping the 138 * scope in which it is allocated. That is a classic C bug. 139 * 140 * Instead, the block literal must be copied to the heap with the Block_copy() 141 * function or by sending it a -[copy] message. 142 */ 143typedef void (^dispatch_block_t)(void); 144 145__BEGIN_DECLS 146 147/*! 148 * @function dispatch_retain 149 * 150 * @abstract 151 * Increment the reference count of a dispatch object. 152 * 153 * @discussion 154 * Calls to dispatch_retain() must be balanced with calls to 155 * dispatch_release(). 156 * 157 * @param object 158 * The object to retain. 159 * The result of passing NULL in this parameter is undefined. 160 */ 161__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 162DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 163void 164dispatch_retain(dispatch_object_t object); 165#if OS_OBJECT_USE_OBJC_RETAIN_RELEASE 166#undef dispatch_retain 167#define dispatch_retain(object) ({ dispatch_object_t _o = (object); \ 168 _dispatch_object_validate(_o); (void)[_o retain]; }) 169#endif 170 171/*! 172 * @function dispatch_release 173 * 174 * @abstract 175 * Decrement the reference count of a dispatch object. 176 * 177 * @discussion 178 * A dispatch object is asynchronously deallocated once all references are 179 * released (i.e. the reference count becomes zero). The system does not 180 * guarantee that a given client is the last or only reference to a given 181 * object. 182 * 183 * @param object 184 * The object to release. 185 * The result of passing NULL in this parameter is undefined. 186 */ 187__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 188DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 189void 190dispatch_release(dispatch_object_t object); 191#if OS_OBJECT_USE_OBJC_RETAIN_RELEASE 192#undef dispatch_release 193#define dispatch_release(object) ({ dispatch_object_t _o = (object); \ 194 _dispatch_object_validate(_o); [_o release]; }) 195#endif 196 197/*! 198 * @function dispatch_get_context 199 * 200 * @abstract 201 * Returns the application defined context of the object. 202 * 203 * @param object 204 * The result of passing NULL in this parameter is undefined. 205 * 206 * @result 207 * The context of the object; may be NULL. 208 */ 209__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 210DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_PURE DISPATCH_WARN_RESULT 211DISPATCH_NOTHROW 212void * 213dispatch_get_context(dispatch_object_t object); 214 215/*! 216 * @function dispatch_set_context 217 * 218 * @abstract 219 * Associates an application defined context with the object. 220 * 221 * @param object 222 * The result of passing NULL in this parameter is undefined. 223 * 224 * @param context 225 * The new client defined context for the object. This may be NULL. 226 * 227 */ 228__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 229DISPATCH_EXPORT DISPATCH_NOTHROW //DISPATCH_NONNULL1 230void 231dispatch_set_context(dispatch_object_t object, void *context); 232 233/*! 234 * @function dispatch_set_finalizer_f 235 * 236 * @abstract 237 * Set the finalizer function for a dispatch object. 238 * 239 * @param object 240 * The dispatch object to modify. 241 * The result of passing NULL in this parameter is undefined. 242 * 243 * @param finalizer 244 * The finalizer function pointer. 245 * 246 * @discussion 247 * A dispatch object's finalizer will be invoked on the object's target queue 248 * after all references to the object have been released. This finalizer may be 249 * used by the application to release any resources associated with the object, 250 * such as freeing the object's context. 251 * The context parameter passed to the finalizer function is the current 252 * context of the dispatch object at the time the finalizer call is made. 253 */ 254__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 255DISPATCH_EXPORT DISPATCH_NOTHROW //DISPATCH_NONNULL1 256void 257dispatch_set_finalizer_f(dispatch_object_t object, 258 dispatch_function_t finalizer); 259 260/*! 261 * @function dispatch_suspend 262 * 263 * @abstract 264 * Suspends the invocation of blocks on a dispatch object. 265 * 266 * @discussion 267 * A suspended object will not invoke any blocks associated with it. The 268 * suspension of an object will occur after any running block associated with 269 * the object completes. 270 * 271 * Calls to dispatch_suspend() must be balanced with calls 272 * to dispatch_resume(). 273 * 274 * @param object 275 * The object to be suspended. 276 * The result of passing NULL in this parameter is undefined. 277 */ 278__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 279DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 280void 281dispatch_suspend(dispatch_object_t object); 282 283/*! 284 * @function dispatch_resume 285 * 286 * @abstract 287 * Resumes the invocation of blocks on a dispatch object. 288 * 289 * @param object 290 * The object to be resumed. 291 * The result of passing NULL in this parameter is undefined. 292 */ 293__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0) 294DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 295void 296dispatch_resume(dispatch_object_t object); 297 298/*! 299 * @function dispatch_wait 300 * 301 * @abstract 302 * Wait synchronously for an object or until the specified timeout has elapsed. 303 * 304 * @discussion 305 * Type-generic macro that maps to dispatch_block_wait, dispatch_group_wait or 306 * dispatch_semaphore_wait, depending on the type of the first argument. 307 * See documentation for these functions for more details. 308 * This function is unavailable for any other object type. 309 * 310 * @param object 311 * The object to wait on. 312 * The result of passing NULL in this parameter is undefined. 313 * 314 * @param timeout 315 * When to timeout (see dispatch_time). As a convenience, there are the 316 * DISPATCH_TIME_NOW and DISPATCH_TIME_FOREVER constants. 317 * 318 * @result 319 * Returns zero on success or non-zero on error (i.e. timed out). 320 */ 321DISPATCH_UNAVAILABLE 322DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW 323long 324dispatch_wait(void *object, dispatch_time_t timeout); 325#if __has_extension(c_generic_selections) 326#define dispatch_wait(object, timeout) \ 327 _Generic((object), \ 328 dispatch_block_t:dispatch_block_wait, \ 329 dispatch_group_t:dispatch_group_wait, \ 330 dispatch_semaphore_t:dispatch_semaphore_wait \ 331 )((object),(timeout)) 332#endif 333 334/*! 335 * @function dispatch_notify 336 * 337 * @abstract 338 * Schedule a notification block to be submitted to a queue when the execution 339 * of a specified object has completed. 340 * 341 * @discussion 342 * Type-generic macro that maps to dispatch_block_notify or 343 * dispatch_group_notify, depending on the type of the first argument. 344 * See documentation for these functions for more details. 345 * This function is unavailable for any other object type. 346 * 347 * @param object 348 * The object to observe. 349 * The result of passing NULL in this parameter is undefined. 350 * 351 * @param queue 352 * The queue to which the supplied notification block will be submitted when 353 * the observed object completes. 354 * 355 * @param notification_block 356 * The block to submit when the observed object completes. 357 */ 358DISPATCH_UNAVAILABLE 359DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 360void 361dispatch_notify(void *object, dispatch_object_t queue, 362 dispatch_block_t notification_block); 363#if __has_extension(c_generic_selections) 364#define dispatch_notify(object, queue, notification_block) \ 365 _Generic((object), \ 366 dispatch_block_t:dispatch_block_notify, \ 367 dispatch_group_t:dispatch_group_notify \ 368 )((object),(queue), (notification_block)) 369#endif 370 371/*! 372 * @function dispatch_cancel 373 * 374 * @abstract 375 * Cancel the specified object. 376 * 377 * @discussion 378 * Type-generic macro that maps to dispatch_block_cancel or 379 * dispatch_source_cancel, depending on the type of the first argument. 380 * See documentation for these functions for more details. 381 * This function is unavailable for any other object type. 382 * 383 * @param object 384 * The object to cancel. 385 * The result of passing NULL in this parameter is undefined. 386 */ 387DISPATCH_UNAVAILABLE 388DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW 389void 390dispatch_cancel(void *object); 391#if __has_extension(c_generic_selections) 392#define dispatch_cancel(object) \ 393 _Generic((object), \ 394 dispatch_block_t:dispatch_block_cancel, \ 395 dispatch_source_t:dispatch_source_cancel \ 396 )((object)) 397#endif 398 399/*! 400 * @function dispatch_testcancel 401 * 402 * @abstract 403 * Test whether the specified object has been canceled 404 * 405 * @discussion 406 * Type-generic macro that maps to dispatch_block_testcancel or 407 * dispatch_source_testcancel, depending on the type of the first argument. 408 * See documentation for these functions for more details. 409 * This function is unavailable for any other object type. 410 * 411 * @param object 412 * The object to test. 413 * The result of passing NULL in this parameter is undefined. 414 * 415 * @result 416 * Non-zero if canceled and zero if not canceled. 417 */ 418DISPATCH_UNAVAILABLE 419DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE 420DISPATCH_NOTHROW 421long 422dispatch_testcancel(void *object); 423#if __has_extension(c_generic_selections) 424#define dispatch_testcancel(object) \ 425 _Generic((object), \ 426 dispatch_block_t:dispatch_block_testcancel, \ 427 dispatch_source_t:dispatch_source_testcancel \ 428 )((object)) 429#endif 430 431/*! 432 * @function dispatch_debug 433 * 434 * @abstract 435 * Programmatically log debug information about a dispatch object. 436 * 437 * @discussion 438 * Programmatically log debug information about a dispatch object. By default, 439 * the log output is sent to syslog at notice level. In the debug version of 440 * the library, the log output is sent to a file in /var/tmp. 441 * The log output destination can be configured via the LIBDISPATCH_LOG 442 * environment variable, valid values are: YES, NO, syslog, stderr, file. 443 * 444 * This function is deprecated and will be removed in a future release. 445 * Objective-C callers may use -debugDescription instead. 446 * 447 * @param object 448 * The object to introspect. 449 * 450 * @param message 451 * The message to log above and beyond the introspection. 452 */ 453__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6,__MAC_10_9,__IPHONE_4_0,__IPHONE_6_0) 454DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NOTHROW 455__attribute__((__format__(printf,2,3))) 456void 457dispatch_debug(dispatch_object_t object, const char *message, ...); 458 459__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6,__MAC_10_9,__IPHONE_4_0,__IPHONE_6_0) 460DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NOTHROW 461__attribute__((__format__(printf,2,0))) 462void 463dispatch_debugv(dispatch_object_t object, const char *message, va_list ap); 464 465__END_DECLS 466 467#endif 468