1/* 2 * Copyright (c) 2008-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_INTERNAL__ 28#define __DISPATCH_INTERNAL__ 29 30#include <config/config.h> 31 32#define __DISPATCH_BUILDING_DISPATCH__ 33#define __DISPATCH_INDIRECT__ 34 35#ifdef __APPLE__ 36#include <Availability.h> 37#include <TargetConditionals.h> 38#endif 39 40 41#if !defined(DISPATCH_MACH_SPI) && TARGET_OS_MAC 42#define DISPATCH_MACH_SPI 1 43#endif 44 45#if !defined(USE_OBJC) && HAVE_OBJC 46#define USE_OBJC 1 47#endif 48 49#if USE_OBJC && ((!TARGET_IPHONE_SIMULATOR && defined(__i386__)) || \ 50 (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 1080)) 51// Disable Objective-C support on platforms with legacy objc runtime 52#undef USE_OBJC 53#define USE_OBJC 0 54#endif 55 56#if USE_OBJC 57#define OS_OBJECT_HAVE_OBJC_SUPPORT 1 58#if __OBJC__ 59#define OS_OBJECT_USE_OBJC 1 60#else 61#define OS_OBJECT_USE_OBJC 0 62#endif // __OBJC__ 63#else 64#define OS_OBJECT_HAVE_OBJC_SUPPORT 0 65#endif // USE_OBJC 66 67#include <dispatch/dispatch.h> 68#include <dispatch/base.h> 69 70 71#include <os/object.h> 72#include <dispatch/object.h> 73#include <dispatch/time.h> 74#include <dispatch/queue.h> 75#include <dispatch/source.h> 76#include <dispatch/group.h> 77#include <dispatch/semaphore.h> 78#include <dispatch/once.h> 79#include <dispatch/data.h> 80#if !TARGET_OS_WIN32 81#include <dispatch/io.h> 82#endif 83 84#define DISPATCH_STRUCT_DECL(type, name, ...) \ 85 struct type __VA_ARGS__ name 86 87// Visual Studio C++ does not support C99 designated initializers. 88// This means that static declarations should be zero initialized and cannot 89// be const since we must fill in the values during DLL initialization. 90#if !TARGET_OS_WIN32 91#define DISPATCH_STRUCT_INSTANCE(type, name, ...) \ 92struct type name = { \ 93__VA_ARGS__ \ 94} 95#else 96#define DISPATCH_STRUCT_INSTANCE(type, name, ...) \ 97struct type name = { 0 } 98#endif 99 100#if !TARGET_OS_WIN32 101#define DISPATCH_CONST_STRUCT_DECL(type, name, ...) \ 102 const DISPATCH_STRUCT_DECL(type, name, __VA_ARGS__) 103 104#define DISPATCH_CONST_STRUCT_INSTANCE(type, name, ...) \ 105 const DISPATCH_STRUCT_INSTANCE(type, name, __VA_ARGS__) 106#else 107#define DISPATCH_CONST_STRUCT_DECL(type, name, ...) \ 108 DISPATCH_STRUCT_DECL(type, name, __VA_ARGS__) 109 110#define DISPATCH_CONST_STRUCT_INSTANCE(type, name, ...) \ 111 DISPATCH_STRUCT_INSTANCE(type, name, __VA_ARGS__) 112#endif 113 114/* private.h must be included last to avoid picking up installed headers. */ 115#include "object_private.h" 116#include "queue_private.h" 117#include "source_private.h" 118#include "mach_private.h" 119#include "data_private.h" 120#if !TARGET_OS_WIN32 121#include "io_private.h" 122#endif 123#include "benchmark.h" 124#include "private.h" 125 126/* SPI for Libsystem-internal use */ 127DISPATCH_EXPORT DISPATCH_NOTHROW void libdispatch_init(void); 128#if !TARGET_OS_WIN32 129DISPATCH_EXPORT DISPATCH_NOTHROW void dispatch_atfork_prepare(void); 130DISPATCH_EXPORT DISPATCH_NOTHROW void dispatch_atfork_parent(void); 131DISPATCH_EXPORT DISPATCH_NOTHROW void dispatch_atfork_child(void); 132#endif 133 134/* More #includes at EOF (dependent on the contents of internal.h) ... */ 135 136// Abort on uncaught exceptions thrown from client callouts rdar://8577499 137#if !defined(DISPATCH_USE_CLIENT_CALLOUT) 138#define DISPATCH_USE_CLIENT_CALLOUT 1 139#endif 140 141/* The "_debug" library build */ 142#ifndef DISPATCH_DEBUG 143#define DISPATCH_DEBUG 0 144#endif 145 146#ifndef DISPATCH_PROFILE 147#define DISPATCH_PROFILE 0 148#endif 149 150#if (!TARGET_OS_EMBEDDED || DISPATCH_DEBUG || DISPATCH_PROFILE) && \ 151 !defined(DISPATCH_USE_DTRACE) 152#define DISPATCH_USE_DTRACE 1 153#endif 154 155#if ((!TARGET_OS_EMBEDDED && DISPATCH_INTROSPECTION) || DISPATCH_DEBUG || \ 156 DISPATCH_PROFILE) && !defined(DISPATCH_USE_DTRACE_INTROSPECTION) 157#define DISPATCH_USE_DTRACE_INTROSPECTION 1 158#endif 159 160#if HAVE_LIBKERN_OSCROSSENDIAN_H 161#include <libkern/OSCrossEndian.h> 162#endif 163#if HAVE_LIBKERN_OSATOMIC_H 164#include <libkern/OSAtomic.h> 165#endif 166#if HAVE_MACH 167#include <mach/boolean.h> 168#include <mach/clock_types.h> 169#include <mach/clock.h> 170#include <mach/exception.h> 171#include <mach/mach.h> 172#include <mach/mach_error.h> 173#include <mach/mach_host.h> 174#include <mach/mach_interface.h> 175#include <mach/mach_time.h> 176#include <mach/mach_traps.h> 177#include <mach/message.h> 178#include <mach/mig_errors.h> 179#include <mach/host_info.h> 180#include <mach/notify.h> 181#include <mach/mach_vm.h> 182#include <mach/vm_map.h> 183#endif /* HAVE_MACH */ 184#if HAVE_MALLOC_MALLOC_H 185#include <malloc/malloc.h> 186#endif 187 188#include <sys/stat.h> 189 190#if !TARGET_OS_WIN32 191#include <sys/event.h> 192#include <sys/mount.h> 193#include <sys/queue.h> 194#include <sys/sysctl.h> 195#include <sys/socket.h> 196#include <sys/time.h> 197#include <sys/mman.h> 198#include <netinet/in.h> 199#else 200#include "sys_queue.h" 201#endif 202 203#ifdef __BLOCKS__ 204#include <Block_private.h> 205#include <Block.h> 206#endif /* __BLOCKS__ */ 207 208#include <assert.h> 209#include <errno.h> 210#if HAVE_FCNTL_H 211#include <fcntl.h> 212#endif 213#include <limits.h> 214#include <search.h> 215#if USE_POSIX_SEM 216#include <semaphore.h> 217#endif 218#include <signal.h> 219#include <stdarg.h> 220#include <stdbool.h> 221#include <stdint.h> 222#include <stdio.h> 223#include <stdlib.h> 224#include <string.h> 225#if !TARGET_OS_WIN32 226#include <syslog.h> 227#endif 228#if HAVE_UNISTD_H 229#include <unistd.h> 230#endif 231 232#ifndef __has_builtin 233#define __has_builtin(x) 0 234#endif 235#ifndef __has_include 236#define __has_include(x) 0 237#endif 238#ifndef __has_feature 239#define __has_feature(x) 0 240#endif 241#ifndef __has_attribute 242#define __has_attribute(x) 0 243#endif 244 245#if __GNUC__ 246#define DISPATCH_NOINLINE __attribute__((__noinline__)) 247#define DISPATCH_USED __attribute__((__used__)) 248#define DISPATCH_UNUSED __attribute__((__unused__)) 249#define DISPATCH_WEAK __attribute__((__weak__)) 250#define DISPATCH_OVERLOADABLE __attribute__((__overloadable__)) 251#if DISPATCH_DEBUG 252#define DISPATCH_ALWAYS_INLINE_NDEBUG 253#else 254#define DISPATCH_ALWAYS_INLINE_NDEBUG __attribute__((__always_inline__)) 255#endif 256#else /* __GNUC__ */ 257#define DISPATCH_NOINLINE 258#define DISPATCH_USED 259#define DISPATCH_UNUSED 260#define DISPATCH_WEAK 261#define DISPATCH_ALWAYS_INLINE_NDEBUG 262#endif /* __GNUC__ */ 263 264#define DISPATCH_CONCAT(x,y) DISPATCH_CONCAT1(x,y) 265#define DISPATCH_CONCAT1(x,y) x ## y 266 267// workaround 6368156 268#ifdef NSEC_PER_SEC 269#undef NSEC_PER_SEC 270#endif 271#ifdef USEC_PER_SEC 272#undef USEC_PER_SEC 273#endif 274#ifdef NSEC_PER_USEC 275#undef NSEC_PER_USEC 276#endif 277#define NSEC_PER_SEC 1000000000ull 278#define USEC_PER_SEC 1000000ull 279#define NSEC_PER_USEC 1000ull 280 281/* I wish we had __builtin_expect_range() */ 282#if __GNUC__ 283#define fastpath(x) ((typeof(x))__builtin_expect((long)(x), ~0l)) 284#define slowpath(x) ((typeof(x))__builtin_expect((long)(x), 0l)) 285#else 286#define fastpath(x) (x) 287#define slowpath(x) (x) 288#endif // __GNUC__ 289 290DISPATCH_NOINLINE 291void _dispatch_bug(size_t line, long val); 292 293#if HAVE_MACH 294DISPATCH_NOINLINE 295void _dispatch_bug_client(const char* msg); 296DISPATCH_NOINLINE 297void _dispatch_bug_mach_client(const char *msg, mach_msg_return_t kr); 298DISPATCH_NOINLINE 299void _dispatch_bug_kevent_client(const char* msg, const char* filter, 300 const char *operation, int err); 301#endif 302 303DISPATCH_NOINLINE DISPATCH_NORETURN 304void _dispatch_abort(size_t line, long val); 305 306#if !defined(DISPATCH_USE_OS_TRACE) && DISPATCH_DEBUG 307#if __has_include(<os/trace.h>) 308#define DISPATCH_USE_OS_TRACE 1 309#include <os/trace.h> 310#endif 311#endif // DISPATCH_USE_OS_TRACE 312 313#if DISPATCH_USE_OS_TRACE 314#define _dispatch_log(msg, ...) os_trace("libdispatch", msg, ## __VA_ARGS__) 315#else 316DISPATCH_NOINLINE __attribute__((__format__(__printf__,1,2))) 317void _dispatch_log(const char *msg, ...); 318#endif // DISPATCH_USE_OS_TRACE 319 320#define dsnprintf(...) \ 321 ({ int _r = snprintf(__VA_ARGS__); _r < 0 ? 0u : (size_t)_r; }) 322 323/* 324 * For reporting bugs within libdispatch when using the "_debug" version of the 325 * library. 326 */ 327#if __GNUC__ 328#define dispatch_assert(e) do { \ 329 if (__builtin_constant_p(e)) { \ 330 char __compile_time_assert__[(bool)(e) ? 1 : -1] DISPATCH_UNUSED; \ 331 } else { \ 332 typeof(e) _e = fastpath(e); /* always eval 'e' */ \ 333 if (DISPATCH_DEBUG && !_e) { \ 334 _dispatch_abort(__LINE__, (long)_e); \ 335 } \ 336 } \ 337 } while (0) 338#else 339static inline void _dispatch_assert(long e, long line) { 340 if (DISPATCH_DEBUG && !e) _dispatch_abort(line, e); 341} 342#define dispatch_assert(e) _dispatch_assert((long)(e), __LINE__) 343#endif /* __GNUC__ */ 344 345#if __GNUC__ 346/* 347 * A lot of API return zero upon success and not-zero on fail. Let's capture 348 * and log the non-zero value 349 */ 350#define dispatch_assert_zero(e) do { \ 351 if (__builtin_constant_p(e)) { \ 352 char __compile_time_assert__[(bool)(e) ? -1 : 1] DISPATCH_UNUSED; \ 353 } else { \ 354 typeof(e) _e = slowpath(e); /* always eval 'e' */ \ 355 if (DISPATCH_DEBUG && _e) { \ 356 _dispatch_abort(__LINE__, (long)_e); \ 357 } \ 358 } \ 359 } while (0) 360#else 361static inline void _dispatch_assert_zero(long e, long line) { 362 if (DISPATCH_DEBUG && e) _dispatch_abort(line, e); 363} 364#define dispatch_assert_zero(e) _dispatch_assert((long)(e), __LINE__) 365#endif /* __GNUC__ */ 366 367/* 368 * For reporting bugs or impedance mismatches between libdispatch and external 369 * subsystems. These do NOT abort(), and are always compiled into the product. 370 * 371 * In particular, we wrap all system-calls with assume() macros. 372 */ 373#if __GNUC__ 374#define dispatch_assume(e) ({ \ 375 typeof(e) _e = fastpath(e); /* always eval 'e' */ \ 376 if (!_e) { \ 377 if (__builtin_constant_p(e)) { \ 378 char __compile_time_assert__[(bool)(e) ? 1 : -1]; \ 379 (void)__compile_time_assert__; \ 380 } \ 381 _dispatch_bug(__LINE__, (long)_e); \ 382 } \ 383 _e; \ 384 }) 385#else 386static inline long _dispatch_assume(long e, long line) { 387 if (!e) _dispatch_bug(line, e); 388 return e; 389} 390#define dispatch_assume(e) _dispatch_assume((long)(e), __LINE__) 391#endif /* __GNUC__ */ 392 393/* 394 * A lot of API return zero upon success and not-zero on fail. Let's capture 395 * and log the non-zero value 396 */ 397#if __GNUC__ 398#define dispatch_assume_zero(e) ({ \ 399 typeof(e) _e = slowpath(e); /* always eval 'e' */ \ 400 if (_e) { \ 401 if (__builtin_constant_p(e)) { \ 402 char __compile_time_assert__[(bool)(e) ? -1 : 1]; \ 403 (void)__compile_time_assert__; \ 404 } \ 405 _dispatch_bug(__LINE__, (long)_e); \ 406 } \ 407 _e; \ 408 }) 409#else 410static inline long _dispatch_assume_zero(long e, long line) { 411 if (e) _dispatch_bug(line, e); 412 return e; 413} 414#define dispatch_assume_zero(e) _dispatch_assume_zero((long)(e), __LINE__) 415#endif /* __GNUC__ */ 416 417/* 418 * For reporting bugs in clients when using the "_debug" version of the library. 419 */ 420#if __GNUC__ 421#define dispatch_debug_assert(e, msg, args...) do { \ 422 if (__builtin_constant_p(e)) { \ 423 char __compile_time_assert__[(bool)(e) ? 1 : -1] DISPATCH_UNUSED; \ 424 } else { \ 425 typeof(e) _e = fastpath(e); /* always eval 'e' */ \ 426 if (DISPATCH_DEBUG && !_e) { \ 427 _dispatch_log("%s() 0x%lx: " msg, __func__, (long)_e, ##args); \ 428 abort(); \ 429 } \ 430 } \ 431 } while (0) 432#else 433#define dispatch_debug_assert(e, msg, args...) do { \ 434 long _e = (long)fastpath(e); /* always eval 'e' */ \ 435 if (DISPATCH_DEBUG && !_e) { \ 436 _dispatch_log("%s() 0x%lx: " msg, __FUNCTION__, _e, ##args); \ 437 abort(); \ 438 } \ 439} while (0) 440#endif /* __GNUC__ */ 441 442/* Make sure the debug statments don't get too stale */ 443#define _dispatch_debug(x, args...) do { \ 444 if (DISPATCH_DEBUG) { \ 445 _dispatch_log("%u\t%p\t" x, __LINE__, \ 446 (void *)_dispatch_thread_self(), ##args); \ 447 } \ 448} while (0) 449 450#if DISPATCH_DEBUG 451#if HAVE_MACH 452DISPATCH_NOINLINE DISPATCH_USED 453void dispatch_debug_machport(mach_port_t name, const char* str); 454#endif 455#endif 456 457#if DISPATCH_DEBUG 458/* This is the private version of the deprecated dispatch_debug() */ 459DISPATCH_NONNULL2 DISPATCH_NOTHROW 460__attribute__((__format__(printf,2,3))) 461void 462_dispatch_object_debug(dispatch_object_t object, const char *message, ...); 463#else 464#define _dispatch_object_debug(object, message, ...) 465#endif // DISPATCH_DEBUG 466 467#if DISPATCH_USE_CLIENT_CALLOUT 468 469DISPATCH_NOTHROW void 470_dispatch_client_callout(void *ctxt, dispatch_function_t f); 471DISPATCH_NOTHROW void 472_dispatch_client_callout2(void *ctxt, size_t i, void (*f)(void *, size_t)); 473DISPATCH_NOTHROW bool 474_dispatch_client_callout3(void *ctxt, dispatch_data_t region, size_t offset, 475 const void *buffer, size_t size, dispatch_data_applier_function_t f); 476DISPATCH_NOTHROW void 477_dispatch_client_callout4(void *ctxt, dispatch_mach_reason_t reason, 478 dispatch_mach_msg_t dmsg, mach_error_t error, 479 dispatch_mach_handler_function_t f); 480 481#else // !DISPATCH_USE_CLIENT_CALLOUT 482 483DISPATCH_ALWAYS_INLINE 484static inline void 485_dispatch_client_callout(void *ctxt, dispatch_function_t f) 486{ 487 return f(ctxt); 488} 489 490DISPATCH_ALWAYS_INLINE 491static inline void 492_dispatch_client_callout2(void *ctxt, size_t i, void (*f)(void *, size_t)) 493{ 494 return f(ctxt, i); 495} 496 497DISPATCH_ALWAYS_INLINE 498static inline bool 499_dispatch_client_callout3(void *ctxt, dispatch_data_t region, size_t offset, 500 const void *buffer, size_t size, dispatch_data_applier_function_t f) 501{ 502 return f(ctxt, region, offset, buffer, size); 503} 504 505DISPATCH_ALWAYS_INLINE 506static inline void 507_dispatch_client_callout4(void *ctxt, dispatch_mach_reason_t reason, 508 dispatch_mach_msg_t dmsg, mach_error_t error, 509 dispatch_mach_handler_function_t f); 510{ 511 return f(ctxt, reason, dmsg, error); 512} 513 514#endif // !DISPATCH_USE_CLIENT_CALLOUT 515 516#ifdef __BLOCKS__ 517#define _dispatch_Block_invoke(bb) \ 518 ((dispatch_function_t)((struct Block_layout *)bb)->invoke) 519DISPATCH_ALWAYS_INLINE 520static inline void 521_dispatch_client_callout_block(dispatch_block_t b) 522{ 523 return _dispatch_client_callout(b, _dispatch_Block_invoke(b)); 524} 525 526#if __GNUC__ 527dispatch_block_t _dispatch_Block_copy(dispatch_block_t block); 528#define _dispatch_Block_copy(x) ((typeof(x))_dispatch_Block_copy(x)) 529#else 530dispatch_block_t _dispatch_Block_copy(const void *block); 531#endif 532 533void _dispatch_call_block_and_release(void *block); 534#endif /* __BLOCKS__ */ 535 536void _dispatch_temporary_resource_shortage(void); 537void *_dispatch_calloc(size_t num_items, size_t size); 538void _dispatch_vtable_init(void); 539char *_dispatch_get_build(void); 540 541uint64_t _dispatch_timeout(dispatch_time_t when); 542 543extern bool _dispatch_safe_fork, _dispatch_child_of_unsafe_fork; 544 545extern struct _dispatch_hw_config_s { 546 uint32_t cc_max_active; 547 uint32_t cc_max_logical; 548 uint32_t cc_max_physical; 549} _dispatch_hw_config; 550 551#if !defined(DISPATCH_USE_OS_SEMAPHORE_CACHE) && !(TARGET_IPHONE_SIMULATOR && \ 552 IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1090) 553#if __has_include(<os/semaphore_private.h>) 554#define DISPATCH_USE_OS_SEMAPHORE_CACHE 1 555#include <os/semaphore_private.h> 556#endif 557#endif 558 559/* #includes dependent on internal.h */ 560#include "shims.h" 561 562// Older Mac OS X and iOS Simulator fallbacks 563 564#if HAVE_PTHREAD_WORKQUEUES 565#ifndef WORKQ_BG_PRIOQUEUE 566#define WORKQ_BG_PRIOQUEUE 3 567#endif 568#ifndef WORKQ_ADDTHREADS_OPTION_OVERCOMMIT 569#define WORKQ_ADDTHREADS_OPTION_OVERCOMMIT 0x00000001 570#endif 571#if TARGET_IPHONE_SIMULATOR && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1070 572#ifndef DISPATCH_NO_BG_PRIORITY 573#define DISPATCH_NO_BG_PRIORITY 1 574#endif 575#endif 576#if TARGET_IPHONE_SIMULATOR && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1080 577#ifndef DISPATCH_USE_LEGACY_WORKQUEUE_FALLBACK 578#define DISPATCH_USE_LEGACY_WORKQUEUE_FALLBACK 1 579#endif 580#endif 581#if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 1080 582#undef HAVE_PTHREAD_WORKQUEUE_SETDISPATCH_NP 583#define HAVE_PTHREAD_WORKQUEUE_SETDISPATCH_NP 0 584#endif 585#endif // HAVE_PTHREAD_WORKQUEUES 586 587#if HAVE_MACH 588#if !defined(MACH_NOTIFY_SEND_POSSIBLE) || (TARGET_IPHONE_SIMULATOR && \ 589 IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1070) 590#undef MACH_NOTIFY_SEND_POSSIBLE 591#define MACH_NOTIFY_SEND_POSSIBLE MACH_NOTIFY_DEAD_NAME 592#endif 593#endif // HAVE_MACH 594 595#ifdef EVFILT_VM 596#ifndef DISPATCH_USE_VM_PRESSURE 597#define DISPATCH_USE_VM_PRESSURE 1 598#endif 599#endif // EVFILT_VM 600 601#ifdef EVFILT_MEMORYSTATUS 602#ifndef DISPATCH_USE_MEMORYSTATUS 603#define DISPATCH_USE_MEMORYSTATUS 1 604#endif 605#endif // EVFILT_MEMORYSTATUS 606 607#if TARGET_IPHONE_SIMULATOR && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1070 608#undef DISPATCH_USE_VM_PRESSURE_SOURCE 609#define DISPATCH_USE_VM_PRESSURE_SOURCE 0 610#endif // TARGET_IPHONE_SIMULATOR 611#if TARGET_OS_EMBEDDED 612#if !defined(DISPATCH_USE_VM_PRESSURE_SOURCE) && DISPATCH_USE_VM_PRESSURE 613#define DISPATCH_USE_VM_PRESSURE_SOURCE 1 614#endif 615#else // !TARGET_OS_EMBEDDED 616#if !defined(DISPATCH_USE_MEMORYSTATUS_SOURCE) && DISPATCH_USE_MEMORYSTATUS 617#define DISPATCH_USE_MEMORYSTATUS_SOURCE 1 618#elif !defined(DISPATCH_USE_VM_PRESSURE_SOURCE) && DISPATCH_USE_VM_PRESSURE 619#define DISPATCH_USE_VM_PRESSURE_SOURCE 1 620#endif 621#endif // TARGET_OS_EMBEDDED 622 623#if !defined(NOTE_LEEWAY) || (TARGET_IPHONE_SIMULATOR && \ 624 IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1090) 625#undef NOTE_LEEWAY 626#define NOTE_LEEWAY 0 627#undef NOTE_CRITICAL 628#define NOTE_CRITICAL 0 629#undef NOTE_BACKGROUND 630#define NOTE_BACKGROUND 0 631#endif // NOTE_LEEWAY 632 633#if HAVE_DECL_NOTE_REAP 634#if defined(NOTE_REAP) && defined(__APPLE__) 635#undef NOTE_REAP 636#define NOTE_REAP 0x10000000 // <rdar://problem/13338526> 637#endif 638#endif // HAVE_DECL_NOTE_REAP 639 640#if defined(F_SETNOSIGPIPE) && defined(F_GETNOSIGPIPE) 641#if TARGET_IPHONE_SIMULATOR && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1070 642#undef DISPATCH_USE_SETNOSIGPIPE 643#define DISPATCH_USE_SETNOSIGPIPE 0 644#endif 645#ifndef DISPATCH_USE_SETNOSIGPIPE 646#define DISPATCH_USE_SETNOSIGPIPE 1 647#endif 648#endif // F_SETNOSIGPIPE 649 650 651#if HAVE_LIBPROC_INTERNAL_H 652#include <libproc.h> 653#include <libproc_internal.h> 654#if TARGET_IPHONE_SIMULATOR && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1090 655#undef DISPATCH_USE_IMPORTANCE_ASSERTION 656#define DISPATCH_USE_IMPORTANCE_ASSERTION 0 657#endif 658#if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 1090 659#undef DISPATCH_USE_IMPORTANCE_ASSERTION 660#define DISPATCH_USE_IMPORTANCE_ASSERTION 0 661#endif 662#ifndef DISPATCH_USE_IMPORTANCE_ASSERTION 663#define DISPATCH_USE_IMPORTANCE_ASSERTION 1 664#endif 665#endif // HAVE_LIBPROC_INTERNAL_H 666 667#if HAVE_SYS_GUARDED_H 668#include <sys/guarded.h> 669#if TARGET_IPHONE_SIMULATOR && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1090 670#undef DISPATCH_USE_GUARDED_FD 671#define DISPATCH_USE_GUARDED_FD 0 672#endif 673#ifndef DISPATCH_USE_GUARDED_FD 674#define DISPATCH_USE_GUARDED_FD 1 675#endif 676// change_fdguard_np() requires GUARD_DUP <rdar://problem/11814513> 677#if DISPATCH_USE_GUARDED_FD && RDAR_11814513 678#define DISPATCH_USE_GUARDED_FD_CHANGE_FDGUARD 1 679#endif 680#endif // HAVE_SYS_GUARDED_H 681 682 683#define _dispatch_hardware_crash() __builtin_trap() 684 685#define _dispatch_set_crash_log_message(x) 686 687#if HAVE_MACH 688// MIG_REPLY_MISMATCH means either: 689// 1) A signal handler is NOT using async-safe API. See the sigaction(2) man 690// page for more info. 691// 2) A hand crafted call to mach_msg*() screwed up. Use MIG. 692#define DISPATCH_VERIFY_MIG(x) do { \ 693 if ((x) == MIG_REPLY_MISMATCH) { \ 694 _dispatch_set_crash_log_message("MIG_REPLY_MISMATCH"); \ 695 _dispatch_hardware_crash(); \ 696 } \ 697 } while (0) 698#endif 699 700#define DISPATCH_CRASH(x) do { \ 701 _dispatch_set_crash_log_message("BUG IN LIBDISPATCH: " x); \ 702 _dispatch_hardware_crash(); \ 703 } while (0) 704 705#define DISPATCH_CLIENT_CRASH(x) do { \ 706 _dispatch_set_crash_log_message("BUG IN CLIENT OF LIBDISPATCH: " x); \ 707 _dispatch_hardware_crash(); \ 708 } while (0) 709 710#define _OS_OBJECT_CLIENT_CRASH(x) do { \ 711 _dispatch_set_crash_log_message("API MISUSE: " x); \ 712 _dispatch_hardware_crash(); \ 713 } while (0) 714 715/* #includes dependent on internal.h */ 716#include "object_internal.h" 717#include "semaphore_internal.h" 718#include "introspection_internal.h" 719#include "queue_internal.h" 720#include "source_internal.h" 721#include "data_internal.h" 722#if !TARGET_OS_WIN32 723#include "io_internal.h" 724#endif 725#include "trace.h" 726 727#endif /* __DISPATCH_INTERNAL__ */ 728