]> git.saurik.com Git - apple/libdispatch.git/blob - dispatch/object.h
libdispatch-703.1.4.tar.gz
[apple/libdispatch.git] / dispatch / object.h
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 DISPATCH_ASSUME_NONNULL_BEGIN
30
31 /*!
32 * @typedef dispatch_object_t
33 *
34 * @abstract
35 * Abstract base type for all dispatch objects.
36 * The details of the type definition are language-specific.
37 *
38 * @discussion
39 * Dispatch objects are reference counted via calls to dispatch_retain() and
40 * dispatch_release().
41 */
42
43 #if OS_OBJECT_USE_OBJC
44 /*
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.
50 */
51 OS_OBJECT_DECL_CLASS(dispatch_object);
52
53 #if OS_OBJECT_SWIFT3
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)
57
58 DISPATCH_INLINE DISPATCH_ALWAYS_INLINE DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
59 void
60 _dispatch_object_validate(dispatch_object_t object) {
61 void *isa = *(void* volatile*)(OS_OBJECT_BRIDGE void*)object;
62 (void)isa;
63 }
64 #endif // OS_OBJECT_SWIFT3
65
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__)
69 /*
70 * Dispatch objects are NOT C++ objects. Nevertheless, we can at least keep C++
71 * aware of type compatibility.
72 */
73 typedef struct dispatch_object_s {
74 private:
75 dispatch_object_s();
76 ~dispatch_object_s();
77 dispatch_object_s(const dispatch_object_s &);
78 void operator=(const dispatch_object_s &);
79 } *dispatch_object_t;
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
84 #else /* Plain C */
85 typedef union {
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__));
103 /*! @parseOnly */
104 #define DISPATCH_DECL(name) typedef struct name##_s *name##_t
105 /*! @parseOnly */
106 #define DISPATCH_GLOBAL_OBJECT(t, x) (&(x))
107 /*! @parseOnly */
108 #define DISPATCH_RETURNS_RETAINED
109 #endif
110
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
126 /*! @parseOnly */
127 #define DISPATCH_SOURCE_DECL(name) \
128 DISPATCH_DECL(name);
129 /*! @parseOnly */
130 #define DISPATCH_DATA_DECL(name) DISPATCH_DECL(name)
131 /*! @parseOnly */
132 #define DISPATCH_SOURCE_TYPE_DECL(name) \
133 DISPATCH_EXPORT const struct dispatch_source_type_s \
134 _dispatch_source_type_##name
135 #else
136 #define DISPATCH_SOURCE_DECL(name) \
137 DISPATCH_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)
141 #endif
142
143 #ifdef __BLOCKS__
144 /*!
145 * @typedef dispatch_block_t
146 *
147 * @abstract
148 * The type of blocks submitted to dispatch queues, which take no arguments
149 * and have no return value.
150 *
151 * @discussion
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.
155 *
156 * The declaration of a block literal allocates storage on the stack.
157 * Therefore, this is an invalid construct:
158 * <code>
159 * dispatch_block_t block;
160 * if (x) {
161 * block = ^{ printf("true\n"); };
162 * } else {
163 * block = ^{ printf("false\n"); };
164 * }
165 * block(); // unsafe!!!
166 * </code>
167 *
168 * What is happening behind the scenes:
169 * <code>
170 * if (x) {
171 * struct Block __tmp_1 = ...; // setup details
172 * block = &__tmp_1;
173 * } else {
174 * struct Block __tmp_2 = ...; // setup details
175 * block = &__tmp_2;
176 * }
177 * </code>
178 *
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.
181 *
182 * Instead, the block literal must be copied to the heap with the Block_copy()
183 * function or by sending it a -[copy] message.
184 */
185 typedef void (^dispatch_block_t)(void);
186 #endif // __BLOCKS__
187
188 __BEGIN_DECLS
189
190 /*!
191 * @function dispatch_retain
192 *
193 * @abstract
194 * Increment the reference count of a dispatch object.
195 *
196 * @discussion
197 * Calls to dispatch_retain() must be balanced with calls to
198 * dispatch_release().
199 *
200 * @param object
201 * The object to retain.
202 * The result of passing NULL in this parameter is undefined.
203 */
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")
207 void
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]; })
214 #endif
215
216 /*!
217 * @function dispatch_release
218 *
219 * @abstract
220 * Decrement the reference count of a dispatch object.
221 *
222 * @discussion
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
226 * object.
227 *
228 * @param object
229 * The object to release.
230 * The result of passing NULL in this parameter is undefined.
231 */
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")
235 void
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]; })
242 #endif
243
244 /*!
245 * @function dispatch_get_context
246 *
247 * @abstract
248 * Returns the application defined context of the object.
249 *
250 * @param object
251 * The result of passing NULL in this parameter is undefined.
252 *
253 * @result
254 * The context of the object; may be NULL.
255 */
256 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
257 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_PURE DISPATCH_WARN_RESULT
258 DISPATCH_NOTHROW
259 void *_Nullable
260 dispatch_get_context(dispatch_object_t object);
261
262 /*!
263 * @function dispatch_set_context
264 *
265 * @abstract
266 * Associates an application defined context with the object.
267 *
268 * @param object
269 * The result of passing NULL in this parameter is undefined.
270 *
271 * @param context
272 * The new client defined context for the object. This may be NULL.
273 *
274 */
275 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
276 DISPATCH_EXPORT DISPATCH_NOTHROW
277 void
278 dispatch_set_context(dispatch_object_t object, void *_Nullable context);
279
280 /*!
281 * @function dispatch_set_finalizer_f
282 *
283 * @abstract
284 * Set the finalizer function for a dispatch object.
285 *
286 * @param object
287 * The dispatch object to modify.
288 * The result of passing NULL in this parameter is undefined.
289 *
290 * @param finalizer
291 * The finalizer function pointer.
292 *
293 * @discussion
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.
300 */
301 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
302 DISPATCH_EXPORT DISPATCH_NOTHROW
303 void
304 dispatch_set_finalizer_f(dispatch_object_t object,
305 dispatch_function_t _Nullable finalizer);
306
307 /*!
308 * @function dispatch_activate
309 *
310 * @abstract
311 * Activates the specified dispatch object.
312 *
313 * @discussion
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.
317 *
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.
321 *
322 * Calling dispatch_activate() on an active object has no effect.
323 * Releasing the last reference count on an inactive object is undefined.
324 *
325 * @param object
326 * The object to be activated.
327 * The result of passing NULL in this parameter is undefined.
328 */
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
332 void
333 dispatch_activate(dispatch_object_t object);
334
335 /*!
336 * @function dispatch_suspend
337 *
338 * @abstract
339 * Suspends the invocation of blocks on a dispatch object.
340 *
341 * @discussion
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.
345 *
346 * Calls to dispatch_suspend() must be balanced with calls
347 * to dispatch_resume().
348 *
349 * @param object
350 * The object to be suspended.
351 * The result of passing NULL in this parameter is undefined.
352 */
353 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
354 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
355 void
356 dispatch_suspend(dispatch_object_t object);
357
358 /*!
359 * @function dispatch_resume
360 *
361 * @abstract
362 * Resumes the invocation of blocks on a dispatch object.
363 *
364 * @discussion
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.
369 *
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.
373 *
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
376 * terminated.
377 *
378 * @param object
379 * The object to be resumed.
380 * The result of passing NULL in this parameter is undefined.
381 */
382 __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
383 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
384 void
385 dispatch_resume(dispatch_object_t object);
386
387 #ifdef __BLOCKS__
388 /*!
389 * @function dispatch_wait
390 *
391 * @abstract
392 * Wait synchronously for an object or until the specified timeout has elapsed.
393 *
394 * @discussion
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.
399 *
400 * @param object
401 * The object to wait on.
402 * The result of passing NULL in this parameter is undefined.
403 *
404 * @param timeout
405 * When to timeout (see dispatch_time). As a convenience, there are the
406 * DISPATCH_TIME_NOW and DISPATCH_TIME_FOREVER constants.
407 *
408 * @result
409 * Returns zero on success or non-zero on error (i.e. timed out).
410 */
411 DISPATCH_UNAVAILABLE
412 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
413 long
414 dispatch_wait(void *object, dispatch_time_t timeout);
415 #if __has_extension(c_generic_selections)
416 #define dispatch_wait(object, timeout) \
417 _Generic((object), \
418 dispatch_block_t:dispatch_block_wait, \
419 dispatch_group_t:dispatch_group_wait, \
420 dispatch_semaphore_t:dispatch_semaphore_wait \
421 )((object),(timeout))
422 #endif
423
424 /*!
425 * @function dispatch_notify
426 *
427 * @abstract
428 * Schedule a notification block to be submitted to a queue when the execution
429 * of a specified object has completed.
430 *
431 * @discussion
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.
436 *
437 * @param object
438 * The object to observe.
439 * The result of passing NULL in this parameter is undefined.
440 *
441 * @param queue
442 * The queue to which the supplied notification block will be submitted when
443 * the observed object completes.
444 *
445 * @param notification_block
446 * The block to submit when the observed object completes.
447 */
448 DISPATCH_UNAVAILABLE
449 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
450 void
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) \
455 _Generic((object), \
456 dispatch_block_t:dispatch_block_notify, \
457 dispatch_group_t:dispatch_group_notify \
458 )((object),(queue), (notification_block))
459 #endif
460
461 /*!
462 * @function dispatch_cancel
463 *
464 * @abstract
465 * Cancel the specified object.
466 *
467 * @discussion
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.
472 *
473 * @param object
474 * The object to cancel.
475 * The result of passing NULL in this parameter is undefined.
476 */
477 DISPATCH_UNAVAILABLE
478 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
479 void
480 dispatch_cancel(void *object);
481 #if __has_extension(c_generic_selections)
482 #define dispatch_cancel(object) \
483 _Generic((object), \
484 dispatch_block_t:dispatch_block_cancel, \
485 dispatch_source_t:dispatch_source_cancel \
486 )((object))
487 #endif
488
489 /*!
490 * @function dispatch_testcancel
491 *
492 * @abstract
493 * Test whether the specified object has been canceled
494 *
495 * @discussion
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.
500 *
501 * @param object
502 * The object to test.
503 * The result of passing NULL in this parameter is undefined.
504 *
505 * @result
506 * Non-zero if canceled and zero if not canceled.
507 */
508 DISPATCH_UNAVAILABLE
509 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE
510 DISPATCH_NOTHROW
511 long
512 dispatch_testcancel(void *object);
513 #if __has_extension(c_generic_selections)
514 #define dispatch_testcancel(object) \
515 _Generic((object), \
516 dispatch_block_t:dispatch_block_testcancel, \
517 dispatch_source_t:dispatch_source_testcancel \
518 )((object))
519 #endif
520 #endif // __BLOCKS__
521
522 /*!
523 * @function dispatch_debug
524 *
525 * @abstract
526 * Programmatically log debug information about a dispatch object.
527 *
528 * @discussion
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.
534 *
535 * This function is deprecated and will be removed in a future release.
536 * Objective-C callers may use -debugDescription instead.
537 *
538 * @param object
539 * The object to introspect.
540 *
541 * @param message
542 * The message to log above and beyond the introspection.
543 */
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)))
547 void
548 dispatch_debug(dispatch_object_t object, const char *message, ...);
549
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)))
553 void
554 dispatch_debugv(dispatch_object_t object, const char *message, va_list ap);
555
556 __END_DECLS
557
558 DISPATCH_ASSUME_NONNULL_END
559
560 #endif