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#if !defined(OS_VOUCHER_CREATION_SPI) && TARGET_OS_MAC
45#define OS_VOUCHER_CREATION_SPI 1
46#endif
47#if !defined(OS_VOUCHER_ACTIVITY_SPI) && TARGET_OS_MAC
48#define OS_VOUCHER_ACTIVITY_SPI 1
49#endif
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
53#endif
54#if !defined(DISPATCH_LAYOUT_SPI) && TARGET_OS_MAC
55#define DISPATCH_LAYOUT_SPI 1
56#endif
57
58#if !defined(USE_OBJC) && HAVE_OBJC
59#define USE_OBJC 1
60#endif
61
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
65#undef USE_OBJC
66#define USE_OBJC 0
67#endif
68
69#if USE_OBJC
70#define OS_OBJECT_HAVE_OBJC_SUPPORT 1
71#if __OBJC__
72#define OS_OBJECT_USE_OBJC 1
73#else
74#define OS_OBJECT_USE_OBJC 0
75#endif // __OBJC__
76#else
77#define OS_OBJECT_HAVE_OBJC_SUPPORT 0
78#endif // USE_OBJC
79
80#include <dispatch/dispatch.h>
81#include <dispatch/base.h>
82
83
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>
94#if !TARGET_OS_WIN32
95#include <dispatch/io.h>
96#endif
97
98#define DISPATCH_STRUCT_DECL(type, name, ...) \
99	struct type __VA_ARGS__ name
100
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.
104#if !TARGET_OS_WIN32
105#define DISPATCH_STRUCT_INSTANCE(type, name, ...) \
106struct type name = { \
107__VA_ARGS__ \
108}
109#else
110#define DISPATCH_STRUCT_INSTANCE(type, name, ...) \
111struct type name = { 0 }
112#endif
113
114#if !TARGET_OS_WIN32
115#define DISPATCH_CONST_STRUCT_DECL(type, name, ...) \
116	const DISPATCH_STRUCT_DECL(type, name, __VA_ARGS__)
117
118#define DISPATCH_CONST_STRUCT_INSTANCE(type, name, ...) \
119	const DISPATCH_STRUCT_INSTANCE(type, name, __VA_ARGS__)
120#else
121#define DISPATCH_CONST_STRUCT_DECL(type, name, ...) \
122	DISPATCH_STRUCT_DECL(type, name, __VA_ARGS__)
123
124#define DISPATCH_CONST_STRUCT_INSTANCE(type, name, ...) \
125	DISPATCH_STRUCT_INSTANCE(type, name, __VA_ARGS__)
126#endif
127
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"
134#if !TARGET_OS_WIN32
135#include "io_private.h"
136#endif
137#include "voucher_private.h"
138#include "voucher_activity_private.h"
139#include "layout_private.h"
140#include "benchmark.h"
141#include "private.h"
142
143/* SPI for Libsystem-internal use */
144DISPATCH_EXPORT DISPATCH_NOTHROW void libdispatch_init(void);
145#if !TARGET_OS_WIN32
146DISPATCH_EXPORT DISPATCH_NOTHROW void dispatch_atfork_prepare(void);
147DISPATCH_EXPORT DISPATCH_NOTHROW void dispatch_atfork_parent(void);
148DISPATCH_EXPORT DISPATCH_NOTHROW void dispatch_atfork_child(void);
149#endif
150
151/* More #includes at EOF (dependent on the contents of internal.h) ... */
152
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
156#endif
157
158/* The "_debug" library build */
159#ifndef DISPATCH_DEBUG
160#define DISPATCH_DEBUG 0
161#endif
162
163#ifndef DISPATCH_PROFILE
164#define DISPATCH_PROFILE 0
165#endif
166
167#if (!TARGET_OS_EMBEDDED || DISPATCH_DEBUG || DISPATCH_PROFILE) && \
168		!defined(DISPATCH_USE_DTRACE)
169#define DISPATCH_USE_DTRACE 1
170#endif
171
172#if DISPATCH_USE_DTRACE && (DISPATCH_INTROSPECTION || DISPATCH_DEBUG || \
173		DISPATCH_PROFILE) && !defined(DISPATCH_USE_DTRACE_INTROSPECTION)
174#define DISPATCH_USE_DTRACE_INTROSPECTION 1
175#endif
176
177#if HAVE_LIBKERN_OSCROSSENDIAN_H
178#include <libkern/OSCrossEndian.h>
179#endif
180#if HAVE_LIBKERN_OSATOMIC_H
181#include <libkern/OSAtomic.h>
182#endif
183#if HAVE_MACH
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>
204#endif
205
206#include <sys/stat.h>
207
208#if !TARGET_OS_WIN32
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>
217#else
218#include "sys_queue.h"
219#endif
220
221#ifdef __BLOCKS__
222#include <Block_private.h>
223#include <Block.h>
224#endif /* __BLOCKS__ */
225
226#include <assert.h>
227#include <errno.h>
228#if HAVE_FCNTL_H
229#include <fcntl.h>
230#endif
231#include <limits.h>
232#include <search.h>
233#if USE_POSIX_SEM
234#include <semaphore.h>
235#endif
236#include <signal.h>
237#include <stdarg.h>
238#include <stdbool.h>
239#include <stdint.h>
240#include <stdio.h>
241#include <stdlib.h>
242#include <string.h>
243#if HAVE_UNISTD_H
244#include <unistd.h>
245#endif
246
247#ifndef __has_builtin
248#define __has_builtin(x) 0
249#endif
250#ifndef __has_include
251#define __has_include(x) 0
252#endif
253#ifndef __has_feature
254#define __has_feature(x) 0
255#endif
256#ifndef __has_attribute
257#define __has_attribute(x) 0
258#endif
259
260#if __GNUC__
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__))
266#if DISPATCH_DEBUG
267#define DISPATCH_ALWAYS_INLINE_NDEBUG
268#else
269#define DISPATCH_ALWAYS_INLINE_NDEBUG __attribute__((__always_inline__))
270#endif
271#else	/* __GNUC__ */
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__ */
278
279#define DISPATCH_CONCAT(x,y) DISPATCH_CONCAT1(x,y)
280#define DISPATCH_CONCAT1(x,y) x ## y
281
282// workaround 6368156
283#ifdef NSEC_PER_SEC
284#undef NSEC_PER_SEC
285#endif
286#ifdef USEC_PER_SEC
287#undef USEC_PER_SEC
288#endif
289#ifdef NSEC_PER_USEC
290#undef NSEC_PER_USEC
291#endif
292#define NSEC_PER_SEC 1000000000ull
293#define USEC_PER_SEC 1000000ull
294#define NSEC_PER_USEC 1000ull
295
296/* I wish we had __builtin_expect_range() */
297#if __GNUC__
298#define fastpath(x) ((typeof(x))__builtin_expect((long)(x), ~0l))
299#define slowpath(x) ((typeof(x))__builtin_expect((long)(x), 0l))
300#else
301#define fastpath(x) (x)
302#define slowpath(x) (x)
303#endif // __GNUC__
304
305DISPATCH_NOINLINE
306void _dispatch_bug(size_t line, long val);
307
308#if HAVE_MACH
309DISPATCH_NOINLINE
310void _dispatch_bug_client(const char* msg);
311DISPATCH_NOINLINE
312void _dispatch_bug_mach_client(const char *msg, mach_msg_return_t kr);
313DISPATCH_NOINLINE
314void _dispatch_bug_kevent_client(const char* msg, const char* filter,
315		const char *operation, int err);
316#endif
317
318DISPATCH_NOINLINE DISPATCH_NORETURN
319void _dispatch_abort(size_t line, long val);
320
321#if !defined(DISPATCH_USE_OS_DEBUG_LOG) && DISPATCH_DEBUG
322#if __has_include(<os/debug_private.h>)
323#define DISPATCH_USE_OS_DEBUG_LOG 1
324#include <os/debug_private.h>
325#endif
326#endif // DISPATCH_USE_OS_DEBUG_LOG
327
328#if !defined(DISPATCH_USE_SIMPLE_ASL) && !DISPATCH_USE_OS_DEBUG_LOG
329#if __has_include(<_simple.h>)
330#define DISPATCH_USE_SIMPLE_ASL 1
331#include <_simple.h>
332#endif
333#endif // DISPATCH_USE_SIMPLE_ASL
334
335#if !DISPATCH_USE_SIMPLE_ASL && !DISPATCH_USE_OS_DEBUG_LOG && !TARGET_OS_WIN32
336#include <syslog.h>
337#endif
338
339#if DISPATCH_USE_OS_DEBUG_LOG
340#define _dispatch_log(msg, ...) os_debug_log("libdispatch", msg, ## __VA_ARGS__)
341#else
342DISPATCH_NOINLINE __attribute__((__format__(__printf__,1,2)))
343void _dispatch_log(const char *msg, ...);
344#endif // DISPATCH_USE_OS_DEBUG_LOG
345
346#define dsnprintf(...) \
347		({ int _r = snprintf(__VA_ARGS__); _r < 0 ? 0u : (size_t)_r; })
348
349/*
350 * For reporting bugs within libdispatch when using the "_debug" version of the
351 * library.
352 */
353#if __GNUC__
354#define dispatch_assert(e) do { \
355		if (__builtin_constant_p(e)) { \
356			char __compile_time_assert__[(bool)(e) ? 1 : -1] DISPATCH_UNUSED; \
357		} else { \
358			typeof(e) _e = fastpath(e); /* always eval 'e' */ \
359			if (DISPATCH_DEBUG && !_e) { \
360				_dispatch_abort(__LINE__, (long)_e); \
361			} \
362		} \
363	} while (0)
364#else
365static inline void _dispatch_assert(long e, long line) {
366	if (DISPATCH_DEBUG && !e) _dispatch_abort(line, e);
367}
368#define dispatch_assert(e) _dispatch_assert((long)(e), __LINE__)
369#endif	/* __GNUC__ */
370
371#if __GNUC__
372/*
373 * A lot of API return zero upon success and not-zero on fail. Let's capture
374 * and log the non-zero value
375 */
376#define dispatch_assert_zero(e) do { \
377		if (__builtin_constant_p(e)) { \
378			char __compile_time_assert__[(bool)(e) ? -1 : 1] DISPATCH_UNUSED; \
379		} else { \
380			typeof(e) _e = slowpath(e); /* always eval 'e' */ \
381			if (DISPATCH_DEBUG && _e) { \
382				_dispatch_abort(__LINE__, (long)_e); \
383			} \
384		} \
385	} while (0)
386#else
387static inline void _dispatch_assert_zero(long e, long line) {
388	if (DISPATCH_DEBUG && e) _dispatch_abort(line, e);
389}
390#define dispatch_assert_zero(e) _dispatch_assert((long)(e), __LINE__)
391#endif	/* __GNUC__ */
392
393/*
394 * For reporting bugs or impedance mismatches between libdispatch and external
395 * subsystems. These do NOT abort(), and are always compiled into the product.
396 *
397 * In particular, we wrap all system-calls with assume() macros.
398 */
399#if __GNUC__
400#define dispatch_assume(e) ({ \
401		typeof(e) _e = fastpath(e); /* always eval 'e' */ \
402		if (!_e) { \
403			if (__builtin_constant_p(e)) { \
404				char __compile_time_assert__[(bool)(e) ? 1 : -1]; \
405				(void)__compile_time_assert__; \
406			} \
407			_dispatch_bug(__LINE__, (long)_e); \
408		} \
409		_e; \
410	})
411#else
412static inline long _dispatch_assume(long e, long line) {
413	if (!e) _dispatch_bug(line, e);
414	return e;
415}
416#define dispatch_assume(e) _dispatch_assume((long)(e), __LINE__)
417#endif	/* __GNUC__ */
418
419/*
420 * A lot of API return zero upon success and not-zero on fail. Let's capture
421 * and log the non-zero value
422 */
423#if __GNUC__
424#define dispatch_assume_zero(e) ({ \
425		typeof(e) _e = slowpath(e); /* always eval 'e' */ \
426		if (_e) { \
427			if (__builtin_constant_p(e)) { \
428				char __compile_time_assert__[(bool)(e) ? -1 : 1]; \
429				(void)__compile_time_assert__; \
430			} \
431			_dispatch_bug(__LINE__, (long)_e); \
432		} \
433		_e; \
434	})
435#else
436static inline long _dispatch_assume_zero(long e, long line) {
437	if (e) _dispatch_bug(line, e);
438	return e;
439}
440#define dispatch_assume_zero(e) _dispatch_assume_zero((long)(e), __LINE__)
441#endif	/* __GNUC__ */
442
443/*
444 * For reporting bugs in clients when using the "_debug" version of the library.
445 */
446#if __GNUC__
447#define dispatch_debug_assert(e, msg, args...) do { \
448		if (__builtin_constant_p(e)) { \
449			char __compile_time_assert__[(bool)(e) ? 1 : -1] DISPATCH_UNUSED; \
450		} else { \
451			typeof(e) _e = fastpath(e); /* always eval 'e' */ \
452			if (DISPATCH_DEBUG && !_e) { \
453				_dispatch_log("%s() 0x%lx: " msg, __func__, (long)_e, ##args); \
454				abort(); \
455			} \
456		} \
457	} while (0)
458#else
459#define dispatch_debug_assert(e, msg, args...) do { \
460	long _e = (long)fastpath(e); /* always eval 'e' */ \
461	if (DISPATCH_DEBUG && !_e) { \
462		_dispatch_log("%s() 0x%lx: " msg, __FUNCTION__, _e, ##args); \
463		abort(); \
464	} \
465} while (0)
466#endif	/* __GNUC__ */
467
468/* Make sure the debug statments don't get too stale */
469#define _dispatch_debug(x, args...) do { \
470	if (DISPATCH_DEBUG) { \
471		_dispatch_log("%u\t%p\t" x, __LINE__, \
472				(void *)_dispatch_thread_self(), ##args); \
473	} \
474} while (0)
475
476#if DISPATCH_DEBUG
477#if HAVE_MACH
478DISPATCH_NOINLINE DISPATCH_USED
479void dispatch_debug_machport(mach_port_t name, const char* str);
480#endif
481#endif
482
483#if DISPATCH_DEBUG
484/* This is the private version of the deprecated dispatch_debug() */
485DISPATCH_NONNULL2 DISPATCH_NOTHROW
486__attribute__((__format__(printf,2,3)))
487void
488_dispatch_object_debug(dispatch_object_t object, const char *message, ...);
489#else
490#define _dispatch_object_debug(object, message, ...)
491#endif // DISPATCH_DEBUG
492
493#ifdef __BLOCKS__
494#define _dispatch_Block_invoke(bb) \
495		((dispatch_function_t)((struct Block_layout *)bb)->invoke)
496#if __GNUC__
497dispatch_block_t _dispatch_Block_copy(dispatch_block_t block);
498#define _dispatch_Block_copy(x) ((typeof(x))_dispatch_Block_copy(x))
499#else
500dispatch_block_t _dispatch_Block_copy(const void *block);
501#endif
502void _dispatch_call_block_and_release(void *block);
503#endif /* __BLOCKS__ */
504
505void _dispatch_temporary_resource_shortage(void);
506void *_dispatch_calloc(size_t num_items, size_t size);
507void _dispatch_vtable_init(void);
508char *_dispatch_get_build(void);
509
510uint64_t _dispatch_timeout(dispatch_time_t when);
511
512extern bool _dispatch_safe_fork, _dispatch_child_of_unsafe_fork;
513
514#if !defined(DISPATCH_USE_OS_SEMAPHORE_CACHE) && !(TARGET_IPHONE_SIMULATOR)
515// rdar://problem/15492045
516#if __has_include(<os/semaphore_private.h>)
517#define DISPATCH_USE_OS_SEMAPHORE_CACHE 1
518#include <os/semaphore_private.h>
519#endif
520#endif
521
522/* #includes dependent on internal.h */
523#include "shims.h"
524
525// Older Mac OS X and iOS Simulator fallbacks
526
527#if HAVE_PTHREAD_WORKQUEUES
528#ifndef WORKQ_ADDTHREADS_OPTION_OVERCOMMIT
529#define WORKQ_ADDTHREADS_OPTION_OVERCOMMIT 0x00000001
530#endif
531#if TARGET_IPHONE_SIMULATOR && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1080
532#ifndef DISPATCH_USE_LEGACY_WORKQUEUE_FALLBACK
533#define DISPATCH_USE_LEGACY_WORKQUEUE_FALLBACK 1
534#endif
535#endif
536#if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 1080
537#undef HAVE_PTHREAD_WORKQUEUE_SETDISPATCH_NP
538#define HAVE_PTHREAD_WORKQUEUE_SETDISPATCH_NP 0
539#endif
540#if TARGET_IPHONE_SIMULATOR && \
541		IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 101000
542#ifndef DISPATCH_USE_NOQOS_WORKQUEUE_FALLBACK
543#define DISPATCH_USE_NOQOS_WORKQUEUE_FALLBACK 1
544#endif
545#endif
546#if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 101000
547#undef HAVE__PTHREAD_WORKQUEUE_INIT
548#define HAVE__PTHREAD_WORKQUEUE_INIT 0
549#endif
550#endif // HAVE_PTHREAD_WORKQUEUES
551#if HAVE__PTHREAD_WORKQUEUE_INIT && PTHREAD_WORKQUEUE_SPI_VERSION >= 20140213 \
552		&& !defined(HAVE_PTHREAD_WORKQUEUE_QOS)
553#define HAVE_PTHREAD_WORKQUEUE_QOS 1
554#endif
555
556#if HAVE_MACH
557#if !defined(MACH_NOTIFY_SEND_POSSIBLE) || (TARGET_IPHONE_SIMULATOR && \
558		IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1070)
559#undef MACH_NOTIFY_SEND_POSSIBLE
560#define MACH_NOTIFY_SEND_POSSIBLE MACH_NOTIFY_DEAD_NAME
561#endif
562#endif // HAVE_MACH
563
564#ifdef EVFILT_MEMORYSTATUS
565#ifndef DISPATCH_USE_MEMORYSTATUS
566#define DISPATCH_USE_MEMORYSTATUS 1
567#endif
568#endif // EVFILT_MEMORYSTATUS
569
570#if defined(EVFILT_VM) && !DISPATCH_USE_MEMORYSTATUS
571#ifndef DISPATCH_USE_VM_PRESSURE
572#define DISPATCH_USE_VM_PRESSURE 1
573#endif
574#endif // EVFILT_VM
575
576#if TARGET_IPHONE_SIMULATOR
577#undef DISPATCH_USE_MEMORYSTATUS_SOURCE
578#define DISPATCH_USE_MEMORYSTATUS_SOURCE 0
579#undef DISPATCH_USE_VM_PRESSURE_SOURCE
580#define DISPATCH_USE_VM_PRESSURE_SOURCE 0
581#endif // TARGET_IPHONE_SIMULATOR
582#if !defined(DISPATCH_USE_MEMORYSTATUS_SOURCE) && DISPATCH_USE_MEMORYSTATUS
583#define DISPATCH_USE_MEMORYSTATUS_SOURCE 1
584#elif !defined(DISPATCH_USE_VM_PRESSURE_SOURCE) && DISPATCH_USE_VM_PRESSURE
585#define DISPATCH_USE_VM_PRESSURE_SOURCE 1
586#endif
587
588#if !defined(NOTE_LEEWAY) || (TARGET_IPHONE_SIMULATOR && \
589		IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1090)
590#undef NOTE_LEEWAY
591#define NOTE_LEEWAY 0
592#undef NOTE_CRITICAL
593#define NOTE_CRITICAL 0
594#undef NOTE_BACKGROUND
595#define NOTE_BACKGROUND 0
596#endif // NOTE_LEEWAY
597
598#if HAVE_DECL_NOTE_REAP
599#if defined(NOTE_REAP) && defined(__APPLE__)
600#undef NOTE_REAP
601#define NOTE_REAP 0x10000000 // <rdar://problem/13338526>
602#endif
603#endif // HAVE_DECL_NOTE_REAP
604
605#if defined(F_SETNOSIGPIPE) && defined(F_GETNOSIGPIPE)
606#if TARGET_IPHONE_SIMULATOR && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1070
607#undef DISPATCH_USE_SETNOSIGPIPE
608#define DISPATCH_USE_SETNOSIGPIPE 0
609#endif
610#ifndef DISPATCH_USE_SETNOSIGPIPE
611#define DISPATCH_USE_SETNOSIGPIPE 1
612#endif
613#endif // F_SETNOSIGPIPE
614
615#if defined(MACH_SEND_NOIMPORTANCE)
616#ifndef DISPATCH_USE_CHECKIN_NOIMPORTANCE
617#define DISPATCH_USE_CHECKIN_NOIMPORTANCE 1 // rdar://problem/16996737
618#endif
619#endif // MACH_SEND_NOIMPORTANCE
620
621
622#if HAVE_LIBPROC_INTERNAL_H
623#include <libproc.h>
624#include <libproc_internal.h>
625#if TARGET_IPHONE_SIMULATOR && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1090
626#undef DISPATCH_USE_IMPORTANCE_ASSERTION
627#define DISPATCH_USE_IMPORTANCE_ASSERTION 0
628#endif
629#if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED < 1090
630#undef DISPATCH_USE_IMPORTANCE_ASSERTION
631#define DISPATCH_USE_IMPORTANCE_ASSERTION 0
632#endif
633#ifndef DISPATCH_USE_IMPORTANCE_ASSERTION
634#define DISPATCH_USE_IMPORTANCE_ASSERTION 1
635#endif
636#endif // HAVE_LIBPROC_INTERNAL_H
637
638#if HAVE_SYS_GUARDED_H
639#include <sys/guarded.h>
640#if TARGET_IPHONE_SIMULATOR && IPHONE_SIMULATOR_HOST_MIN_VERSION_REQUIRED < 1090
641#undef DISPATCH_USE_GUARDED_FD
642#define DISPATCH_USE_GUARDED_FD 0
643#endif
644#ifndef DISPATCH_USE_GUARDED_FD
645#define DISPATCH_USE_GUARDED_FD 1
646#endif
647// change_fdguard_np() requires GUARD_DUP <rdar://problem/11814513>
648#if DISPATCH_USE_GUARDED_FD && RDAR_11814513
649#define DISPATCH_USE_GUARDED_FD_CHANGE_FDGUARD 1
650#endif
651#endif // HAVE_SYS_GUARDED_H
652
653
654#ifndef MACH_MSGH_BITS_VOUCHER_MASK
655#define MACH_MSGH_BITS_VOUCHER_MASK	0x001f0000
656#define	MACH_MSGH_BITS_SET_PORTS(remote, local, voucher)	\
657	(((remote) & MACH_MSGH_BITS_REMOTE_MASK) | 		\
658	 (((local) << 8) & MACH_MSGH_BITS_LOCAL_MASK) | 	\
659	 (((voucher) << 16) & MACH_MSGH_BITS_VOUCHER_MASK))
660#define	MACH_MSGH_BITS_VOUCHER(bits)				\
661		(((bits) & MACH_MSGH_BITS_VOUCHER_MASK) >> 16)
662#define MACH_MSGH_BITS_HAS_VOUCHER(bits)			\
663	(MACH_MSGH_BITS_VOUCHER(bits) != MACH_MSGH_BITS_ZERO)
664#define msgh_voucher_port msgh_reserved
665#define mach_voucher_t mach_port_t
666#define MACH_VOUCHER_NULL MACH_PORT_NULL
667#define MACH_SEND_INVALID_VOUCHER 0x10000005
668#endif
669
670#define _dispatch_hardware_crash() \
671		__asm__(""); __builtin_trap() // <rdar://problem/17464981>
672
673#define _dispatch_set_crash_log_message(msg)
674
675#if HAVE_MACH
676// MIG_REPLY_MISMATCH means either:
677// 1) A signal handler is NOT using async-safe API. See the sigaction(2) man
678//    page for more info.
679// 2) A hand crafted call to mach_msg*() screwed up. Use MIG.
680#define DISPATCH_VERIFY_MIG(x) do { \
681		if ((x) == MIG_REPLY_MISMATCH) { \
682			_dispatch_set_crash_log_message("MIG_REPLY_MISMATCH"); \
683			_dispatch_hardware_crash(); \
684		} \
685	} while (0)
686#endif
687
688#define DISPATCH_CRASH(x) do { \
689		_dispatch_set_crash_log_message("BUG IN LIBDISPATCH: " x); \
690		_dispatch_hardware_crash(); \
691	} while (0)
692
693#define DISPATCH_CLIENT_CRASH(x) do { \
694		_dispatch_set_crash_log_message("BUG IN CLIENT OF LIBDISPATCH: " x); \
695		_dispatch_hardware_crash(); \
696	} while (0)
697
698#define _OS_OBJECT_CLIENT_CRASH(x) do { \
699		_dispatch_set_crash_log_message("API MISUSE: " x); \
700		_dispatch_hardware_crash(); \
701	} while (0)
702
703extern int _dispatch_set_qos_class_enabled;
704#define DISPATCH_NO_VOUCHER ((voucher_t)(void*)~0ul)
705#define DISPATCH_NO_PRIORITY ((pthread_priority_t)~0ul)
706#define DISPATCH_PRIORITY_ENFORCE 0x1
707static inline void _dispatch_adopt_priority_and_replace_voucher(
708		pthread_priority_t priority, voucher_t voucher, unsigned long flags);
709#if HAVE_MACH
710static inline void _dispatch_set_priority_and_mach_voucher(
711		pthread_priority_t priority, mach_voucher_t kv);
712mach_port_t _dispatch_get_mach_host_port(void);
713#endif
714
715
716/* #includes dependent on internal.h */
717#include "object_internal.h"
718#include "semaphore_internal.h"
719#include "introspection_internal.h"
720#include "queue_internal.h"
721#include "source_internal.h"
722#include "voucher_internal.h"
723#include "data_internal.h"
724#if !TARGET_OS_WIN32
725#include "io_internal.h"
726#endif
727#include "inline_internal.h"
728
729#endif /* __DISPATCH_INTERNAL__ */
730