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