2 * Copyright (c) 2012-2013 Apple Inc. All rights reserved.
4 * @APPLE_APACHE_LICENSE_HEADER_START@
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @APPLE_APACHE_LICENSE_HEADER_END@
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.
27 #ifndef __DISPATCH_INTROSPECTION_PRIVATE__
28 #define __DISPATCH_INTROSPECTION_PRIVATE__
34 * Introspection SPI for libdispatch.
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
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.
47 #if defined(__cplusplus)
48 #define __BEGIN_DECLS extern "C" {
58 #ifndef __DISPATCH_INDIRECT__
60 * Typedefs of opaque types, for direct inclusion of header in lldb expressions
62 typedef __typeof__(sizeof(int)) size_t;
63 typedef struct _opaque_pthread_t
*pthread_t
;
64 typedef void (*dispatch_function_t
)(void *);
65 typedef struct Block_layout
*dispatch_block_t
;
66 typedef struct dispatch_continuation_s
*dispatch_continuation_t
;
67 typedef struct dispatch_queue_s
*dispatch_queue_t
;
68 typedef struct dispatch_source_s
*dispatch_source_t
;
69 typedef struct dispatch_group_s
*dispatch_group_t
;
70 typedef struct dispatch_object_s
*dispatch_object_t
;
71 #ifndef __OSX_AVAILABLE_STARTING
72 #define __OSX_AVAILABLE_STARTING(x,y)
74 #ifndef DISPATCH_EXPORT
75 #define DISPATCH_EXPORT extern
77 #endif // __DISPATCH_INDIRECT__
80 * @typedef dispatch_introspection_versions_s
83 * A structure of version and size information of introspection structures.
85 * @field introspection_version
86 * Version of overall dispatch_introspection SPI.
88 * @field hooks_version
89 * Version of dispatch_introspection_hooks_s structure.
90 * Version 2 adds the queue_item_complete member.
93 * Size of dispatch_introspection_hooks_s structure.
95 * @field queue_item_version
96 * Version of dispatch_introspection_queue_item_s structure.
98 * @field queue_item_size
99 * Size of dispatch_introspection_queue_item_s structure.
101 * @field queue_block_version
102 * Version of dispatch_introspection_queue_block_s structure.
104 * @field queue_block_size
105 * Size of dispatch_introspection_queue_block_s structure.
107 * @field queue_function_version
108 * Version of dispatch_introspection_queue_function_s structure.
110 * @field queue_function_size
111 * Size of dispatch_introspection_queue_function_s structure.
113 * @field queue_thread_version
114 * Version of dispatch_introspection_queue_thread_s structure.
116 * @field queue_thread_size
117 * Size of dispatch_introspection_queue_thread_s structure.
119 * @field object_version
120 * Version of dispatch_introspection_object_s structure.
123 * Size of dispatch_introspection_object_s structure.
125 * @field queue_version
126 * Version of dispatch_introspection_queue_s structure.
129 * Size of dispatch_introspection_queue_s structure.
131 * @field source_version
132 * Version of dispatch_introspection_source_s structure.
135 * Size of dispatch_introspection_source_s structure.
138 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
)
139 DISPATCH_EXPORT
const struct dispatch_introspection_versions_s
{
140 unsigned long introspection_version
;
141 unsigned long hooks_version
;
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
;
153 unsigned long queue_version
;
155 unsigned long source_version
;
157 } dispatch_introspection_versions
;
160 * @typedef dispatch_introspection_queue_block_s
163 * A structure of introspection information for a block item enqueued on a
166 * @field continuation
167 * Pointer to enqueued item.
169 * @field target_queue
170 * Target queue of item (may be different to the queue the item is currently
174 * Block for enqueued item.
176 * @field block_invoke
177 * Function pointer of block for enqueued item.
180 * Group containing enqueued item (may be NULL).
183 * Thread waiting for completion of enqueued item (NULL if sync == 0).
186 * Item is a barrier on the queue (all items on serial queues are barriers).
189 * Item was enqueued by a dispatch_sync/dispatch_barrier_sync.
192 * Item is part of a dispatch_apply.
194 typedef 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
;
201 unsigned long barrier
:1,
204 } dispatch_introspection_queue_block_s
;
205 typedef dispatch_introspection_queue_block_s
206 *dispatch_introspection_queue_block_t
;
209 * @typedef dispatch_introspection_queue_function_s
212 * A structure of introspection information for a function & context pointer
213 * item enqueued on a dispatch queue.
215 * @field continuation
216 * Pointer to enqueued item.
218 * @field target_queue
219 * Target queue of item (may be different to the queue the item is currently
223 * Context in enqueued item.
225 * @field block_invoke
226 * Function pointer in enqueued item.
229 * Group containing enqueued item (may be NULL).
232 * Thread waiting for completion of enqueued item (NULL if sync == 0).
235 * Item is a barrier on the queue (all items on serial queues are barriers).
238 * Item was enqueued by a dispatch_sync_f/dispatch_barrier_sync_f.
241 * Item is part of a dispatch_apply_f.
243 typedef struct dispatch_introspection_queue_function_s
{
244 dispatch_continuation_t continuation
;
245 dispatch_queue_t target_queue
;
247 dispatch_function_t function
;
248 dispatch_group_t group
;
250 unsigned long barrier
:1,
253 } dispatch_introspection_queue_function_s
;
254 typedef dispatch_introspection_queue_function_s
255 *dispatch_introspection_queue_function_t
;
258 * @typedef dispatch_introspection_object_s
261 * A structure of introspection information for a generic dispatch object.
266 * @field target_queue
267 * Target queue of object (may be different to the queue the object is
268 * currently enqueued on).
271 * Object class pointer.
274 * String describing the object type.
276 typedef struct dispatch_introspection_object_s
{
277 dispatch_continuation_t object
;
278 dispatch_queue_t target_queue
;
281 } dispatch_introspection_object_s
;
282 typedef dispatch_introspection_object_s
*dispatch_introspection_object_t
;
285 * @typedef dispatch_introspection_queue_s
288 * A structure of introspection information for a dispatch queue.
291 * Pointer to queue object.
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.
298 * Pointer to queue label.
301 * Queue serial number (unique per process).
304 * Queue width (1: serial queue, UINT_MAX: concurrent queue).
306 * @field suspend_count
307 * Number of times the queue has been suspended.
310 * Queue is enqueued on another queue.
313 * Queue is executing a barrier item.
316 * Queue is being drained (cannot get queue items).
319 * Queue is a global queue.
322 * Queue is the main queue.
324 typedef struct dispatch_introspection_queue_s
{
325 dispatch_queue_t queue
;
326 dispatch_queue_t target_queue
;
328 unsigned long serialnum
;
330 unsigned int suspend_count
;
331 unsigned long enqueued
:1,
336 } dispatch_introspection_queue_s
;
337 typedef dispatch_introspection_queue_s
*dispatch_introspection_queue_t
;
340 * @typedef dispatch_introspection_source_s
343 * A structure of introspection information for a dispatch source.
346 * Pointer to source object.
348 * @field target_queue
349 * Target queue of source (may be different to the queue the source is currently
353 * Source type (kevent filter)
356 * Source handle (monitored entity).
359 * Context pointer passed to source handler. Pointer to handler block if
360 * handler_is_block == 1.
363 * Source handler function. Function pointer of handler block if
364 * handler_is_block == 1.
366 * @field suspend_count
367 * Number of times the source has been suspended.
370 * Source is enqueued on a queue.
372 * @field handler_is_block
373 * Source handler is a block.
379 * Source is a dispatch_after timer.
381 typedef struct dispatch_introspection_source_s
{
382 dispatch_source_t source
;
383 dispatch_queue_t target_queue
;
385 unsigned long handle
;
387 dispatch_function_t handler
;
388 unsigned int suspend_count
;
389 unsigned long enqueued
:1,
393 } dispatch_introspection_source_s
;
394 typedef dispatch_introspection_source_s
*dispatch_introspection_source_t
;
397 * @typedef dispatch_introspection_queue_thread_s
400 * A structure of introspection information about a thread executing items for
404 * Pointer to thread object.
407 * Thread executing items for a queue.
410 * Queue introspection information. The queue.queue field is NULL if this thread
411 * is not currently executing items for a queue.
413 typedef struct dispatch_introspection_queue_thread_s
{
414 dispatch_continuation_t object
;
416 dispatch_introspection_queue_s queue
;
417 } dispatch_introspection_queue_thread_s
;
418 typedef dispatch_introspection_queue_thread_s
419 *dispatch_introspection_queue_thread_t
;
422 * @enum dispatch_introspection_queue_item_type
425 * Types of items enqueued on a dispatch queue.
427 enum 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,
437 * @typedef dispatch_introspection_queue_item_s
440 * A structure of introspection information about an item enqueued on a
444 * Indicates which of the union members applies to this item.
446 typedef struct dispatch_introspection_queue_item_s
{
447 unsigned long type
; // dispatch_introspection_queue_item_type
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
;
455 } dispatch_introspection_queue_item_s
;
456 typedef dispatch_introspection_queue_item_s
457 *dispatch_introspection_queue_item_t
;
460 * @typedef dispatch_introspection_hook_queue_create_t
463 * A function pointer called when a dispatch queue is created.
466 * Pointer to queue introspection structure.
468 typedef void (*dispatch_introspection_hook_queue_create_t
)(
469 dispatch_introspection_queue_t queue_info
);
472 * @typedef dispatch_introspection_hook_queue_dispose_t
475 * A function pointer called when a dispatch queue is destroyed.
478 * Pointer to queue introspection structure.
480 typedef void (*dispatch_introspection_hook_queue_dispose_t
)(
481 dispatch_introspection_queue_t queue_info
);
484 * @typedef dispatch_introspection_hook_queue_item_enqueue_t
487 * A function pointer called when an item is enqueued onto a dispatch queue.
493 * Pointer to item introspection structure.
495 typedef void (*dispatch_introspection_hook_queue_item_enqueue_t
)(
496 dispatch_queue_t queue
, dispatch_introspection_queue_item_t item
);
499 * @typedef dispatch_introspection_hook_queue_item_dequeue_t
502 * A function pointer called when an item is dequeued from a dispatch queue.
508 * Pointer to item introspection structure.
510 typedef void (*dispatch_introspection_hook_queue_item_dequeue_t
)(
511 dispatch_queue_t queue
, dispatch_introspection_queue_item_t item
);
514 * @typedef dispatch_introspection_hook_queue_item_complete_t
517 * A function pointer called when an item previously dequeued from a dispatch
518 * queue has completed processing.
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.
529 * Opaque dentifier for completed item. Must NOT be dereferenced.
531 typedef void (*dispatch_introspection_hook_queue_item_complete_t
)(
532 dispatch_continuation_t object
);
535 * @typedef dispatch_introspection_hooks_s
538 * A structure of function pointer hoooks into libdispatch.
541 typedef 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
;
548 } dispatch_introspection_hooks_s
;
549 typedef dispatch_introspection_hooks_s
*dispatch_introspection_hooks_t
;
552 * @function dispatch_introspection_get_queues
555 * Retrieve introspection information about all dispatch queues in the process,
556 * in batches of specified size.
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
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.
569 * Number of queues to introspect.
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.
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.
581 extern dispatch_queue_t
582 dispatch_introspection_get_queues(dispatch_queue_t start
, size_t count
,
583 dispatch_introspection_queue_t queues
);
586 * @function dispatch_introspection_get_queue_threads
589 * Retrieve introspection information about all threads in the process executing
590 * items for dispatch queues, in batches of specified size.
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).
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.
603 * Number of queue threads to introspect.
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.
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.
615 extern dispatch_continuation_t
616 dispatch_introspection_get_queue_threads(dispatch_continuation_t start
,
617 size_t count
, dispatch_introspection_queue_thread_t threads
);
620 * @function dispatch_introspection_queue_get_items
623 * Retrieve introspection information about all items enqueued on a queue, in
624 * batches of specified size.
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).
631 * Queue to introspect.
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.
639 * Number of items to introspect.
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.
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.
651 extern dispatch_continuation_t
652 dispatch_introspection_queue_get_items(dispatch_queue_t queue
,
653 dispatch_continuation_t start
, size_t count
,
654 dispatch_introspection_queue_item_t items
);
657 * @function dispatch_introspection_queue_get_info
660 * Retrieve introspection information about a specified dispatch queue.
663 * Retrieving queue information must take place from a debugger context (while
664 * the rest of the process is suspended).
667 * Queue to introspect.
670 * Queue information struct.
672 extern dispatch_introspection_queue_s
673 dispatch_introspection_queue_get_info(dispatch_queue_t queue
);
676 * @function dispatch_introspection_queue_item_get_info
679 * Retrieve introspection information about a specified dispatch queue item.
682 * Retrieving queue item information must take place from a debugger context
683 * (while the rest of the process is suspended).
686 * Queue to introspect.
689 * Item to introspect.
692 * Queue item information struct.
694 extern dispatch_introspection_queue_item_s
695 dispatch_introspection_queue_item_get_info(dispatch_queue_t queue
,
696 dispatch_continuation_t item
);
699 * @function dispatch_introspection_hooks_install
702 * Install hook functions into libdispatch.
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.
709 * The caller is responsible for implementing chaining to the hooks that were
710 * previously installed (if any).
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
719 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
)
721 dispatch_introspection_hooks_install(dispatch_introspection_hooks_t hooks
);
724 * @function dispatch_introspection_hook_callouts_enable
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().
732 * Enabling hook callout functions must take place from a debugger context
733 * (while the rest of the process is suspended).
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.
745 dispatch_introspection_hook_callouts_enable(
746 dispatch_introspection_hooks_t enable
);
749 * @function dispatch_introspection_hook_callout_queue_create
752 * Callout to queue creation hook that a debugger can break on.
756 dispatch_introspection_hook_callout_queue_create(
757 dispatch_introspection_queue_t queue_info
);
760 * @function dispatch_introspection_hook_callout_queue_dispose
763 * Callout to queue destruction hook that a debugger can break on.
767 dispatch_introspection_hook_callout_queue_dispose(
768 dispatch_introspection_queue_t queue_info
);
771 * @function dispatch_introspection_hook_callout_queue_item_enqueue
774 * Callout to queue enqueue hook that a debugger can break on.
778 dispatch_introspection_hook_callout_queue_item_enqueue(
779 dispatch_queue_t queue
, dispatch_introspection_queue_item_t item
);
782 * @function dispatch_introspection_hook_callout_queue_item_dequeue
785 * Callout to queue dequeue hook that a debugger can break on.
789 dispatch_introspection_hook_callout_queue_item_dequeue(
790 dispatch_queue_t queue
, dispatch_introspection_queue_item_t item
);
793 * @function dispatch_introspection_hook_callout_queue_item_complete
796 * Callout to queue item complete hook that a debugger can break on.
800 dispatch_introspection_hook_callout_queue_item_complete(
801 dispatch_continuation_t object
);