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#if __has_include(<sys/qos.h>)
 30#include <sys/qos.h>
 31#endif
 32
 33DISPATCH_ASSUME_NONNULL_BEGIN
 34DISPATCH_ASSUME_ABI_SINGLE_BEGIN
 35
 36/*!
 37 * @typedef dispatch_object_t
 38 *
 39 * @abstract
 40 * Abstract base type for all dispatch objects.
 41 * The details of the type definition are language-specific.
 42 *
 43 * @discussion
 44 * Dispatch objects are reference counted via calls to dispatch_retain() and
 45 * dispatch_release().
 46 */
 47
 48#if OS_OBJECT_USE_OBJC
 49/*
 50 * By default, dispatch objects are declared as Objective-C types when building
 51 * with an Objective-C compiler. This allows them to participate in ARC, in RR
 52 * management by the Blocks runtime and in leaks checking by the static
 53 * analyzer, and enables them to be added to Cocoa collections.
 54 * See <os/object.h> for details.
 55 */
 56DISPATCH_SWIFT_NAME(DispatchObject) OS_OBJECT_DECL_CLASS(dispatch_object);
 57
 58#if OS_OBJECT_SWIFT3
 59#define DISPATCH_DECL(name) OS_OBJECT_DECL_SENDABLE_SUBCLASS_SWIFT(name, dispatch_object)
 60#define DISPATCH_DECL_SUBCLASS(name, base) OS_OBJECT_DECL_SENDABLE_SUBCLASS_SWIFT(name, base)
 61/*
 62 * DISPATCH_DECL_FACTORY_CLASS_SWIFT adopts _hasMissingDesignatedInitializers swift attribute.
 63 * That makes subclasses of this class stop inheriting its initializers.
 64 */
 65#define DISPATCH_DECL_FACTORY_CLASS_SWIFT(name, swift_name) \
 66		OS_OBJECT_SWIFT_HAS_MISSING_DESIGNATED_INIT DISPATCH_DECL_SWIFT(name, swift_name)
 67#define DISPATCH_DECL_SWIFT(name, swift_name) DISPATCH_SWIFT_NAME(swift_name) DISPATCH_DECL(name)
 68#define DISPATCH_DECL_SUBCLASS_SWIFT(name, base, swift_name) \
 69		DISPATCH_SWIFT_NAME(swift_name) DISPATCH_DECL_SUBCLASS(name, base)
 70
 71/*
 72 * DISPATCH_DECL_SERIAL_EXECUTOR_SWIFT is for declaring subclasses of a serial executor base class. 
 73 */
 74#if DISPATCH_OSX_SUPPORTS_AT_LEAST(140000, 170000, 170000, 100000, 90400, 10000)
 75#define DISPATCH_DECL_SERIAL_EXECUTOR_SWIFT(name, swift_name) \
 76	DISPATCH_DECL_SUBCLASS_SWIFT(name, dispatch_queue_serial_executor, swift_name)
 77#else
 78#define DISPATCH_DECL_SERIAL_EXECUTOR_SWIFT(name, swift_name) \
 79	DISPATCH_DECL_SUBCLASS_SWIFT(name, dispatch_queue, swift_name)
 80#endif
 81
 82#else // OS_OBJECT_SWIFT3
 83#define DISPATCH_DECL(name) OS_OBJECT_DECL_SUBCLASS(name, dispatch_object)
 84#define DISPATCH_DECL_SUBCLASS(name, base) OS_OBJECT_DECL_SUBCLASS(name, base)
 85#define DISPATCH_DECL_FACTORY_CLASS_SWIFT(name, swift_name) DISPATCH_DECL_SWIFT(name, swift_name)
 86#define DISPATCH_DECL_SWIFT(name, swift_name) DISPATCH_DECL(name)
 87#define DISPATCH_DECL_SUBCLASS_SWIFT(name, base, swift_name) DISPATCH_DECL_SUBCLASS(name, base)
 88#define DISPATCH_DECL_SERIAL_EXECUTOR_SWIFT(name, swift_name) \
 89		DISPATCH_DECL_SUBCLASS_SWIFT(name, dispatch_queue, swift_name)
 90DISPATCH_INLINE DISPATCH_ALWAYS_INLINE DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
 91DISPATCH_SWIFT_UNAVAILABLE("Unavailable in Swift")
 92void
 93_dispatch_object_validate(dispatch_object_t object)
 94{
 95	void *isa = *(void *volatile*)(OS_OBJECT_BRIDGE void*)object;
 96	(void)isa;
 97}
 98#endif // OS_OBJECT_SWIFT3
 99
100#define DISPATCH_GLOBAL_OBJECT(type, object) ((OS_OBJECT_BRIDGE type)&(object))
101#define DISPATCH_RETURNS_RETAINED OS_OBJECT_RETURNS_RETAINED
102#elif defined(__cplusplus) && !defined(__DISPATCH_BUILDING_DISPATCH__)
103/*
104 * Dispatch objects are NOT C++ objects. Nevertheless, we can at least keep C++
105 * aware of type compatibility.
106 */
107typedef struct dispatch_object_s {
108private:
109	dispatch_object_s();
110	~dispatch_object_s();
111	dispatch_object_s(const dispatch_object_s &);
112	void operator=(const dispatch_object_s &);
113} *dispatch_object_t;
114#define DISPATCH_DECL(name) \
115		typedef struct name##_s : public dispatch_object_s {} *name##_t
116#define DISPATCH_DECL_SUBCLASS(name, base) \
117		typedef struct name##_s : public base##_s {} *name##_t
118#define DISPATCH_DECL_FACTORY_CLASS_SWIFT(name, swift_name) DISPATCH_DECL_SWIFT(name, swift_name)
119#define DISPATCH_DECL_SWIFT(name, swift_name) DISPATCH_DECL(name)
120#define DISPATCH_DECL_SUBCLASS_SWIFT(name, base, swift_name) DISPATCH_DECL_SUBCLASS(name, base)
121#define DISPATCH_DECL_SERIAL_EXECUTOR_SWIFT(name, swift_name) \
122		DISPATCH_DECL_SUBCLASS_SWIFT(name, dispatch_queue, swift_name)
123#define DISPATCH_GLOBAL_OBJECT(type, object) (static_cast<type>(&(object)))
124#define DISPATCH_RETURNS_RETAINED
125#else /* Plain C */
126typedef union {
127	struct _os_object_s *_os_obj;
128	struct dispatch_object_s *_do;
129	struct dispatch_queue_s *_dq;
130	struct dispatch_queue_attr_s *_dqa;
131	struct dispatch_group_s *_dg;
132	struct dispatch_source_s *_ds;
133	struct dispatch_channel_s *_dch;
134	struct dispatch_mach_s *_dm;
135	struct dispatch_mach_msg_s *_dmsg;
136	struct dispatch_semaphore_s *_dsema;
137	struct dispatch_data_s *_ddata;
138	struct dispatch_io_s *_dchannel;
139} dispatch_object_t DISPATCH_TRANSPARENT_UNION;
140#define DISPATCH_DECL(name) typedef struct name##_s *name##_t
141#define DISPATCH_DECL_SUBCLASS(name, base) typedef base##_t name##_t
142#define DISPATCH_DECL_FACTORY_CLASS_SWIFT(name, swift_name) DISPATCH_DECL_SWIFT(name, swift_name)
143#define DISPATCH_DECL_SWIFT(name, swift_name) DISPATCH_DECL(name)
144#define DISPATCH_DECL_SUBCLASS_SWIFT(name, base, swift_name) DISPATCH_DECL_SUBCLASS(name, base)
145#define DISPATCH_DECL_SERIAL_EXECUTOR_SWIFT(name, swift_name) \
146		DISPATCH_DECL_SUBCLASS_SWIFT(name, dispatch_queue, swift_name)
147#define DISPATCH_GLOBAL_OBJECT(type, object) ((type)&(object))
148#define DISPATCH_RETURNS_RETAINED
149#endif
150
151#if OS_OBJECT_SWIFT3 && OS_OBJECT_USE_OBJC
152#define DISPATCH_SOURCE_TYPE_DECL(name) \
153		DISPATCH_EXPORT struct dispatch_source_type_s \
154				_dispatch_source_type_##name; \
155		OS_OBJECT_DECL_PROTOCOL(dispatch_source_##name, <OS_dispatch_source>); \
156		OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL( \
157				dispatch_source, dispatch_source_##name)
158#define DISPATCH_SOURCE_TYPE_DECL_SWIFT(name, swift_name) \
159		DISPATCH_EXPORT struct dispatch_source_type_s \
160				_dispatch_source_type_##name; \
161		DISPATCH_SWIFT_NAME(swift_name) \
162		OS_OBJECT_SWIFT_SENDABLE \
163		OS_OBJECT_DECL_PROTOCOL(dispatch_source_##name, <OS_dispatch_source>); \
164		OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL( \
165				dispatch_source, dispatch_source_##name)
166#define DISPATCH_SOURCE_DECL(name) \
167		DISPATCH_DECL(name); \
168		OS_OBJECT_DECL_PROTOCOL(name, <NSObject>); \
169		OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL(name, name)
170#define DISPATCH_SOURCE_DECL_SWIFT(name, swift_name, protocol_name) \
171		DISPATCH_SWIFT_NAME(swift_name) \
172		DISPATCH_DECL(name); \
173		DISPATCH_SWIFT_NAME(protocol_name) \
174		OS_OBJECT_DECL_PROTOCOL(name, <NSObject>); \
175		OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL(name, name)
176#ifndef DISPATCH_DATA_DECL
177#define DISPATCH_DATA_DECL(name) OS_OBJECT_DECL_SENDABLE_SWIFT(name)
178#endif // DISPATCH_DATA_DECL
179#define DISPATCH_DATA_DECL_SWIFT(name, swift_name) \
180		DISPATCH_SWIFT_NAME(swift_name) \
181		DISPATCH_DATA_DECL(name)
182#else
183#define DISPATCH_SOURCE_DECL(name) \
184		DISPATCH_DECL(name);
185#define DISPATCH_SOURCE_DECL_SWIFT(name, swift_name, protocol_name) DISPATCH_SOURCE_DECL(name)
186#define DISPATCH_DATA_DECL(name) DISPATCH_DECL(name)
187#define DISPATCH_DATA_DECL_SWIFT(name, swift_name) DISPATCH_DATA_DECL(name)
188#define DISPATCH_SOURCE_TYPE_DECL(name) \
189		DISPATCH_EXPORT const struct dispatch_source_type_s \
190		_dispatch_source_type_##name
191#define DISPATCH_SOURCE_TYPE_DECL_SWIFT(name, swift_name) \
192		DISPATCH_SOURCE_TYPE_DECL(name)
193#endif
194
195#ifdef __BLOCKS__
196/*!
197 * @typedef dispatch_block_t
198 *
199 * @abstract
200 * The type of blocks submitted to dispatch queues, which take no arguments
201 * and have no return value.
202 *
203 * @discussion
204 * When not building with Objective-C ARC, a block object allocated on or
205 * copied to the heap must be released with a -[release] message or the
206 * Block_release() function.
207 *
208 * The declaration of a block literal allocates storage on the stack.
209 * Therefore, this is an invalid construct:
210 * <code>
211 * dispatch_block_t block;
212 * if (x) {
213 *     block = ^{ printf("true\n"); };
214 * } else {
215 *     block = ^{ printf("false\n"); };
216 * }
217 * block(); // unsafe!!!
218 * </code>
219 *
220 * What is happening behind the scenes:
221 * <code>
222 * if (x) {
223 *     struct Block __tmp_1 = ...; // setup details
224 *     block = &__tmp_1;
225 * } else {
226 *     struct Block __tmp_2 = ...; // setup details
227 *     block = &__tmp_2;
228 * }
229 * </code>
230 *
231 * As the example demonstrates, the address of a stack variable is escaping the
232 * scope in which it is allocated. That is a classic C bug.
233 *
234 * Instead, the block literal must be copied to the heap with the Block_copy()
235 * function or by sending it a -[copy] message.
236 */
237DISPATCH_SWIFT_UNAVAILABLE("Unavailable in Swift")
238typedef void (^dispatch_block_t)(void);
239#endif // __BLOCKS__
240
241__BEGIN_DECLS
242
243/*!
244 * @typedef dispatch_qos_class_t
245 * Alias for qos_class_t type.
246 */
247DISPATCH_SWIFT_UNAVAILABLE("Use DispatchQoS")
248#if __has_include(<sys/qos.h>)
249typedef qos_class_t dispatch_qos_class_t;
250#else
251typedef unsigned int dispatch_qos_class_t;
252#endif
253
254/*!
255 * @function dispatch_retain
256 *
257 * @abstract
258 * Increment the reference count of a dispatch object.
259 *
260 * @discussion
261 * Calls to dispatch_retain() must be balanced with calls to
262 * dispatch_release().
263 *
264 * @param object
265 * The object to retain.
266 * The result of passing NULL in this parameter is undefined.
267 */
268API_AVAILABLE(macos(10.6), ios(4.0))
269DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
270DISPATCH_SWIFT_UNAVAILABLE("Can't be used with ARC")
271void
272dispatch_retain(dispatch_object_t object);
273#if OS_OBJECT_USE_OBJC_RETAIN_RELEASE
274#undef dispatch_retain
275#define dispatch_retain(object) \
276		__extension__({ dispatch_object_t _o = (object); \
277		_dispatch_object_validate(_o); (void)[_o retain]; })
278#endif
279
280/*!
281 * @function dispatch_release
282 *
283 * @abstract
284 * Decrement the reference count of a dispatch object.
285 *
286 * @discussion
287 * A dispatch object is asynchronously deallocated once all references are
288 * released (i.e. the reference count becomes zero). The system does not
289 * guarantee that a given client is the last or only reference to a given
290 * object.
291 *
292 * @param object
293 * The object to release.
294 * The result of passing NULL in this parameter is undefined.
295 */
296API_AVAILABLE(macos(10.6), ios(4.0))
297DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
298DISPATCH_SWIFT_UNAVAILABLE("Can't be used with ARC")
299void
300dispatch_release(dispatch_object_t object);
301#if OS_OBJECT_USE_OBJC_RETAIN_RELEASE
302#undef dispatch_release
303#define dispatch_release(object) \
304		__extension__({ dispatch_object_t _o = (object); \
305		_dispatch_object_validate(_o); [_o release]; })
306#endif
307
308/*!
309 * @function dispatch_get_context
310 *
311 * @abstract
312 * Returns the application defined context of the object.
313 *
314 * @param object
315 * The result of passing NULL in this parameter is undefined.
316 *
317 * @result
318 * The context of the object; may be NULL.
319 */
320API_AVAILABLE(macos(10.6), ios(4.0))
321DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_PURE DISPATCH_WARN_RESULT
322DISPATCH_NOTHROW
323DISPATCH_SWIFT_UNAVAILABLE("Unavailable in Swift")
324void *_Nullable
325dispatch_get_context(dispatch_object_t object);
326
327/*!
328 * @function dispatch_set_context
329 *
330 * @abstract
331 * Associates an application defined context with the object.
332 *
333 * @param object
334 * The result of passing NULL in this parameter is undefined.
335 *
336 * @param context
337 * The new client defined context for the object. This may be NULL.
338 *
339 */
340API_AVAILABLE(macos(10.6), ios(4.0))
341DISPATCH_EXPORT DISPATCH_NOTHROW
342DISPATCH_SWIFT_UNAVAILABLE("Unavailable in Swift")
343void
344dispatch_set_context(dispatch_object_t object, void *_Nullable context);
345
346/*!
347 * @function dispatch_set_finalizer_f
348 *
349 * @abstract
350 * Set the finalizer function for a dispatch object.
351 *
352 * @param object
353 * The dispatch object to modify.
354 * The result of passing NULL in this parameter is undefined.
355 *
356 * @param finalizer
357 * The finalizer function pointer.
358 *
359 * @discussion
360 * A dispatch object's finalizer will be invoked on the object's target queue
361 * after all references to the object have been released. This finalizer may be
362 * used by the application to release any resources associated with the object,
363 * such as freeing the object's context.
364 * The context parameter passed to the finalizer function is the current
365 * context of the dispatch object at the time the finalizer call is made.
366 */
367API_AVAILABLE(macos(10.6), ios(4.0))
368DISPATCH_EXPORT DISPATCH_NOTHROW
369DISPATCH_SWIFT_UNAVAILABLE("Unavailable in Swift")
370void
371dispatch_set_finalizer_f(dispatch_object_t object,
372		dispatch_function_t _Nullable finalizer);
373
374/*!
375 * @function dispatch_activate
376 *
377 * @abstract
378 * Activates the specified dispatch object.
379 *
380 * @discussion
381 * Dispatch objects such as queues and sources may be created in an inactive
382 * state. Objects in this state have to be activated before any blocks
383 * associated with them will be invoked.
384 *
385 * The target queue of inactive objects can be changed using
386 * dispatch_set_target_queue(). Change of target queue is no longer permitted
387 * once an initially inactive object has been activated.
388 *
389 * Calling dispatch_activate() on an active object has no effect.
390 * Releasing the last reference count on an inactive object is undefined.
391 *
392 * @param object
393 * The object to be activated.
394 * The result of passing NULL in this parameter is undefined.
395 */
396API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
397DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
398DISPATCH_SWIFT_NAME(DispatchObject.activate(self:))
399void
400dispatch_activate(dispatch_object_t object);
401
402/*!
403 * @function dispatch_suspend
404 *
405 * @abstract
406 * Suspends the invocation of blocks on a dispatch object.
407 *
408 * @discussion
409 * A suspended object will not invoke any blocks associated with it. The
410 * suspension of an object will occur after any running block associated with
411 * the object completes.
412 *
413 * Calls to dispatch_suspend() must be balanced with calls
414 * to dispatch_resume().
415 *
416 * @param object
417 * The object to be suspended.
418 * The result of passing NULL in this parameter is undefined.
419 */
420API_AVAILABLE(macos(10.6), ios(4.0))
421DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
422DISPATCH_SWIFT_NAME(DispatchObject.suspend(self:))
423void
424dispatch_suspend(dispatch_object_t object);
425
426/*!
427 * @function dispatch_resume
428 *
429 * @abstract
430 * Resumes the invocation of blocks on a dispatch object.
431 *
432 * @discussion
433 * Dispatch objects can be suspended with dispatch_suspend(), which increments
434 * an internal suspension count. dispatch_resume() is the inverse operation,
435 * and consumes suspension counts. When the last suspension count is consumed,
436 * blocks associated with the object will be invoked again.
437 *
438 * For backward compatibility reasons, dispatch_resume() on an inactive and not
439 * otherwise suspended dispatch source object has the same effect as calling
440 * dispatch_activate(). For new code, using dispatch_activate() is preferred.
441 *
442 * If the specified object has zero suspension count and is not an inactive
443 * source, this function will result in an assertion and the process being
444 * terminated.
445 *
446 * @param object
447 * The object to be resumed.
448 * The result of passing NULL in this parameter is undefined.
449 */
450API_AVAILABLE(macos(10.6), ios(4.0))
451DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
452DISPATCH_SWIFT_NAME(DispatchObject.resume(self:))
453void
454dispatch_resume(dispatch_object_t object);
455
456/*!
457 * @function dispatch_set_qos_class_floor
458 *
459 * @abstract
460 * Sets the QOS class floor on a dispatch queue, source or workloop.
461 *
462 * @discussion
463 * The QOS class of workitems submitted to this object asynchronously will be
464 * elevated to at least the specified QOS class floor. The QOS of the workitem
465 * will be used if higher than the floor even when the workitem has been created
466 * without "ENFORCE" semantics.
467 *
468 * Setting the QOS class floor is equivalent to the QOS effects of configuring
469 * a queue whose target queue has a QoS class set to the same value.
470 *
471 * @param object
472 * A dispatch queue, workloop, or source to configure.
473 * The object must be inactive.
474 *
475 * Passing another object type or an object that has been activated is undefined
476 * and will cause the process to be terminated.
477 *
478 * @param qos_class
479 * A QOS class value:
480 *  - QOS_CLASS_USER_INTERACTIVE
481 *  - QOS_CLASS_USER_INITIATED
482 *  - QOS_CLASS_DEFAULT
483 *  - QOS_CLASS_UTILITY
484 *  - QOS_CLASS_BACKGROUND
485 * Passing any other value is undefined.
486 *
487 * @param relative_priority
488 * A relative priority within the QOS class. This value is a negative
489 * offset from the maximum supported scheduler priority for the given class.
490 * Passing a value greater than zero or less than QOS_MIN_RELATIVE_PRIORITY
491 * is undefined.
492 */
493API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
494DISPATCH_EXPORT DISPATCH_NOTHROW
495DISPATCH_SWIFT_UNAVAILABLE("Unavailable in Swift")
496void
497dispatch_set_qos_class_floor(dispatch_object_t object,
498		dispatch_qos_class_t qos_class, int relative_priority);
499
500#ifdef __BLOCKS__
501/*!
502 * @function dispatch_wait
503 *
504 * @abstract
505 * Wait synchronously for an object or until the specified timeout has elapsed.
506 *
507 * @discussion
508 * Type-generic macro that maps to dispatch_block_wait, dispatch_group_wait or
509 * dispatch_semaphore_wait, depending on the type of the first argument.
510 * See documentation for these functions for more details.
511 * This function is unavailable for any other object type.
512 *
513 * @param object
514 * The object to wait on.
515 * The result of passing NULL in this parameter is undefined.
516 *
517 * @param timeout
518 * When to timeout (see dispatch_time). As a convenience, there are the
519 * DISPATCH_TIME_NOW and DISPATCH_TIME_FOREVER constants.
520 *
521 * @result
522 * Returns zero on success or non-zero on error (i.e. timed out).
523 */
524DISPATCH_UNAVAILABLE
525DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
526intptr_t
527dispatch_wait(void *object, dispatch_time_t timeout);
528#if __has_extension(c_generic_selections)
529#define dispatch_wait(object, timeout) \
530		_Generic((object), \
531			dispatch_block_t:dispatch_block_wait, \
532			dispatch_group_t:dispatch_group_wait, \
533			dispatch_semaphore_t:dispatch_semaphore_wait \
534		)((object),(timeout))
535#endif
536
537/*!
538 * @function dispatch_notify
539 *
540 * @abstract
541 * Schedule a notification block to be submitted to a queue when the execution
542 * of a specified object has completed.
543 *
544 * @discussion
545 * Type-generic macro that maps to dispatch_block_notify or
546 * dispatch_group_notify, depending on the type of the first argument.
547 * See documentation for these functions for more details.
548 * This function is unavailable for any other object type.
549 *
550 * @param object
551 * The object to observe.
552 * The result of passing NULL in this parameter is undefined.
553 *
554 * @param queue
555 * The queue to which the supplied notification block will be submitted when
556 * the observed object completes.
557 *
558 * @param notification_block
559 * The block to submit when the observed object completes.
560 */
561DISPATCH_UNAVAILABLE
562DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
563void
564dispatch_notify(void *object, dispatch_object_t queue,
565		dispatch_block_t notification_block);
566#if __has_extension(c_generic_selections)
567#define dispatch_notify(object, queue, notification_block) \
568		_Generic((object), \
569			dispatch_block_t:dispatch_block_notify, \
570			dispatch_group_t:dispatch_group_notify \
571		)((object),(queue), (notification_block))
572#endif
573
574/*!
575 * @function dispatch_cancel
576 *
577 * @abstract
578 * Cancel the specified object.
579 *
580 * @discussion
581 * Type-generic macro that maps to dispatch_block_cancel or
582 * dispatch_source_cancel, depending on the type of the first argument.
583 * See documentation for these functions for more details.
584 * This function is unavailable for any other object type.
585 *
586 * @param object
587 * The object to cancel.
588 * The result of passing NULL in this parameter is undefined.
589 */
590DISPATCH_UNAVAILABLE
591DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
592void
593dispatch_cancel(void *object);
594#if __has_extension(c_generic_selections)
595#define dispatch_cancel(object) \
596		_Generic((object), \
597			dispatch_block_t:dispatch_block_cancel, \
598			dispatch_source_t:dispatch_source_cancel \
599		)((object))
600#endif
601
602/*!
603 * @function dispatch_testcancel
604 *
605 * @abstract
606 * Test whether the specified object has been canceled
607 *
608 * @discussion
609 * Type-generic macro that maps to dispatch_block_testcancel or
610 * dispatch_source_testcancel, depending on the type of the first argument.
611 * See documentation for these functions for more details.
612 * This function is unavailable for any other object type.
613 *
614 * @param object
615 * The object to test.
616 * The result of passing NULL in this parameter is undefined.
617 *
618 * @result
619 * Non-zero if canceled and zero if not canceled.
620 */
621DISPATCH_UNAVAILABLE
622DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE
623DISPATCH_NOTHROW
624intptr_t
625dispatch_testcancel(void *object);
626#if __has_extension(c_generic_selections)
627#define dispatch_testcancel(object) \
628		_Generic((object), \
629			dispatch_block_t:dispatch_block_testcancel, \
630			dispatch_source_t:dispatch_source_testcancel \
631		)((object))
632#endif
633#endif // __BLOCKS__
634
635/*!
636 * @function dispatch_debug
637 *
638 * @abstract
639 * Programmatically log debug information about a dispatch object.
640 *
641 * @discussion
642 * Programmatically log debug information about a dispatch object. By default,
643 * the log output is sent to syslog at notice level. In the debug version of
644 * the library, the log output is sent to a file in /var/tmp.
645 * The log output destination can be configured via the LIBDISPATCH_LOG
646 * environment variable, valid values are: YES, NO, syslog, stderr, file.
647 *
648 * This function is deprecated and will be removed in a future release.
649 * Objective-C callers may use -debugDescription instead.
650 *
651 * @param object
652 * The object to introspect.
653 *
654 * @param message
655 * The message to log above and beyond the introspection.
656 */
657API_DEPRECATED("unsupported interface", macos(10.6,10.9), ios(4.0,6.0))
658DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NOTHROW DISPATCH_COLD
659__attribute__((__format__(printf,2,3)))
660void
661dispatch_debug(dispatch_object_t object,
662			   const char *DISPATCH_UNSAFE_INDEXABLE message, ...);
663
664API_DEPRECATED("unsupported interface", macos(10.6,10.9), ios(4.0,6.0))
665DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NOTHROW DISPATCH_COLD
666__attribute__((__format__(printf,2,0)))
667void
668dispatch_debugv(dispatch_object_t object,
669				const char *DISPATCH_UNSAFE_INDEXABLE message, va_list ap);
670
671__END_DECLS
672
673DISPATCH_ASSUME_ABI_SINGLE_END
674DISPATCH_ASSUME_NONNULL_END
675
676#endif