1/*
2 * Copyright (c) 2012-2013 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/*
22 * IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
23 * which are subject to change in future releases of Mac OS X. Any applications
24 * relying on these interfaces WILL break.
25 */
26
27#ifndef __DISPATCH_INTROSPECTION_PRIVATE__
28#define __DISPATCH_INTROSPECTION_PRIVATE__
29
30/*!
31 * @header
32 *
33 * @abstract
34 * Introspection SPI for libdispatch.
35 *
36 * @discussion
37 * This SPI is only available in the introspection version of the library,
38 * loaded by running a process with the environment variable
39 * DYLD_LIBRARY_PATH=/usr/lib/system/introspection
40 *
41 * NOTE: most of these functions are _not_ exported from the shared library,
42 * the unexported functions are intended to only be called from a debugger
43 * context while the rest of the process is suspended.
44 */
45
46#ifndef __BEGIN_DECLS
47#if defined(__cplusplus)
48#define	__BEGIN_DECLS extern "C" {
49#define	__END_DECLS }
50#else
51#define	__BEGIN_DECLS
52#define	__END_DECLS
53#endif
54#endif
55
56__BEGIN_DECLS
57
58#ifndef __DISPATCH_INDIRECT__
59/*
60 * Typedefs of opaque types, for direct inclusion of header in lldb expressions
61 */
62typedef __typeof__(sizeof(int)) size_t;
63typedef struct _opaque_pthread_t *pthread_t;
64typedef void (*dispatch_function_t)(void *);
65typedef struct Block_layout *dispatch_block_t;
66typedef struct dispatch_continuation_s *dispatch_continuation_t;
67typedef struct dispatch_queue_s *dispatch_queue_t;
68typedef struct dispatch_source_s *dispatch_source_t;
69typedef struct dispatch_group_s *dispatch_group_t;
70typedef struct dispatch_object_s *dispatch_object_t;
71#ifndef __OSX_AVAILABLE_STARTING
72#define __OSX_AVAILABLE_STARTING(x,y)
73#endif
74#ifndef DISPATCH_EXPORT
75#define DISPATCH_EXPORT extern
76#endif
77#endif // __DISPATCH_INDIRECT__
78
79/*!
80 * @typedef dispatch_introspection_versions_s
81 *
82 * @abstract
83 * A structure of version and size information of introspection structures.
84 *
85 * @field introspection_version
86 * Version of overall dispatch_introspection SPI.
87 *
88 * @field hooks_version
89 * Version of dispatch_introspection_hooks_s structure.
90 * Version 2 adds the queue_item_complete member.
91 *
92 * @field hooks_size
93 * Size of dispatch_introspection_hooks_s structure.
94 *
95 * @field queue_item_version
96 * Version of dispatch_introspection_queue_item_s structure.
97 *
98 * @field queue_item_size
99 * Size of dispatch_introspection_queue_item_s structure.
100 *
101 * @field queue_block_version
102 * Version of dispatch_introspection_queue_block_s structure.
103 *
104 * @field queue_block_size
105 * Size of dispatch_introspection_queue_block_s structure.
106 *
107 * @field queue_function_version
108 * Version of dispatch_introspection_queue_function_s structure.
109 *
110 * @field queue_function_size
111 * Size of dispatch_introspection_queue_function_s structure.
112 *
113 * @field queue_thread_version
114 * Version of dispatch_introspection_queue_thread_s structure.
115 *
116 * @field queue_thread_size
117 * Size of dispatch_introspection_queue_thread_s structure.
118 *
119 * @field object_version
120 * Version of dispatch_introspection_object_s structure.
121 *
122 * @field object_size
123 * Size of dispatch_introspection_object_s structure.
124 *
125 * @field queue_version
126 * Version of dispatch_introspection_queue_s structure.
127 *
128 * @field queue_size
129 * Size of dispatch_introspection_queue_s structure.
130 *
131 * @field source_version
132 * Version of dispatch_introspection_source_s structure.
133 *
134 * @field source_size
135 * Size of dispatch_introspection_source_s structure.
136 */
137
138__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0)
139DISPATCH_EXPORT const struct dispatch_introspection_versions_s {
140	unsigned long introspection_version;
141	unsigned long hooks_version;
142	size_t hooks_size;
143	unsigned long queue_item_version;
144	size_t queue_item_size;
145	unsigned long queue_block_version;
146	size_t queue_block_size;
147	unsigned long queue_function_version;
148	size_t queue_function_size;
149	unsigned long queue_thread_version;
150	size_t queue_thread_size;
151	unsigned long object_version;
152	size_t object_size;
153	unsigned long queue_version;
154	size_t queue_size;
155	unsigned long source_version;
156	size_t source_size;
157} dispatch_introspection_versions;
158
159/*!
160 * @typedef dispatch_introspection_queue_block_s
161 *
162 * @abstract
163 * A structure of introspection information for a block item enqueued on a
164 * dispatch queue.
165 *
166 * @field continuation
167 * Pointer to enqueued item.
168 *
169 * @field target_queue
170 * Target queue of item (may be different to the queue the item is currently
171 * enqueued on).
172 *
173 * @field block
174 * Block for enqueued item.
175 *
176 * @field block_invoke
177 * Function pointer of block for enqueued item.
178 *
179 * @field group
180 * Group containing enqueued item (may be NULL).
181 *
182 * @field waiter
183 * Thread waiting for completion of enqueued item (NULL if sync == 0).
184 *
185 * @field barrier
186 * Item is a barrier on the queue (all items on serial queues are barriers).
187 *
188 * @field sync
189 * Item was enqueued by a dispatch_sync/dispatch_barrier_sync.
190 *
191 * @field apply
192 * Item is part of a dispatch_apply.
193 */
194typedef struct dispatch_introspection_queue_block_s {
195	dispatch_continuation_t continuation;
196	dispatch_queue_t target_queue;
197	dispatch_block_t block;
198	dispatch_function_t block_invoke;
199	dispatch_group_t group;
200	pthread_t waiter;
201	unsigned long barrier:1,
202			sync:1,
203			apply:1;
204} dispatch_introspection_queue_block_s;
205typedef dispatch_introspection_queue_block_s
206		*dispatch_introspection_queue_block_t;
207
208/*!
209 * @typedef dispatch_introspection_queue_function_s
210 *
211 * @abstract
212 * A structure of introspection information for a function & context pointer
213 * item enqueued on a dispatch queue.
214 *
215 * @field continuation
216 * Pointer to enqueued item.
217 *
218 * @field target_queue
219 * Target queue of item (may be different to the queue the item is currently
220 * enqueued on).
221 *
222 * @field context
223 * Context in enqueued item.
224 *
225 * @field block_invoke
226 * Function pointer in enqueued item.
227 *
228 * @field group
229 * Group containing enqueued item (may be NULL).
230 *
231 * @field waiter
232 * Thread waiting for completion of enqueued item (NULL if sync == 0).
233 *
234 * @field barrier
235 * Item is a barrier on the queue (all items on serial queues are barriers).
236 *
237 * @field sync
238 * Item was enqueued by a dispatch_sync_f/dispatch_barrier_sync_f.
239 *
240 * @field apply
241 * Item is part of a dispatch_apply_f.
242 */
243typedef struct dispatch_introspection_queue_function_s {
244	dispatch_continuation_t continuation;
245	dispatch_queue_t target_queue;
246	void *context;
247	dispatch_function_t function;
248	dispatch_group_t group;
249	pthread_t waiter;
250	unsigned long barrier:1,
251			sync:1,
252			apply:1;
253} dispatch_introspection_queue_function_s;
254typedef dispatch_introspection_queue_function_s
255		*dispatch_introspection_queue_function_t;
256
257/*!
258 * @typedef dispatch_introspection_object_s
259 *
260 * @abstract
261 * A structure of introspection information for a generic dispatch object.
262 *
263 * @field object
264 * Pointer to object.
265 *
266 * @field target_queue
267 * Target queue of object (may be different to the queue the object is
268 * currently enqueued on).
269 *
270 * @field type
271 * Object class pointer.
272 *
273 * @field kind
274 * String describing the object type.
275 */
276typedef struct dispatch_introspection_object_s {
277	dispatch_continuation_t object;
278	dispatch_queue_t target_queue;
279	void *type;
280	const char *kind;
281} dispatch_introspection_object_s;
282typedef dispatch_introspection_object_s *dispatch_introspection_object_t;
283
284/*!
285 * @typedef dispatch_introspection_queue_s
286 *
287 * @abstract
288 * A structure of introspection information for a dispatch queue.
289 *
290 * @field queue
291 * Pointer to queue object.
292 *
293 * @field target_queue
294 * Target queue of queue (may be different to the queue the queue is currently
295 * enqueued on). NULL indicates queue is a root queue.
296 *
297 * @field label
298 * Pointer to queue label.
299 *
300 * @field serialnum
301 * Queue serial number (unique per process).
302 *
303 * @field width
304 * Queue width (1: serial queue, UINT_MAX: concurrent queue).
305 *
306 * @field suspend_count
307 * Number of times the queue has been suspended.
308 *
309 * @field enqueued
310 * Queue is enqueued on another queue.
311 *
312 * @field barrier
313 * Queue is executing a barrier item.
314 *
315 * @field draining
316 * Queue is being drained (cannot get queue items).
317 *
318 * @field global
319 * Queue is a global queue.
320 *
321 * @field main
322 * Queue is the main queue.
323 */
324typedef struct dispatch_introspection_queue_s {
325	dispatch_queue_t queue;
326	dispatch_queue_t target_queue;
327	const char *label;
328	unsigned long serialnum;
329	unsigned int width;
330	unsigned int suspend_count;
331	unsigned long enqueued:1,
332			barrier:1,
333			draining:1,
334			global:1,
335			main:1;
336} dispatch_introspection_queue_s;
337typedef dispatch_introspection_queue_s *dispatch_introspection_queue_t;
338
339/*!
340 * @typedef dispatch_introspection_source_s
341 *
342 * @abstract
343 * A structure of introspection information for a dispatch source.
344 *
345 * @field source
346 * Pointer to source object.
347 *
348 * @field target_queue
349 * Target queue of source (may be different to the queue the source is currently
350 * enqueued on).
351 *
352 * @field type
353 * Source type (kevent filter)
354 *
355 * @field handle
356 * Source handle (monitored entity).
357 *
358 * @field context
359 * Context pointer passed to source handler. Pointer to handler block if
360 * handler_is_block == 1.
361 *
362 * @field handler
363 * Source handler function. Function pointer of handler block if
364 * handler_is_block == 1.
365 *
366 * @field suspend_count
367 * Number of times the source has been suspended.
368 *
369 * @field enqueued
370 * Source is enqueued on a queue.
371 *
372 * @field handler_is_block
373 * Source handler is a block.
374 *
375 * @field timer
376 * Source is a timer.
377 *
378 * @field after
379 * Source is a dispatch_after timer.
380 */
381typedef struct dispatch_introspection_source_s {
382	dispatch_source_t source;
383	dispatch_queue_t target_queue;
384	unsigned long type;
385	unsigned long handle;
386	void *context;
387	dispatch_function_t handler;
388	unsigned int suspend_count;
389	unsigned long enqueued:1,
390			handler_is_block:1,
391			timer:1,
392			after:1;
393} dispatch_introspection_source_s;
394typedef dispatch_introspection_source_s *dispatch_introspection_source_t;
395
396/*!
397 * @typedef dispatch_introspection_queue_thread_s
398 *
399 * @abstract
400 * A structure of introspection information about a thread executing items for
401 * a dispatch queue.
402 *
403 * @field object
404 * Pointer to thread object.
405 *
406 * @field thread
407 * Thread executing items for a queue.
408 *
409 * @field queue
410 * Queue introspection information. The queue.queue field is NULL if this thread
411 * is not currently executing items for a queue.
412 */
413typedef struct dispatch_introspection_queue_thread_s {
414	dispatch_continuation_t object;
415	pthread_t thread;
416	dispatch_introspection_queue_s queue;
417} dispatch_introspection_queue_thread_s;
418typedef dispatch_introspection_queue_thread_s
419		*dispatch_introspection_queue_thread_t;
420
421/*!
422 * @enum dispatch_introspection_queue_item_type
423 *
424 * @abstract
425 * Types of items enqueued on a dispatch queue.
426 */
427enum dispatch_introspection_queue_item_type {
428  dispatch_introspection_queue_item_type_none = 0x0,
429  dispatch_introspection_queue_item_type_block = 0x11,
430  dispatch_introspection_queue_item_type_function = 0x12,
431  dispatch_introspection_queue_item_type_object = 0x100,
432  dispatch_introspection_queue_item_type_queue = 0x101,
433  dispatch_introspection_queue_item_type_source = 0102,
434};
435
436/*!
437 * @typedef dispatch_introspection_queue_item_s
438 *
439 * @abstract
440 * A structure of introspection information about an item enqueued on a
441 * dispatch queue.
442 *
443 * @field type
444 * Indicates which of the union members applies to this item.
445 */
446typedef struct dispatch_introspection_queue_item_s {
447	unsigned long type; // dispatch_introspection_queue_item_type
448	union {
449		dispatch_introspection_queue_block_s block;
450		dispatch_introspection_queue_function_s function;
451		dispatch_introspection_object_s object;
452		dispatch_introspection_queue_s queue;
453		dispatch_introspection_source_s source;
454	};
455} dispatch_introspection_queue_item_s;
456typedef dispatch_introspection_queue_item_s
457		*dispatch_introspection_queue_item_t;
458
459/*!
460 * @typedef dispatch_introspection_hook_queue_create_t
461 *
462 * @abstract
463 * A function pointer called when a dispatch queue is created.
464 *
465 * @param queue_info
466 * Pointer to queue introspection structure.
467 */
468typedef void (*dispatch_introspection_hook_queue_create_t)(
469		dispatch_introspection_queue_t queue_info);
470
471/*!
472 * @typedef dispatch_introspection_hook_queue_dispose_t
473 *
474 * @abstract
475 * A function pointer called when a dispatch queue is destroyed.
476 *
477 * @param queue_info
478 * Pointer to queue introspection structure.
479 */
480typedef void (*dispatch_introspection_hook_queue_dispose_t)(
481		dispatch_introspection_queue_t queue_info);
482
483/*!
484 * @typedef dispatch_introspection_hook_queue_item_enqueue_t
485 *
486 * @abstract
487 * A function pointer called when an item is enqueued onto a dispatch queue.
488 *
489 * @param queue
490 * Pointer to queue.
491 *
492 * @param item
493 * Pointer to item introspection structure.
494 */
495typedef void (*dispatch_introspection_hook_queue_item_enqueue_t)(
496		dispatch_queue_t queue, dispatch_introspection_queue_item_t item);
497
498/*!
499 * @typedef dispatch_introspection_hook_queue_item_dequeue_t
500 *
501 * @abstract
502 * A function pointer called when an item is dequeued from a dispatch queue.
503 *
504 * @param queue
505 * Pointer to queue.
506 *
507 * @param item
508 * Pointer to item introspection structure.
509 */
510typedef void (*dispatch_introspection_hook_queue_item_dequeue_t)(
511		dispatch_queue_t queue, dispatch_introspection_queue_item_t item);
512
513/*!
514 * @typedef dispatch_introspection_hook_queue_item_complete_t
515 *
516 * @abstract
517 * A function pointer called when an item previously dequeued from a dispatch
518 * queue has completed processing.
519 *
520 * @discussion
521 * The object pointer value passed to this function pointer must be treated as a
522 * value only. It is intended solely for matching up with an earlier call to a
523 * dequeue hook function pointer by comparing to the first member of the
524 * dispatch_introspection_queue_item_t structure. It must NOT be dereferenced
525 * or e.g. passed to dispatch_introspection_queue_item_get_info(), the memory
526 * that was backing it may have been reused at the time this hook is called.
527 *
528 * @param object
529 * Opaque dentifier for completed item. Must NOT be dereferenced.
530 */
531typedef void (*dispatch_introspection_hook_queue_item_complete_t)(
532		dispatch_continuation_t object);
533
534/*!
535 * @typedef dispatch_introspection_hooks_s
536 *
537 * @abstract
538 * A structure of function pointer hoooks into libdispatch.
539 */
540
541typedef struct dispatch_introspection_hooks_s {
542	dispatch_introspection_hook_queue_create_t queue_create;
543	dispatch_introspection_hook_queue_dispose_t queue_dispose;
544	dispatch_introspection_hook_queue_item_enqueue_t queue_item_enqueue;
545	dispatch_introspection_hook_queue_item_dequeue_t queue_item_dequeue;
546	dispatch_introspection_hook_queue_item_complete_t queue_item_complete;
547	void *_reserved[5];
548} dispatch_introspection_hooks_s;
549typedef dispatch_introspection_hooks_s *dispatch_introspection_hooks_t;
550
551/*!
552 * @function dispatch_introspection_get_queues
553 *
554 * @abstract
555 * Retrieve introspection information about all dispatch queues in the process,
556 * in batches of specified size.
557 *
558 * @discussion
559 * Retrieving queue information and iterating through the list of all queues
560 * must take place from a debugger context (while the rest of the process is
561 * suspended).
562 *
563 * @param start
564 * Starting point for this batch of queue information, as returned by a previous
565 * call to _dispatch_introspection_get_queues().
566 * Pass NULL to retrieve the initial batch.
567 *
568 * @param count
569 * Number of queues to introspect.
570 *
571 * @param queues
572 * Array to fill with queue information. If less than 'count' queues are left
573 * in this batch, the end of valid entries in the array will be indicated
574 * by an entry with NULL queue member.
575 *
576 * @result
577 * Queue to pass to another call to _dispatch_introspection_get_queues() to
578 * retrieve information about the next batch of queues. May be NULL if there
579 * are no more queues to iterate over.
580 */
581extern dispatch_queue_t
582dispatch_introspection_get_queues(dispatch_queue_t start, size_t count,
583		dispatch_introspection_queue_t queues);
584
585/*!
586 * @function dispatch_introspection_get_queue_threads
587 *
588 * @abstract
589 * Retrieve introspection information about all threads in the process executing
590 * items for dispatch queues, in batches of specified size.
591 *
592 * @discussion
593 * Retrieving thread information and iterating through the list of all queue
594 * threads must take place from a debugger context (while the rest of the
595 * process is suspended).
596 *
597 * @param start
598 * Starting point for this batch of thread information, as returned by a
599 * previous call to _dispatch_introspection_get_queue_threads().
600 * Pass NULL to retrieve the initial batch.
601 *
602 * @param count
603 * Number of queue threads to introspect.
604 *
605 * @param threads
606 * Array to fill with queue thread information. If less than 'count' threads are
607 * left in this batch, the end of valid entries in the array will be indicated
608 * by an entry with NULL object member.
609 *
610 * @result
611 * Object to pass to another call to _dispatch_introspection_get_queues() to
612 * retrieve information about the next batch of queues. May be NULL if there
613 * are no more queues to iterate over.
614 */
615extern dispatch_continuation_t
616dispatch_introspection_get_queue_threads(dispatch_continuation_t start,
617		size_t count, dispatch_introspection_queue_thread_t threads);
618
619/*!
620 * @function dispatch_introspection_queue_get_items
621 *
622 * @abstract
623 * Retrieve introspection information about all items enqueued on a queue, in
624 * batches of specified size.
625 *
626 * @discussion
627 * Retrieving queue item information and iterating through a queue must take
628 * place from a debugger context (while the rest of the process is suspended).
629 *
630 * @param queue
631 * Queue to introspect.
632 *
633 * @param start
634 * Starting point for this batch of queue item information, as returned by a
635 * previous call to _dispatch_introspection_queue_get_items().
636 * Pass NULL to retrieve the initial batch.
637 *
638 * @param count
639 * Number of items to introspect.
640 *
641 * @param items
642 * Array to fill with queue item information. If less than 'count' queues are
643 * left in this batch, the end of valid entries in the array will be indicated
644 * by an entry with type dispatch_introspection_queue_item_type_none.
645 *
646 * @result
647 * Item to pass to another call to _dispatch_introspection_queue_get_items() to
648 * retrieve information about the next batch of queue items. May be NULL if
649 * there are no more items to iterate over.
650 */
651extern dispatch_continuation_t
652dispatch_introspection_queue_get_items(dispatch_queue_t queue,
653		dispatch_continuation_t start, size_t count,
654		dispatch_introspection_queue_item_t items);
655
656/*!
657 * @function dispatch_introspection_queue_get_info
658 *
659 * @abstract
660 * Retrieve introspection information about a specified dispatch queue.
661 *
662 * @discussion
663 * Retrieving queue information must take place from a debugger context (while
664 * the rest of the process is suspended).
665 *
666 * @param queue
667 * Queue to introspect.
668 *
669 * @result
670 * Queue information struct.
671 */
672extern dispatch_introspection_queue_s
673dispatch_introspection_queue_get_info(dispatch_queue_t queue);
674
675/*!
676 * @function dispatch_introspection_queue_item_get_info
677 *
678 * @abstract
679 * Retrieve introspection information about a specified dispatch queue item.
680 *
681 * @discussion
682 * Retrieving queue item information must take place from a debugger context
683 * (while the rest of the process is suspended).
684 *
685 * @param queue
686 * Queue to introspect.
687 *
688 * @param item
689 * Item to introspect.
690 *
691 * @result
692 * Queue item information struct.
693 */
694extern dispatch_introspection_queue_item_s
695dispatch_introspection_queue_item_get_info(dispatch_queue_t queue,
696		dispatch_continuation_t item);
697
698/*!
699 * @function dispatch_introspection_hooks_install
700 *
701 * @abstract
702 * Install hook functions into libdispatch.
703 *
704 * @discussion
705 * Installing hook functions must take place from a debugger context (while the
706 * rest of the process is suspended) or early enough in the process lifecycle
707 * that the process is still single-threaded.
708 *
709 * The caller is responsible for implementing chaining to the hooks that were
710 * previously installed (if any).
711 *
712 * @param hooks
713 * Pointer to structure of hook function pointers. Any of the structure members
714 * may be NULL to indicate that the hook in question should not be installed.
715 * The structure is copied on input and filled with the previously installed
716 * hooks on output.
717 */
718
719__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0)
720DISPATCH_EXPORT void
721dispatch_introspection_hooks_install(dispatch_introspection_hooks_t hooks);
722
723/*!
724 * @function dispatch_introspection_hook_callouts_enable
725 *
726 * @abstract
727 * Enable hook callout functions in libdispatch that a debugger can break on
728 * and get introspection arguments even if there are no hook functions
729 * installed via dispatch_introspection_hooks_install().
730 *
731 * @discussion
732 * Enabling hook callout functions must take place from a debugger context
733 * (while the rest of the process is suspended).
734 *
735 * @param enable
736 * Pointer to dispatch_introspection_hooks_s structure. For every structure
737 * member with (any) non-NULL value, the corresponding hook callout will be
738 * enabled; for every NULL member the hook callout will be disabled (if there
739 * is no hook function installed).
740 * As a convenience, the 'enable' pointer may itself be NULL to indicate that
741 * all hook callouts should be enabled.
742 */
743
744extern void
745dispatch_introspection_hook_callouts_enable(
746		dispatch_introspection_hooks_t enable);
747
748/*!
749 * @function dispatch_introspection_hook_callout_queue_create
750 *
751 * @abstract
752 * Callout to queue creation hook that a debugger can break on.
753 */
754
755extern void
756dispatch_introspection_hook_callout_queue_create(
757		dispatch_introspection_queue_t queue_info);
758
759/*!
760 * @function dispatch_introspection_hook_callout_queue_dispose
761 *
762 * @abstract
763 * Callout to queue destruction hook that a debugger can break on.
764 */
765
766extern void
767dispatch_introspection_hook_callout_queue_dispose(
768		dispatch_introspection_queue_t queue_info);
769
770/*!
771 * @function dispatch_introspection_hook_callout_queue_item_enqueue
772 *
773 * @abstract
774 * Callout to queue enqueue hook that a debugger can break on.
775 */
776
777extern void
778dispatch_introspection_hook_callout_queue_item_enqueue(
779		dispatch_queue_t queue, dispatch_introspection_queue_item_t item);
780
781/*!
782 * @function dispatch_introspection_hook_callout_queue_item_dequeue
783 *
784 * @abstract
785 * Callout to queue dequeue hook that a debugger can break on.
786 */
787
788extern void
789dispatch_introspection_hook_callout_queue_item_dequeue(
790		dispatch_queue_t queue, dispatch_introspection_queue_item_t item);
791
792/*!
793 * @function dispatch_introspection_hook_callout_queue_item_complete
794 *
795 * @abstract
796 * Callout to queue item complete hook that a debugger can break on.
797 */
798
799extern void
800dispatch_introspection_hook_callout_queue_item_complete(
801		dispatch_continuation_t object);
802
803__END_DECLS
804
805#endif
806