2  * Copyright (c) 2008-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_INTERNAL__ 
  28 #define __DISPATCH_INTERNAL__ 
  30 #include <config/config.h> 
  32 #define __DISPATCH_BUILDING_DISPATCH__ 
  33 #define __DISPATCH_INDIRECT__ 
  36 #include <Availability.h> 
  37 #include <TargetConditionals.h> 
  41 #if !defined(DISPATCH_MACH_SPI) && TARGET_OS_MAC 
  42 #define DISPATCH_MACH_SPI 1 
  44 #if !defined(OS_VOUCHER_CREATION_SPI) && TARGET_OS_MAC 
  45 #define OS_VOUCHER_CREATION_SPI 1 
  47 #if !defined(OS_VOUCHER_ACTIVITY_SPI) && TARGET_OS_MAC 
  48 #define OS_VOUCHER_ACTIVITY_SPI 1 
  50 #if !defined(OS_VOUCHER_ACTIVITY_BUFFER_SPI) && TARGET_OS_MAC && \ 
  51                 __has_include(<atm/atm_types.h>) 
  52 #define OS_VOUCHER_ACTIVITY_BUFFER_SPI 1 
  54 #if !defined(DISPATCH_LAYOUT_SPI) && TARGET_OS_MAC 
  55 #define DISPATCH_LAYOUT_SPI 1 
  58 #if !defined(USE_OBJC) && HAVE_OBJC 
  62 #if USE_OBJC && ((!TARGET_IPHONE_SIMULATOR && defined(__i386__)) || \ 
  63                 (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 1080)) 
  64 // Disable Objective-C support on platforms with legacy objc runtime 
  70 #define OS_OBJECT_HAVE_OBJC_SUPPORT 1 
  72 #define OS_OBJECT_USE_OBJC 1 
  74 #define OS_OBJECT_USE_OBJC 0 
  77 #define OS_OBJECT_HAVE_OBJC_SUPPORT 0 
  80 #include <dispatch/dispatch.h> 
  81 #include <dispatch/base.h> 
  84 #include <os/object.h> 
  85 #include <dispatch/time.h> 
  86 #include <dispatch/object.h> 
  87 #include <dispatch/queue.h> 
  88 #include <dispatch/block.h> 
  89 #include <dispatch/source.h> 
  90 #include <dispatch/group.h> 
  91 #include <dispatch/semaphore.h> 
  92 #include <dispatch/once.h> 
  93 #include <dispatch/data.h> 
  95 #include <dispatch/io.h> 
  98 #define DISPATCH_STRUCT_DECL(type, name, ...) \ 
  99         struct type __VA_ARGS__ name 
 101 // Visual Studio C++ does not support C99 designated initializers. 
 102 // This means that static declarations should be zero initialized and cannot 
 103 // be const since we must fill in the values during DLL initialization. 
 105 #define DISPATCH_STRUCT_INSTANCE(type, name, ...) \ 
 106 struct type name = { \ 
 110 #define DISPATCH_STRUCT_INSTANCE(type, name, ...) \ 
 111 struct type name = { 0 } 
 115 #define DISPATCH_CONST_STRUCT_DECL(type, name, ...) \ 
 116         const DISPATCH_STRUCT_DECL(type, name, __VA_ARGS__) 
 118 #define DISPATCH_CONST_STRUCT_INSTANCE(type, name, ...) \ 
 119         const DISPATCH_STRUCT_INSTANCE(type, name, __VA_ARGS__) 
 121 #define DISPATCH_CONST_STRUCT_DECL(type, name, ...) \ 
 122         DISPATCH_STRUCT_DECL(type, name, __VA_ARGS__) 
 124 #define DISPATCH_CONST_STRUCT_INSTANCE(type, name, ...) \ 
 125         DISPATCH_STRUCT_INSTANCE(type, name, __VA_ARGS__) 
 128 /* private.h must be included last to avoid picking up installed headers. */ 
 129 #include "object_private.h" 
 130 #include "queue_private.h" 
 131 #include "source_private.h" 
 132 #include "mach_private.h" 
 133 #include "data_private.h" 
 135 #include "io_private.h" 
 137 #include "voucher_private.h" 
 138 #include "voucher_activity_private.h" 
 139 #include "layout_private.h" 
 140 #include "benchmark.h" 
 143 /* SPI for Libsystem-internal use */ 
 144 DISPATCH_EXPORT DISPATCH_NOTHROW 
void libdispatch_init(void); 
 146 DISPATCH_EXPORT DISPATCH_NOTHROW 
void dispatch_atfork_prepare(void); 
 147 DISPATCH_EXPORT DISPATCH_NOTHROW 
void dispatch_atfork_parent(void); 
 148 DISPATCH_EXPORT DISPATCH_NOTHROW 
void dispatch_atfork_child(void); 
 151 /* More #includes at EOF (dependent on the contents of internal.h) ... */ 
 153 // Abort on uncaught exceptions thrown from client callouts rdar://8577499 
 154 #if !defined(DISPATCH_USE_CLIENT_CALLOUT) 
 155 #define DISPATCH_USE_CLIENT_CALLOUT 1 
 158 /* The "_debug" library build */ 
 159 #ifndef DISPATCH_DEBUG 
 160 #define DISPATCH_DEBUG 0 
 163 #ifndef DISPATCH_PROFILE 
 164 #define DISPATCH_PROFILE 0 
 167 #if (!TARGET_OS_EMBEDDED || DISPATCH_DEBUG || DISPATCH_PROFILE) && \ 
 168                 !defined(DISPATCH_USE_DTRACE) 
 169 #define DISPATCH_USE_DTRACE 1 
 172 #if DISPATCH_USE_DTRACE && (DISPATCH_INTROSPECTION || DISPATCH_DEBUG || \ 
 173                 DISPATCH_PROFILE) && !defined(DISPATCH_USE_DTRACE_INTROSPECTION) 
 174 #define DISPATCH_USE_DTRACE_INTROSPECTION 1 
 177 #if HAVE_LIBKERN_OSCROSSENDIAN_H 
 178 #include <libkern/OSCrossEndian.h> 
 180 #if HAVE_LIBKERN_OSATOMIC_H 
 181 #include <libkern/OSAtomic.h> 
 184 #include <mach/boolean.h> 
 185 #include <mach/clock_types.h> 
 186 #include <mach/clock.h> 
 187 #include <mach/exception.h> 
 188 #include <mach/mach.h> 
 189 #include <mach/mach_error.h> 
 190 #include <mach/mach_host.h> 
 191 #include <mach/mach_interface.h> 
 192 #include <mach/mach_time.h> 
 193 #include <mach/mach_traps.h> 
 194 #include <mach/message.h> 
 195 #include <mach/mig_errors.h> 
 196 #include <mach/host_special_ports.h> 
 197 #include <mach/host_info.h> 
 198 #include <mach/notify.h> 
 199 #include <mach/mach_vm.h> 
 200 #include <mach/vm_map.h> 
 201 #endif /* HAVE_MACH */ 
 202 #if HAVE_MALLOC_MALLOC_H 
 203 #include <malloc/malloc.h> 
 206 #include <sys/stat.h> 
 209 #include <sys/event.h> 
 210 #include <sys/mount.h> 
 211 #include <sys/queue.h> 
 212 #include <sys/sysctl.h> 
 213 #include <sys/socket.h> 
 214 #include <sys/time.h> 
 215 #include <sys/mman.h> 
 216 #include <netinet/in.h> 
 218 #include "sys_queue.h" 
 222 #include <Block_private.h> 
 224 #endif /* __BLOCKS__ */ 
 234 #include <semaphore.h> 
 247 #ifndef __has_builtin 
 248 #define __has_builtin(x) 0 
 250 #ifndef __has_include 
 251 #define __has_include(x) 0 
 253 #ifndef __has_feature 
 254 #define __has_feature(x) 0 
 256 #ifndef __has_attribute 
 257 #define __has_attribute(x) 0 
 261 #define DISPATCH_NOINLINE __attribute__((__noinline__)) 
 262 #define DISPATCH_USED __attribute__((__used__)) 
 263 #define DISPATCH_UNUSED __attribute__((__unused__)) 
 264 #define DISPATCH_WEAK __attribute__((__weak__)) 
 265 #define DISPATCH_OVERLOADABLE __attribute__((__overloadable__)) 
 267 #define DISPATCH_ALWAYS_INLINE_NDEBUG 
 269 #define DISPATCH_ALWAYS_INLINE_NDEBUG __attribute__((__always_inline__)) 
 272 #define DISPATCH_NOINLINE 
 273 #define DISPATCH_USED 
 274 #define DISPATCH_UNUSED 
 275 #define DISPATCH_WEAK 
 276 #define DISPATCH_ALWAYS_INLINE_NDEBUG 
 277 #endif  /* __GNUC__ */ 
 279 #define DISPATCH_CONCAT(x,y) DISPATCH_CONCAT1(x,y) 
 280 #define DISPATCH_CONCAT1(x,y) x ## y 
 282 // workaround 6368156 
 292 #define NSEC_PER_SEC 1000000000ull 
 293 #define USEC_PER_SEC 1000000ull 
 294 #define NSEC_PER_USEC 1000ull 
 296 /* I wish we had __builtin_expect_range() */ 
 298 #define fastpath(x) ((typeof(x))__builtin_expect((long)(x), ~0l)) 
 299 #define slowpath(x) ((typeof(x))__builtin_expect((long)(x), 0l)) 
 301 #define fastpath(x) (x) 
 302 #define slowpath(x) (x) 
 306 // sys/queue.h debugging 
 308 #define TRASHIT(x) do {(x) = (void *)-1;} while (0) 
 309 #endif // DISPATCH_DEBUG 
 310 #define _TAILQ_TRASH_ENTRY(elm, field) do { \ 
 311                         TRASHIT((elm)->field.tqe_next); \ 
 312                         TRASHIT((elm)->field.tqe_prev); \ 
 314 #define _TAILQ_TRASH_HEAD(head) do { \ 
 315                         TRASHIT((head)->tqh_first); \ 
 316                         TRASHIT((head)->tqh_last); \ 
 320 void _dispatch_bug(size_t line
, long val
); 
 324 void _dispatch_bug_client(const char* msg
); 
 326 void _dispatch_bug_mach_client(const char *msg
, mach_msg_return_t kr
); 
 328 void _dispatch_bug_kevent_client(const char* msg
, const char* filter
, 
 329                 const char *operation
, int err
); 
 332 DISPATCH_NOINLINE DISPATCH_NORETURN
 
 333 void _dispatch_abort(size_t line
, long val
); 
 335 #if !defined(DISPATCH_USE_OS_DEBUG_LOG) && DISPATCH_DEBUG 
 336 #if __has_include(<os/debug_private.h>) 
 337 #define DISPATCH_USE_OS_DEBUG_LOG 1 
 338 #include <os/debug_private.h> 
 340 #endif // DISPATCH_USE_OS_DEBUG_LOG 
 342 #if !defined(DISPATCH_USE_SIMPLE_ASL) && !DISPATCH_USE_OS_DEBUG_LOG 
 343 #if __has_include(<_simple.h>) 
 344 #define DISPATCH_USE_SIMPLE_ASL 1 
 347 #endif // DISPATCH_USE_SIMPLE_ASL 
 349 #if !DISPATCH_USE_SIMPLE_ASL && !DISPATCH_USE_OS_DEBUG_LOG && !TARGET_OS_WIN32 
 353 #if DISPATCH_USE_OS_DEBUG_LOG 
 354 #define _dispatch_log(msg, ...) os_debug_log("libdispatch", msg, ## __VA_ARGS__) 
 356 DISPATCH_NOINLINE 
__attribute__((__format__(__printf__
,1,2))) 
 357 void _dispatch_log(const char *msg
, ...); 
 358 #endif // DISPATCH_USE_OS_DEBUG_LOG 
 360 #define dsnprintf(...) \ 
 361                 ({ int _r = snprintf(__VA_ARGS__); _r < 0 ? 0u : (size_t)_r; }) 
 364 #define dispatch_static_assert(e) ({ \ 
 365                 char __compile_time_assert__[(bool)(e) ? 1 : -1] DISPATCH_UNUSED; \ 
 368 #define dispatch_static_assert(e) 
 372  * For reporting bugs within libdispatch when using the "_debug" version of the 
 376 #define dispatch_assert(e) do { \ 
 377                 if (__builtin_constant_p(e)) { \ 
 378                         dispatch_static_assert(e); \ 
 380                         typeof(e) _e = fastpath(e); /* always eval 'e' */ \ 
 381                         if (DISPATCH_DEBUG && !_e) { \ 
 382                                 _dispatch_abort(__LINE__, (long)_e); \ 
 387 static inline void _dispatch_assert(long e
, long line
) { 
 388         if (DISPATCH_DEBUG 
&& !e
) _dispatch_abort(line
, e
); 
 390 #define dispatch_assert(e) _dispatch_assert((long)(e), __LINE__) 
 391 #endif  /* __GNUC__ */ 
 395  * A lot of API return zero upon success and not-zero on fail. Let's capture 
 396  * and log the non-zero value 
 398 #define dispatch_assert_zero(e) do { \ 
 399                 if (__builtin_constant_p(e)) { \ 
 400                         dispatch_static_assert(e); \ 
 402                         typeof(e) _e = slowpath(e); /* always eval 'e' */ \ 
 403                         if (DISPATCH_DEBUG && _e) { \ 
 404                                 _dispatch_abort(__LINE__, (long)_e); \ 
 409 static inline void _dispatch_assert_zero(long e
, long line
) { 
 410         if (DISPATCH_DEBUG 
&& e
) _dispatch_abort(line
, e
); 
 412 #define dispatch_assert_zero(e) _dispatch_assert((long)(e), __LINE__)  
 413 #endif  /* __GNUC__ */ 
 416  * For reporting bugs or impedance mismatches between libdispatch and external 
 417  * subsystems. These do NOT abort(), and are always compiled into the product. 
 419  * In particular, we wrap all system-calls with assume() macros. 
 422 #define dispatch_assume(e) ({ \ 
 423                 typeof(e) _e = fastpath(e); /* always eval 'e' */ \ 
 425                         if (__builtin_constant_p(e)) { \ 
 426                                 dispatch_static_assert(e); \ 
 428                         _dispatch_bug(__LINE__, (long)_e); \ 
 433 static inline long _dispatch_assume(long e
, long line
) { 
 434         if (!e
) _dispatch_bug(line
, e
); 
 437 #define dispatch_assume(e) _dispatch_assume((long)(e), __LINE__) 
 438 #endif  /* __GNUC__ */ 
 441  * A lot of API return zero upon success and not-zero on fail. Let's capture 
 442  * and log the non-zero value 
 445 #define dispatch_assume_zero(e) ({ \ 
 446                 typeof(e) _e = slowpath(e); /* always eval 'e' */ \ 
 448                         if (__builtin_constant_p(e)) { \ 
 449                                 dispatch_static_assert(e); \ 
 451                         _dispatch_bug(__LINE__, (long)_e); \ 
 456 static inline long _dispatch_assume_zero(long e
, long line
) { 
 457         if (e
) _dispatch_bug(line
, e
); 
 460 #define dispatch_assume_zero(e) _dispatch_assume_zero((long)(e), __LINE__) 
 461 #endif  /* __GNUC__ */ 
 464  * For reporting bugs in clients when using the "_debug" version of the library. 
 467 #define dispatch_debug_assert(e, msg, args...) do { \ 
 468                 if (__builtin_constant_p(e)) { \ 
 469                         dispatch_static_assert(e); \ 
 471                         typeof(e) _e = fastpath(e); /* always eval 'e' */ \ 
 472                         if (DISPATCH_DEBUG && !_e) { \ 
 473                                 _dispatch_log("%s() 0x%lx: " msg, __func__, (long)_e, ##args); \ 
 479 #define dispatch_debug_assert(e, msg, args...) do { \ 
 480         long _e = (long)fastpath(e); /* always eval 'e' */ \ 
 481         if (DISPATCH_DEBUG && !_e) { \ 
 482                 _dispatch_log("%s() 0x%lx: " msg, __FUNCTION__, _e, ##args); \ 
 486 #endif  /* __GNUC__ */ 
 488 /* Make sure the debug statments don't get too stale */ 
 489 #define _dispatch_debug(x, args...) do { \ 
 490         if (DISPATCH_DEBUG) { \ 
 491                 _dispatch_log("%u\t%p\t" x, __LINE__, \ 
 492                                 (void *)_dispatch_thread_self(), ##args); \ 
 498 DISPATCH_NOINLINE DISPATCH_USED
 
 499 void dispatch_debug_machport(mach_port_t name
, const char* str
); 
 504 /* This is the private version of the deprecated dispatch_debug() */ 
 505 DISPATCH_NONNULL2 DISPATCH_NOTHROW
 
 506 __attribute__((__format__(printf
,2,3))) 
 508 _dispatch_object_debug(dispatch_object_t object
, const char *message
, ...); 
 510 #define _dispatch_object_debug(object, message, ...) 
 511 #endif // DISPATCH_DEBUG 
 514 #define _dispatch_Block_invoke(bb) \ 
 515                 ((dispatch_function_t)((struct Block_layout *)bb)->invoke) 
 517 dispatch_block_t 
_dispatch_Block_copy(dispatch_block_t block
); 
 518 #define _dispatch_Block_copy(x) ((typeof(x))_dispatch_Block_copy(x)) 
 520 dispatch_block_t 
_dispatch_Block_copy(const void *block
); 
 522 void _dispatch_call_block_and_release(void *block
); 
 523 #endif /* __BLOCKS__ */ 
 525 void _dispatch_temporary_resource_shortage(void); 
 526 void *_dispatch_calloc(size_t num_items
, size_t size
); 
 527 void _dispatch_vtable_init(void); 
 528 char *_dispatch_get_build(void); 
 530 uint64_t _dispatch_timeout(dispatch_time_t when
); 
 532 extern bool _dispatch_safe_fork
, _dispatch_child_of_unsafe_fork
; 
 534 #if !defined(DISPATCH_USE_OS_SEMAPHORE_CACHE) && !(TARGET_IPHONE_SIMULATOR) 
 535 // rdar://problem/15492045 
 536 #if __has_include(<os/semaphore_private.h>) 
 537 #define DISPATCH_USE_OS_SEMAPHORE_CACHE 1 
 538 #include <os/semaphore_private.h> 
 542 /* #includes dependent on internal.h */ 
 545 // Older Mac OS X and iOS Simulator fallbacks 
 547 #if HAVE_PTHREAD_WORKQUEUES 
 548 #ifndef WORKQ_ADDTHREADS_OPTION_OVERCOMMIT 
 549 #define WORKQ_ADDTHREADS_OPTION_OVERCOMMIT 0x00000001 
 551 #if TARGET_IPHONE_SIMULATOR && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1080 
 552 #ifndef DISPATCH_USE_LEGACY_WORKQUEUE_FALLBACK 
 553 #define DISPATCH_USE_LEGACY_WORKQUEUE_FALLBACK 1 
 556 #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 1080 
 557 #undef HAVE_PTHREAD_WORKQUEUE_SETDISPATCH_NP 
 558 #define HAVE_PTHREAD_WORKQUEUE_SETDISPATCH_NP 0 
 560 #if TARGET_IPHONE_SIMULATOR && \ 
 561                 IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 101000 
 562 #ifndef DISPATCH_USE_NOQOS_WORKQUEUE_FALLBACK 
 563 #define DISPATCH_USE_NOQOS_WORKQUEUE_FALLBACK 1 
 566 #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 101000 
 567 #undef HAVE__PTHREAD_WORKQUEUE_INIT 
 568 #define HAVE__PTHREAD_WORKQUEUE_INIT 0 
 570 #endif // HAVE_PTHREAD_WORKQUEUES 
 571 #if HAVE__PTHREAD_WORKQUEUE_INIT && PTHREAD_WORKQUEUE_SPI_VERSION >= 20140213 \ 
 572                 && !defined(HAVE_PTHREAD_WORKQUEUE_QOS) 
 573 #define HAVE_PTHREAD_WORKQUEUE_QOS 1 
 577 #if !defined(MACH_NOTIFY_SEND_POSSIBLE) || (TARGET_IPHONE_SIMULATOR && \ 
 578                 IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1070) 
 579 #undef MACH_NOTIFY_SEND_POSSIBLE 
 580 #define MACH_NOTIFY_SEND_POSSIBLE MACH_NOTIFY_DEAD_NAME 
 584 #ifdef EVFILT_MEMORYSTATUS 
 585 #ifndef DISPATCH_USE_MEMORYSTATUS 
 586 #define DISPATCH_USE_MEMORYSTATUS 1 
 588 #endif // EVFILT_MEMORYSTATUS 
 590 #if defined(EVFILT_VM) && !DISPATCH_USE_MEMORYSTATUS 
 591 #ifndef DISPATCH_USE_VM_PRESSURE 
 592 #define DISPATCH_USE_VM_PRESSURE 1 
 596 #if TARGET_IPHONE_SIMULATOR 
 597 #undef DISPATCH_USE_MEMORYSTATUS_SOURCE 
 598 #define DISPATCH_USE_MEMORYSTATUS_SOURCE 0 
 599 #undef DISPATCH_USE_VM_PRESSURE_SOURCE 
 600 #define DISPATCH_USE_VM_PRESSURE_SOURCE 0 
 601 #endif // TARGET_IPHONE_SIMULATOR 
 602 #if !defined(DISPATCH_USE_MEMORYSTATUS_SOURCE) && DISPATCH_USE_MEMORYSTATUS 
 603 #define DISPATCH_USE_MEMORYSTATUS_SOURCE 1 
 604 #elif !defined(DISPATCH_USE_VM_PRESSURE_SOURCE) && DISPATCH_USE_VM_PRESSURE 
 605 #define DISPATCH_USE_VM_PRESSURE_SOURCE 1 
 608 #if !defined(NOTE_LEEWAY) || (TARGET_IPHONE_SIMULATOR && \ 
 609                 IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1090) 
 611 #define NOTE_LEEWAY 0 
 613 #define NOTE_CRITICAL 0 
 614 #undef NOTE_BACKGROUND 
 615 #define NOTE_BACKGROUND 0 
 616 #endif // NOTE_LEEWAY 
 618 #if HAVE_DECL_NOTE_REAP 
 619 #if defined(NOTE_REAP) && defined(__APPLE__) 
 621 #define NOTE_REAP 0x10000000 // <rdar://problem/13338526> 
 623 #endif // HAVE_DECL_NOTE_REAP 
 625 #if !defined(EV_UDATA_SPECIFIC) || (TARGET_IPHONE_SIMULATOR && \ 
 626                 IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 101100) || \ 
 627                 (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 101100) 
 628 #undef DISPATCH_USE_EV_UDATA_SPECIFIC 
 629 #define DISPATCH_USE_EV_UDATA_SPECIFIC 0 
 630 #elif !defined(DISPATCH_USE_EV_UDATA_SPECIFIC) 
 631 #define DISPATCH_USE_EV_UDATA_SPECIFIC 1 
 632 #endif // EV_UDATA_SPECIFIC 
 634 #if !DISPATCH_USE_EV_UDATA_SPECIFIC 
 635 #undef EV_UDATA_SPECIFIC 
 636 #define EV_UDATA_SPECIFIC 0 
 637 #undef DISPATCH_DYNAMIC_SELECT_FALLBACK 
 638 #define DISPATCH_DYNAMIC_SELECT_FALLBACK 0 
 639 #undef DISPATCH_USE_SELECT_FALLBACK 
 640 #define DISPATCH_USE_SELECT_FALLBACK 1 
 641 #endif // !DISPATCH_USE_EV_UDATA_SPECIFIC 
 643 #if !defined(EV_SET_QOS) || (TARGET_IPHONE_SIMULATOR && \ 
 644                 IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 101100) || \ 
 645                 (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 101100) 
 646 #undef DISPATCH_USE_KEVENT_QOS 
 647 #define DISPATCH_USE_KEVENT_QOS 0 
 648 #elif !defined(DISPATCH_USE_KEVENT_QOS) 
 649 #define DISPATCH_USE_KEVENT_QOS 1 
 652 #if DISPATCH_USE_KEVENT_QOS 
 653 typedef struct kevent_qos_s _dispatch_kevent_qos_s
; 
 654 #else // DISPATCH_USE_KEVENT_QOS 
 655 #ifndef KEVENT_FLAG_IMMEDIATE 
 656 #define KEVENT_FLAG_NONE 0x00 
 657 #define KEVENT_FLAG_IMMEDIATE 0x01 
 658 #define KEVENT_FLAG_ERROR_EVENTS 0x02 
 659 #endif // KEVENT_FLAG_IMMEDIATE 
 660 typedef struct kevent64_s _dispatch_kevent_qos_s
; 
 661 #define kevent_qos(_kq, _changelist, _nchanges, _eventlist, _nevents, \ 
 662                 _data_out, _data_available, _flags) \ 
 663                 ({ unsigned int _f = (_flags); _dispatch_kevent_qos_s _kev_copy; \ 
 664                 const _dispatch_kevent_qos_s *_cl = (_changelist); \ 
 665                 int _n = (_nchanges); const struct timespec _timeout_immediately = {}; \ 
 666                 dispatch_static_assert(!(_data_out) && !(_data_available)); \ 
 667                 if (_f & KEVENT_FLAG_ERROR_EVENTS) { \ 
 668                         dispatch_static_assert(_n == 1); \ 
 669                         _kev_copy = *_cl; _kev_copy.flags |= EV_RECEIPT; } \ 
 670                 kevent64((_kq), _f & KEVENT_FLAG_ERROR_EVENTS ? &_kev_copy : _cl, _n, \ 
 671                         (_eventlist), (_nevents), 0, \ 
 672                         _f & KEVENT_FLAG_IMMEDIATE ? &_timeout_immediately : NULL); }) 
 673 #endif // DISPATCH_USE_KEVENT_QOS 
 675 #if defined(F_SETNOSIGPIPE) && defined(F_GETNOSIGPIPE) 
 676 #if TARGET_IPHONE_SIMULATOR && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1070 
 677 #undef DISPATCH_USE_SETNOSIGPIPE 
 678 #define DISPATCH_USE_SETNOSIGPIPE 0 
 680 #ifndef DISPATCH_USE_SETNOSIGPIPE 
 681 #define DISPATCH_USE_SETNOSIGPIPE 1 
 683 #endif // F_SETNOSIGPIPE 
 685 #if defined(MACH_SEND_NOIMPORTANCE) 
 686 #ifndef DISPATCH_USE_CHECKIN_NOIMPORTANCE 
 687 #define DISPATCH_USE_CHECKIN_NOIMPORTANCE 1 // rdar://problem/16996737 
 689 #ifndef DISPATCH_USE_NOIMPORTANCE_QOS 
 690 #define DISPATCH_USE_NOIMPORTANCE_QOS 1 // rdar://problem/21414476 
 692 #endif // MACH_SEND_NOIMPORTANCE 
 695 #if HAVE_LIBPROC_INTERNAL_H 
 697 #include <libproc_internal.h> 
 698 #if TARGET_IPHONE_SIMULATOR && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1090 
 699 #undef DISPATCH_USE_IMPORTANCE_ASSERTION 
 700 #define DISPATCH_USE_IMPORTANCE_ASSERTION 0 
 702 #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 1090 
 703 #undef DISPATCH_USE_IMPORTANCE_ASSERTION 
 704 #define DISPATCH_USE_IMPORTANCE_ASSERTION 0 
 706 #ifndef DISPATCH_USE_IMPORTANCE_ASSERTION 
 707 #define DISPATCH_USE_IMPORTANCE_ASSERTION 1 
 709 #endif // HAVE_LIBPROC_INTERNAL_H 
 711 #if HAVE_SYS_GUARDED_H 
 712 #include <sys/guarded.h> 
 713 #if TARGET_IPHONE_SIMULATOR && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1090 
 714 #undef DISPATCH_USE_GUARDED_FD 
 715 #define DISPATCH_USE_GUARDED_FD 0 
 717 #ifndef DISPATCH_USE_GUARDED_FD 
 718 #define DISPATCH_USE_GUARDED_FD 1 
 720 // change_fdguard_np() requires GUARD_DUP <rdar://problem/11814513> 
 721 #if DISPATCH_USE_GUARDED_FD && RDAR_11814513 
 722 #define DISPATCH_USE_GUARDED_FD_CHANGE_FDGUARD 1 
 724 #endif // HAVE_SYS_GUARDED_H 
 727 #ifndef MACH_MSGH_BITS_VOUCHER_MASK 
 728 #define MACH_MSGH_BITS_VOUCHER_MASK     0x001f0000 
 729 #define MACH_MSGH_BITS_SET_PORTS(remote, local, voucher)        \ 
 730         (((remote) & MACH_MSGH_BITS_REMOTE_MASK) |              \ 
 731          (((local) << 8) & MACH_MSGH_BITS_LOCAL_MASK) |         \ 
 732          (((voucher) << 16) & MACH_MSGH_BITS_VOUCHER_MASK)) 
 733 #define MACH_MSGH_BITS_VOUCHER(bits)                            \ 
 734                 (((bits) & MACH_MSGH_BITS_VOUCHER_MASK) >> 16) 
 735 #define MACH_MSGH_BITS_HAS_VOUCHER(bits)                        \ 
 736         (MACH_MSGH_BITS_VOUCHER(bits) != MACH_MSGH_BITS_ZERO) 
 737 #define msgh_voucher_port msgh_reserved 
 738 #define mach_voucher_t mach_port_t 
 739 #define MACH_VOUCHER_NULL MACH_PORT_NULL 
 740 #define MACH_SEND_INVALID_VOUCHER 0x10000005 
 743 #define _dispatch_hardware_crash() \ 
 744                 __asm__(""); __builtin_trap() // <rdar://problem/17464981> 
 746 #define _dispatch_set_crash_log_message(msg) 
 747 #define _dispatch_set_crash_log_message_dynamic(msg) 
 750 // MIG_REPLY_MISMATCH means either: 
 751 // 1) A signal handler is NOT using async-safe API. See the sigaction(2) man 
 752 //    page for more info. 
 753 // 2) A hand crafted call to mach_msg*() screwed up. Use MIG. 
 754 #define DISPATCH_VERIFY_MIG(x) do { \ 
 755                 if ((x) == MIG_REPLY_MISMATCH) { \ 
 756                         _dispatch_set_crash_log_message("MIG_REPLY_MISMATCH"); \ 
 757                         _dispatch_hardware_crash(); \ 
 762 #define DISPATCH_CRASH(x) do { \ 
 763                 _dispatch_set_crash_log_message("BUG IN LIBDISPATCH: " x); \ 
 764                 _dispatch_hardware_crash(); \ 
 767 #define DISPATCH_CLIENT_CRASH(x) do { \ 
 768                 _dispatch_set_crash_log_message("BUG IN CLIENT OF LIBDISPATCH: " x); \ 
 769                 _dispatch_hardware_crash(); \ 
 772 #define _OS_OBJECT_CLIENT_CRASH(x) do { \ 
 773                 _dispatch_set_crash_log_message("API MISUSE: " x); \ 
 774                 _dispatch_hardware_crash(); \ 
 777 extern int _dispatch_set_qos_class_enabled
; 
 778 #define DISPATCH_NO_VOUCHER ((voucher_t)(void*)~0ul) 
 779 #define DISPATCH_NO_PRIORITY ((pthread_priority_t)~0ul) 
 780 #define DISPATCH_PRIORITY_ENFORCE 0x1 
 781 #define DISPATCH_VOUCHER_IGNORE_QUEUE_OVERRIDE 0x2 
 782 static inline void _dispatch_adopt_priority_and_replace_voucher( 
 783                 pthread_priority_t priority
, voucher_t voucher
, unsigned long flags
); 
 785 static inline void _dispatch_set_priority_and_mach_voucher( 
 786                 pthread_priority_t priority
, mach_voucher_t kv
); 
 787 mach_port_t 
_dispatch_get_mach_host_port(void); 
 791 /* #includes dependent on internal.h */ 
 792 #include "object_internal.h" 
 793 #include "semaphore_internal.h" 
 794 #include "introspection_internal.h" 
 795 #include "queue_internal.h" 
 796 #include "source_internal.h" 
 797 #include "voucher_internal.h" 
 798 #include "data_internal.h" 
 800 #include "io_internal.h" 
 802 #include "inline_internal.h" 
 804 #endif /* __DISPATCH_INTERNAL__ */