]> git.saurik.com Git - apple/libdispatch.git/blob - dispatch/object.h
libdispatch-913.30.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_source_attr_s *_dsa;
96 struct dispatch_semaphore_s *_dsema;
97 struct dispatch_data_s *_ddata;
98 struct dispatch_io_s *_dchannel;
99 struct dispatch_operation_s *_doperation;
100 struct dispatch_disk_s *_ddisk;
101 } dispatch_object_t DISPATCH_TRANSPARENT_UNION;
102 /*! @parseOnly */
103 #define DISPATCH_DECL(name) typedef struct name##_s *name##_t
104 /*! @parseOnly */
105 #define DISPATCH_GLOBAL_OBJECT(t, x) (&(x))
106 /*! @parseOnly */
107 #define DISPATCH_RETURNS_RETAINED
108 #endif
109
110 #if OS_OBJECT_SWIFT3 && OS_OBJECT_USE_OBJC
111 #define DISPATCH_SOURCE_TYPE_DECL(name) \
112 DISPATCH_EXPORT struct dispatch_source_type_s \
113 _dispatch_source_type_##name; \
114 OS_OBJECT_DECL_PROTOCOL(dispatch_source_##name, <OS_dispatch_source>); \
115 OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL( \
116 dispatch_source, dispatch_source_##name)
117 #define DISPATCH_SOURCE_DECL(name) \
118 DISPATCH_DECL(name); \
119 OS_OBJECT_DECL_PROTOCOL(name, <NSObject>); \
120 OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL(name, name)
121 #ifndef DISPATCH_DATA_DECL
122 #define DISPATCH_DATA_DECL(name) OS_OBJECT_DECL_SWIFT(name)
123 #endif // DISPATCH_DATA_DECL
124 #elif !TARGET_OS_WIN32
125 /*! @parseOnly */
126 #define DISPATCH_SOURCE_DECL(name) \
127 DISPATCH_DECL(name);
128 /*! @parseOnly */
129 #define DISPATCH_DATA_DECL(name) DISPATCH_DECL(name)
130 /*! @parseOnly */
131 #define DISPATCH_SOURCE_TYPE_DECL(name) \
132 DISPATCH_EXPORT const struct dispatch_source_type_s \
133 _dispatch_source_type_##name
134 #else
135 #define DISPATCH_SOURCE_DECL(name) \
136 DISPATCH_DECL(name);
137 #define DISPATCH_SOURCE_TYPE_DECL(name) \
138 DISPATCH_EXPORT struct dispatch_source_type_s _dispatch_source_type_##name
139 #define DISPATCH_DATA_DECL(name) DISPATCH_DECL(name)
140 #endif
141
142 #ifdef __BLOCKS__
143 /*!
144 * @typedef dispatch_block_t
145 *
146 * @abstract
147 * The type of blocks submitted to dispatch queues, which take no arguments
148 * and have no return value.
149 *
150 * @discussion
151 * When not building with Objective-C ARC, a block object allocated on or
152 * copied to the heap must be released with a -[release] message or the
153 * Block_release() function.
154 *
155 * The declaration of a block literal allocates storage on the stack.
156 * Therefore, this is an invalid construct:
157 * <code>
158 * dispatch_block_t block;
159 * if (x) {
160 * block = ^{ printf("true\n"); };
161 * } else {
162 * block = ^{ printf("false\n"); };
163 * }
164 * block(); // unsafe!!!
165 * </code>
166 *
167 * What is happening behind the scenes:
168 * <code>
169 * if (x) {
170 * struct Block __tmp_1 = ...; // setup details
171 * block = &__tmp_1;
172 * } else {
173 * struct Block __tmp_2 = ...; // setup details
174 * block = &__tmp_2;
175 * }
176 * </code>
177 *
178 * As the example demonstrates, the address of a stack variable is escaping the
179 * scope in which it is allocated. That is a classic C bug.
180 *
181 * Instead, the block literal must be copied to the heap with the Block_copy()
182 * function or by sending it a -[copy] message.
183 */
184 typedef void (^dispatch_block_t)(void);
185 #endif // __BLOCKS__
186
187 __BEGIN_DECLS
188
189 /*!
190 * @function dispatch_retain
191 *
192 * @abstract
193 * Increment the reference count of a dispatch object.
194 *
195 * @discussion
196 * Calls to dispatch_retain() must be balanced with calls to
197 * dispatch_release().
198 *
199 * @param object
200 * The object to retain.
201 * The result of passing NULL in this parameter is undefined.
202 */
203 API_AVAILABLE(macos(10.6), ios(4.0))
204 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
205 DISPATCH_SWIFT_UNAVAILABLE("Can't be used with ARC")
206 void
207 dispatch_retain(dispatch_object_t object);
208 #if OS_OBJECT_USE_OBJC_RETAIN_RELEASE
209 #undef dispatch_retain
210 #define dispatch_retain(object) \
211 __extension__({ dispatch_object_t _o = (object); \
212 _dispatch_object_validate(_o); (void)[_o retain]; })
213 #endif
214
215 /*!
216 * @function dispatch_release
217 *
218 * @abstract
219 * Decrement the reference count of a dispatch object.
220 *
221 * @discussion
222 * A dispatch object is asynchronously deallocated once all references are
223 * released (i.e. the reference count becomes zero). The system does not
224 * guarantee that a given client is the last or only reference to a given
225 * object.
226 *
227 * @param object
228 * The object to release.
229 * The result of passing NULL in this parameter is undefined.
230 */
231 API_AVAILABLE(macos(10.6), ios(4.0))
232 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
233 DISPATCH_SWIFT_UNAVAILABLE("Can't be used with ARC")
234 void
235 dispatch_release(dispatch_object_t object);
236 #if OS_OBJECT_USE_OBJC_RETAIN_RELEASE
237 #undef dispatch_release
238 #define dispatch_release(object) \
239 __extension__({ dispatch_object_t _o = (object); \
240 _dispatch_object_validate(_o); [_o release]; })
241 #endif
242
243 /*!
244 * @function dispatch_get_context
245 *
246 * @abstract
247 * Returns the application defined context of the object.
248 *
249 * @param object
250 * The result of passing NULL in this parameter is undefined.
251 *
252 * @result
253 * The context of the object; may be NULL.
254 */
255 API_AVAILABLE(macos(10.6), ios(4.0))
256 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_PURE DISPATCH_WARN_RESULT
257 DISPATCH_NOTHROW
258 void *_Nullable
259 dispatch_get_context(dispatch_object_t object);
260
261 /*!
262 * @function dispatch_set_context
263 *
264 * @abstract
265 * Associates an application defined context with the object.
266 *
267 * @param object
268 * The result of passing NULL in this parameter is undefined.
269 *
270 * @param context
271 * The new client defined context for the object. This may be NULL.
272 *
273 */
274 API_AVAILABLE(macos(10.6), ios(4.0))
275 DISPATCH_EXPORT DISPATCH_NOTHROW
276 void
277 dispatch_set_context(dispatch_object_t object, void *_Nullable context);
278
279 /*!
280 * @function dispatch_set_finalizer_f
281 *
282 * @abstract
283 * Set the finalizer function for a dispatch object.
284 *
285 * @param object
286 * The dispatch object to modify.
287 * The result of passing NULL in this parameter is undefined.
288 *
289 * @param finalizer
290 * The finalizer function pointer.
291 *
292 * @discussion
293 * A dispatch object's finalizer will be invoked on the object's target queue
294 * after all references to the object have been released. This finalizer may be
295 * used by the application to release any resources associated with the object,
296 * such as freeing the object's context.
297 * The context parameter passed to the finalizer function is the current
298 * context of the dispatch object at the time the finalizer call is made.
299 */
300 API_AVAILABLE(macos(10.6), ios(4.0))
301 DISPATCH_EXPORT DISPATCH_NOTHROW
302 void
303 dispatch_set_finalizer_f(dispatch_object_t object,
304 dispatch_function_t _Nullable finalizer);
305
306 /*!
307 * @function dispatch_activate
308 *
309 * @abstract
310 * Activates the specified dispatch object.
311 *
312 * @discussion
313 * Dispatch objects such as queues and sources may be created in an inactive
314 * state. Objects in this state have to be activated before any blocks
315 * associated with them will be invoked.
316 *
317 * The target queue of inactive objects can be changed using
318 * dispatch_set_target_queue(). Change of target queue is no longer permitted
319 * once an initially inactive object has been activated.
320 *
321 * Calling dispatch_activate() on an active object has no effect.
322 * Releasing the last reference count on an inactive object is undefined.
323 *
324 * @param object
325 * The object to be activated.
326 * The result of passing NULL in this parameter is undefined.
327 */
328 API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
329 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
330 void
331 dispatch_activate(dispatch_object_t object);
332
333 /*!
334 * @function dispatch_suspend
335 *
336 * @abstract
337 * Suspends the invocation of blocks on a dispatch object.
338 *
339 * @discussion
340 * A suspended object will not invoke any blocks associated with it. The
341 * suspension of an object will occur after any running block associated with
342 * the object completes.
343 *
344 * Calls to dispatch_suspend() must be balanced with calls
345 * to dispatch_resume().
346 *
347 * @param object
348 * The object to be suspended.
349 * The result of passing NULL in this parameter is undefined.
350 */
351 API_AVAILABLE(macos(10.6), ios(4.0))
352 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
353 void
354 dispatch_suspend(dispatch_object_t object);
355
356 /*!
357 * @function dispatch_resume
358 *
359 * @abstract
360 * Resumes the invocation of blocks on a dispatch object.
361 *
362 * @discussion
363 * Dispatch objects can be suspended with dispatch_suspend(), which increments
364 * an internal suspension count. dispatch_resume() is the inverse operation,
365 * and consumes suspension counts. When the last suspension count is consumed,
366 * blocks associated with the object will be invoked again.
367 *
368 * For backward compatibility reasons, dispatch_resume() on an inactive and not
369 * otherwise suspended dispatch source object has the same effect as calling
370 * dispatch_activate(). For new code, using dispatch_activate() is preferred.
371 *
372 * If the specified object has zero suspension count and is not an inactive
373 * source, this function will result in an assertion and the process being
374 * terminated.
375 *
376 * @param object
377 * The object to be resumed.
378 * The result of passing NULL in this parameter is undefined.
379 */
380 API_AVAILABLE(macos(10.6), ios(4.0))
381 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
382 void
383 dispatch_resume(dispatch_object_t object);
384
385 #ifdef __BLOCKS__
386 /*!
387 * @function dispatch_wait
388 *
389 * @abstract
390 * Wait synchronously for an object or until the specified timeout has elapsed.
391 *
392 * @discussion
393 * Type-generic macro that maps to dispatch_block_wait, dispatch_group_wait or
394 * dispatch_semaphore_wait, depending on the type of the first argument.
395 * See documentation for these functions for more details.
396 * This function is unavailable for any other object type.
397 *
398 * @param object
399 * The object to wait on.
400 * The result of passing NULL in this parameter is undefined.
401 *
402 * @param timeout
403 * When to timeout (see dispatch_time). As a convenience, there are the
404 * DISPATCH_TIME_NOW and DISPATCH_TIME_FOREVER constants.
405 *
406 * @result
407 * Returns zero on success or non-zero on error (i.e. timed out).
408 */
409 DISPATCH_UNAVAILABLE
410 DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
411 long
412 dispatch_wait(void *object, dispatch_time_t timeout);
413 #if __has_extension(c_generic_selections)
414 #define dispatch_wait(object, timeout) \
415 _Generic((object), \
416 dispatch_block_t:dispatch_block_wait, \
417 dispatch_group_t:dispatch_group_wait, \
418 dispatch_semaphore_t:dispatch_semaphore_wait \
419 )((object),(timeout))
420 #endif
421
422 /*!
423 * @function dispatch_notify
424 *
425 * @abstract
426 * Schedule a notification block to be submitted to a queue when the execution
427 * of a specified object has completed.
428 *
429 * @discussion
430 * Type-generic macro that maps to dispatch_block_notify or
431 * dispatch_group_notify, depending on the type of the first argument.
432 * See documentation for these functions for more details.
433 * This function is unavailable for any other object type.
434 *
435 * @param object
436 * The object to observe.
437 * The result of passing NULL in this parameter is undefined.
438 *
439 * @param queue
440 * The queue to which the supplied notification block will be submitted when
441 * the observed object completes.
442 *
443 * @param notification_block
444 * The block to submit when the observed object completes.
445 */
446 DISPATCH_UNAVAILABLE
447 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
448 void
449 dispatch_notify(void *object, dispatch_object_t queue,
450 dispatch_block_t notification_block);
451 #if __has_extension(c_generic_selections)
452 #define dispatch_notify(object, queue, notification_block) \
453 _Generic((object), \
454 dispatch_block_t:dispatch_block_notify, \
455 dispatch_group_t:dispatch_group_notify \
456 )((object),(queue), (notification_block))
457 #endif
458
459 /*!
460 * @function dispatch_cancel
461 *
462 * @abstract
463 * Cancel the specified object.
464 *
465 * @discussion
466 * Type-generic macro that maps to dispatch_block_cancel or
467 * dispatch_source_cancel, depending on the type of the first argument.
468 * See documentation for these functions for more details.
469 * This function is unavailable for any other object type.
470 *
471 * @param object
472 * The object to cancel.
473 * The result of passing NULL in this parameter is undefined.
474 */
475 DISPATCH_UNAVAILABLE
476 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
477 void
478 dispatch_cancel(void *object);
479 #if __has_extension(c_generic_selections)
480 #define dispatch_cancel(object) \
481 _Generic((object), \
482 dispatch_block_t:dispatch_block_cancel, \
483 dispatch_source_t:dispatch_source_cancel \
484 )((object))
485 #endif
486
487 /*!
488 * @function dispatch_testcancel
489 *
490 * @abstract
491 * Test whether the specified object has been canceled
492 *
493 * @discussion
494 * Type-generic macro that maps to dispatch_block_testcancel or
495 * dispatch_source_testcancel, depending on the type of the first argument.
496 * See documentation for these functions for more details.
497 * This function is unavailable for any other object type.
498 *
499 * @param object
500 * The object to test.
501 * The result of passing NULL in this parameter is undefined.
502 *
503 * @result
504 * Non-zero if canceled and zero if not canceled.
505 */
506 DISPATCH_UNAVAILABLE
507 DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE
508 DISPATCH_NOTHROW
509 long
510 dispatch_testcancel(void *object);
511 #if __has_extension(c_generic_selections)
512 #define dispatch_testcancel(object) \
513 _Generic((object), \
514 dispatch_block_t:dispatch_block_testcancel, \
515 dispatch_source_t:dispatch_source_testcancel \
516 )((object))
517 #endif
518 #endif // __BLOCKS__
519
520 /*!
521 * @function dispatch_debug
522 *
523 * @abstract
524 * Programmatically log debug information about a dispatch object.
525 *
526 * @discussion
527 * Programmatically log debug information about a dispatch object. By default,
528 * the log output is sent to syslog at notice level. In the debug version of
529 * the library, the log output is sent to a file in /var/tmp.
530 * The log output destination can be configured via the LIBDISPATCH_LOG
531 * environment variable, valid values are: YES, NO, syslog, stderr, file.
532 *
533 * This function is deprecated and will be removed in a future release.
534 * Objective-C callers may use -debugDescription instead.
535 *
536 * @param object
537 * The object to introspect.
538 *
539 * @param message
540 * The message to log above and beyond the introspection.
541 */
542 API_DEPRECATED("unsupported interface", macos(10.6,10.9), ios(4.0,6.0))
543 DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NOTHROW
544 __attribute__((__format__(printf,2,3)))
545 void
546 dispatch_debug(dispatch_object_t object, const char *message, ...);
547
548 API_DEPRECATED("unsupported interface", macos(10.6,10.9), ios(4.0,6.0))
549 DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NOTHROW
550 __attribute__((__format__(printf,2,0)))
551 void
552 dispatch_debugv(dispatch_object_t object, const char *message, va_list ap);
553
554 __END_DECLS
555
556 DISPATCH_ASSUME_NONNULL_END
557
558 #endif