1/* 2 * Copyright (c) 2014 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* CFInternal.h 25 Copyright (c) 1998-2013, Apple Inc. All rights reserved. 26*/ 27 28/* 29 NOT TO BE USED OUTSIDE CF! 30*/ 31 32#if !CF_BUILDING_CF 33 #error The header file CFInternal.h is for the exclusive use of CoreFoundation. No other project should include it. 34#endif 35 36#if !defined(__COREFOUNDATION_CFINTERNAL__) 37#define __COREFOUNDATION_CFINTERNAL__ 1 38 39 40#define __CF_COMPILE_YEAR__ (__DATE__[7] * 1000 + __DATE__[8] * 100 + __DATE__[9] * 10 + __DATE__[10] - 53328) 41#define __CF_COMPILE_MONTH__ ((__DATE__[1] + __DATE__[2] == 207) ? 1 : \ 42 (__DATE__[1] + __DATE__[2] == 199) ? 2 : \ 43 (__DATE__[1] + __DATE__[2] == 211) ? 3 : \ 44 (__DATE__[1] + __DATE__[2] == 226) ? 4 : \ 45 (__DATE__[1] + __DATE__[2] == 218) ? 5 : \ 46 (__DATE__[1] + __DATE__[2] == 227) ? 6 : \ 47 (__DATE__[1] + __DATE__[2] == 225) ? 7 : \ 48 (__DATE__[1] + __DATE__[2] == 220) ? 8 : \ 49 (__DATE__[1] + __DATE__[2] == 213) ? 9 : \ 50 (__DATE__[1] + __DATE__[2] == 215) ? 10 : \ 51 (__DATE__[1] + __DATE__[2] == 229) ? 11 : \ 52 (__DATE__[1] + __DATE__[2] == 200) ? 12 : 0) 53#define __CF_COMPILE_DAY__ (__DATE__[4] * 10 + __DATE__[5] - (__DATE__[4] == ' ' ? 368 : 528)) 54#define __CF_COMPILE_DATE__ (__CF_COMPILE_YEAR__ * 10000 + __CF_COMPILE_MONTH__ * 100 + __CF_COMPILE_DAY__) 55 56#define __CF_COMPILE_HOUR__ (__TIME__[0] * 10 + __TIME__[1] - 528) 57#define __CF_COMPILE_MINUTE__ (__TIME__[3] * 10 + __TIME__[4] - 528) 58#define __CF_COMPILE_SECOND__ (__TIME__[6] * 10 + __TIME__[7] - 528) 59#define __CF_COMPILE_TIME__ (__CF_COMPILE_HOUR__ * 10000 + __CF_COMPILE_MINUTE__ * 100 + __CF_COMPILE_SECOND__) 60 61#define __CF_COMPILE_SECOND_OF_DAY__ (__CF_COMPILE_HOUR__ * 3600 + __CF_COMPILE_MINUTE__ * 60 + __CF_COMPILE_SECOND__) 62 63// __CF_COMPILE_DAY_OF_EPOCH__ works within Gregorian years 2001 - 2099; the epoch is of course CF's epoch 64#define __CF_COMPILE_DAY_OF_EPOCH__ ((__CF_COMPILE_YEAR__ - 2001) * 365 + (__CF_COMPILE_YEAR__ - 2001) / 4 \ 65 + ((__DATE__[1] + __DATE__[2] == 207) ? 0 : \ 66 (__DATE__[1] + __DATE__[2] == 199) ? 31 : \ 67 (__DATE__[1] + __DATE__[2] == 211) ? 59 + (__CF_COMPILE_YEAR__ % 4 == 0) : \ 68 (__DATE__[1] + __DATE__[2] == 226) ? 90 + (__CF_COMPILE_YEAR__ % 4 == 0) : \ 69 (__DATE__[1] + __DATE__[2] == 218) ? 120 + (__CF_COMPILE_YEAR__ % 4 == 0) : \ 70 (__DATE__[1] + __DATE__[2] == 227) ? 151 + (__CF_COMPILE_YEAR__ % 4 == 0) : \ 71 (__DATE__[1] + __DATE__[2] == 225) ? 181 + (__CF_COMPILE_YEAR__ % 4 == 0) : \ 72 (__DATE__[1] + __DATE__[2] == 220) ? 212 + (__CF_COMPILE_YEAR__ % 4 == 0) : \ 73 (__DATE__[1] + __DATE__[2] == 213) ? 243 + (__CF_COMPILE_YEAR__ % 4 == 0) : \ 74 (__DATE__[1] + __DATE__[2] == 215) ? 273 + (__CF_COMPILE_YEAR__ % 4 == 0) : \ 75 (__DATE__[1] + __DATE__[2] == 229) ? 304 + (__CF_COMPILE_YEAR__ % 4 == 0) : \ 76 (__DATE__[1] + __DATE__[2] == 200) ? 334 + (__CF_COMPILE_YEAR__ % 4 == 0) : \ 77 365 + (__CF_COMPILE_YEAR__ % 4 == 0)) \ 78 + __CF_COMPILE_DAY__) 79 80 81CF_EXTERN_C_BEGIN 82 83#include <CoreFoundation/CFBase.h> 84#include <CoreFoundation/CFURL.h> 85#include <CoreFoundation/CFString.h> 86#include <CoreFoundation/CFDate.h> 87#include <CoreFoundation/CFArray.h> 88#include <CoreFoundation/CFLogUtilities.h> 89#include <CoreFoundation/CFRuntime.h> 90#include <limits.h> 91#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX 92#include <xlocale.h> 93#include <unistd.h> 94#include <sys/time.h> 95#include <signal.h> 96#include <stdio.h> 97#endif 98#include <pthread.h> 99 100 101#if defined(__BIG_ENDIAN__) 102#define __CF_BIG_ENDIAN__ 1 103#define __CF_LITTLE_ENDIAN__ 0 104#endif 105 106#if defined(__LITTLE_ENDIAN__) 107#define __CF_LITTLE_ENDIAN__ 1 108#define __CF_BIG_ENDIAN__ 0 109#endif 110 111 112#include <CoreFoundation/ForFoundationOnly.h> 113 114CF_EXPORT const char *_CFProcessName(void); 115CF_EXPORT CFStringRef _CFProcessNameString(void); 116 117CF_EXPORT Boolean _CFGetCurrentDirectory(char *path, int maxlen); 118 119CF_EXPORT CFArrayRef _CFGetWindowsBinaryDirectories(void); 120 121CF_EXPORT CFStringRef _CFStringCreateHostName(void); 122 123#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI 124#include <CoreFoundation/CFRunLoop.h> 125CF_EXPORT void _CFMachPortInstallNotifyPort(CFRunLoopRef rl, CFStringRef mode); 126#endif 127 128 129CF_PRIVATE CFIndex __CFActiveProcessorCount(); 130 131#ifndef CLANG_ANALYZER_NORETURN 132#if __has_feature(attribute_analyzer_noreturn) 133#define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn)) 134#else 135#define CLANG_ANALYZER_NORETURN 136#endif 137#endif 138 139#if DEPLOYMENT_TARGET_WINDOWS 140#define __builtin_unreachable() do { } while (0) 141#endif 142 143#if defined(__i386__) || defined(__x86_64__) 144 #if defined(__GNUC__) 145 #define HALT do {asm __volatile__("int3"); kill(getpid(), 9); __builtin_unreachable(); } while (0) 146 #elif defined(_MSC_VER) 147 #define HALT do { DebugBreak(); abort(); __builtin_unreachable(); } while (0) 148 #else 149 #error Compiler not supported 150 #endif 151#endif 152 153 154#if defined(DEBUG) 155 #define __CFAssert(cond, prio, desc, a1, a2, a3, a4, a5) \ 156 do { \ 157 if (!(cond)) { \ 158 CFLog(prio, CFSTR(desc), a1, a2, a3, a4, a5); \ 159 /* HALT; */ \ 160 } \ 161 } while (0) 162#else 163 #define __CFAssert(cond, prio, desc, a1, a2, a3, a4, a5) \ 164 do {} while (0) 165#endif 166 167#define CFAssert(condition, priority, description) \ 168 __CFAssert((condition), (priority), description, 0, 0, 0, 0, 0) 169#define CFAssert1(condition, priority, description, a1) \ 170 __CFAssert((condition), (priority), description, (a1), 0, 0, 0, 0) 171#define CFAssert2(condition, priority, description, a1, a2) \ 172 __CFAssert((condition), (priority), description, (a1), (a2), 0, 0, 0) 173#define CFAssert3(condition, priority, description, a1, a2, a3) \ 174 __CFAssert((condition), (priority), description, (a1), (a2), (a3), 0, 0) 175#define CFAssert4(condition, priority, description, a1, a2, a3, a4) \ 176 __CFAssert((condition), (priority), description, (a1), (a2), (a3), (a4), 0) 177 178#define __kCFLogAssertion 3 179 180// This CF-only log function uses no CF functionality, so it may be called anywhere within CF - including thread teardown or prior to full CF setup 181CF_PRIVATE void _CFLogSimple(int32_t lev, char *format, ...); 182 183#if defined(DEBUG) 184extern void __CFGenericValidateType_(CFTypeRef cf, CFTypeID type, const char *func); 185#define __CFGenericValidateType(cf, type) __CFGenericValidateType_(cf, type, __PRETTY_FUNCTION__) 186#else 187#define __CFGenericValidateType(cf, type) ((void)0) 188#endif 189 190#define CF_INFO_BITS (!!(__CF_BIG_ENDIAN__) * 3) 191#define CF_RC_BITS (!!(__CF_LITTLE_ENDIAN__) * 3) 192 193/* Bit manipulation macros */ 194/* Bits are numbered from 31 on left to 0 on right */ 195/* May or may not work if you use them on bitfields in types other than UInt32, bitfields the full width of a UInt32, or anything else for which they were not designed. */ 196/* In the following, N1 and N2 specify an inclusive range N2..N1 with N1 >= N2 */ 197#define __CFBitfieldMask(N1, N2) ((((UInt32)~0UL) << (31UL - (N1) + (N2))) >> (31UL - N1)) 198#define __CFBitfieldGetValue(V, N1, N2) (((V) & __CFBitfieldMask(N1, N2)) >> (N2)) 199#define __CFBitfieldSetValue(V, N1, N2, X) ((V) = ((V) & ~__CFBitfieldMask(N1, N2)) | (((X) << (N2)) & __CFBitfieldMask(N1, N2))) 200#define __CFBitfieldMaxValue(N1, N2) __CFBitfieldGetValue(0xFFFFFFFFUL, (N1), (N2)) 201 202#define __CFBitIsSet(V, N) (((V) & (1UL << (N))) != 0) 203#define __CFBitSet(V, N) ((V) |= (1UL << (N))) 204#define __CFBitClear(V, N) ((V) &= ~(1UL << (N))) 205 206// Foundation uses 20-40 207// Foundation knows about the value of __CFTSDKeyAutoreleaseData1 208enum { 209 __CFTSDKeyAllocator = 1, 210 __CFTSDKeyIsInCFLog = 2, 211 __CFTSDKeyIsInNSCache = 3, 212 __CFTSDKeyIsInGCDMainQ = 4, 213 __CFTSDKeyICUConverter = 7, 214 __CFTSDKeyCollatorLocale = 8, 215 __CFTSDKeyCollatorUCollator = 9, 216 __CFTSDKeyRunLoop = 10, 217 __CFTSDKeyRunLoopCntr = 11, 218 __CFTSDKeyMachMessageBoost = 12, // valid only in the context of a CFMachPort callout 219 // autorelease pool stuff must be higher than run loop constants 220 __CFTSDKeyAutoreleaseData2 = 61, 221 __CFTSDKeyAutoreleaseData1 = 62, 222 __CFTSDKeyExceptionData = 63, 223}; 224 225#define __kCFAllocatorTypeID_CONST 2 226 227CF_INLINE CFAllocatorRef __CFGetDefaultAllocator(void) { 228 CFAllocatorRef allocator = (CFAllocatorRef)_CFGetTSD(__CFTSDKeyAllocator); 229 if (NULL == allocator) { 230 allocator = kCFAllocatorSystemDefault; 231 } 232 return allocator; 233} 234 235 236#if !defined(LLONG_MAX) 237 #if defined(_I64_MAX) 238 #define LLONG_MAX _I64_MAX 239 #else 240 #warning Arbitrarily defining LLONG_MAX 241 #define LLONG_MAX (int64_t)9223372036854775807 242 #endif 243#endif /* !defined(LLONG_MAX) */ 244 245#if !defined(LLONG_MIN) 246 #if defined(_I64_MIN) 247 #define LLONG_MIN _I64_MIN 248 #else 249 #warning Arbitrarily defining LLONG_MIN 250 #define LLONG_MIN (-LLONG_MAX - (int64_t)1) 251 #endif 252#endif /* !defined(LLONG_MIN) */ 253 254#if defined(__GNUC__) && !defined(__STRICT_ANSI__) 255 #define __CFMin(A,B) ({__typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __a : __b; }) 256 #define __CFMax(A,B) ({__typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __b : __a; }) 257#else /* __GNUC__ */ 258 #define __CFMin(A,B) ((A) < (B) ? (A) : (B)) 259 #define __CFMax(A,B) ((A) > (B) ? (A) : (B)) 260#endif /* __GNUC__ */ 261 262/* Secret CFAllocator hint bits */ 263#define __kCFAllocatorTempMemory 0x2 264#define __kCFAllocatorNoPointers 0x10 265#define __kCFAllocatorDoNotRecordEvent 0x100 266#define __kCFAllocatorGCScannedMemory 0x200 /* GC: memory should be scanned. */ 267#define __kCFAllocatorGCObjectMemory 0x400 /* GC: memory needs to be finalized. */ 268 269CF_INLINE auto_memory_type_t CF_GET_GC_MEMORY_TYPE(CFOptionFlags flags) { 270 auto_memory_type_t type = (flags & __kCFAllocatorGCScannedMemory ? 0 : AUTO_UNSCANNED) | (flags & __kCFAllocatorGCObjectMemory ? AUTO_OBJECT : 0); 271 return type; 272} 273 274CF_INLINE void __CFAssignWithWriteBarrier(void **location, void *value) { 275 if (kCFUseCollectableAllocator) { 276 objc_assign_strongCast((id)value, (id *)location); 277 } else { 278 *location = value; 279 } 280} 281 282// Zero-retain count CFAllocator functions, i.e. memory that will be collected, no dealloc necessary 283CF_EXPORT void *_CFAllocatorAllocateGC(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint); 284CF_EXPORT void *_CFAllocatorReallocateGC(CFAllocatorRef allocator, void *ptr, CFIndex newsize, CFOptionFlags hint); 285CF_EXPORT void _CFAllocatorDeallocateGC(CFAllocatorRef allocator, void *ptr); 286 287CF_EXPORT CFAllocatorRef _CFTemporaryMemoryAllocator(void); 288 289extern uint64_t __CFTimeIntervalToTSR(CFTimeInterval ti); 290extern CFTimeInterval __CFTSRToTimeInterval(uint64_t tsr); 291// use this instead of attempting to subtract mach_absolute_time() directly, because that can underflow and give an unexpected answer 292CF_PRIVATE CFTimeInterval __CFTimeIntervalUntilTSR(uint64_t tsr); 293CF_PRIVATE dispatch_time_t __CFTSRToDispatchTime(uint64_t tsr); 294CF_PRIVATE uint64_t __CFTSRToNanoseconds(uint64_t tsr); 295 296extern CFStringRef __CFCopyFormattingDescription(CFTypeRef cf, CFDictionaryRef formatOptions); 297 298/* Enhanced string formatting support 299 */ 300CF_PRIVATE CFDictionaryRef _CFStringGetFormatSpecifierConfiguration(CFStringRef aFormatString); 301CF_PRIVATE CFStringRef _CFStringCopyWithFomatStringConfiguration(CFStringRef aFormatString, CFDictionaryRef formatConfiguration); 302CF_PRIVATE CFStringRef _CFCopyResolvedFormatStringWithConfiguration(CFTypeRef anObject, CFDictionaryRef aConfiguration, CFDictionaryRef formatOptions); 303 304/* result is long long or int, depending on doLonglong 305*/ 306extern Boolean __CFStringScanInteger(CFStringInlineBuffer *buf, CFTypeRef locale, SInt32 *indexPtr, Boolean doLonglong, void *result); 307extern Boolean __CFStringScanDouble(CFStringInlineBuffer *buf, CFTypeRef locale, SInt32 *indexPtr, double *resultPtr); 308extern Boolean __CFStringScanHex(CFStringInlineBuffer *buf, SInt32 *indexPtr, unsigned *result); 309 310extern const char *__CFgetenv(const char *n); 311 312CF_PRIVATE Boolean __CFProcessIsRestricted(); 313 314// This is really about the availability of C99. We don't have that on Windows, but we should everywhere else. 315#if DEPLOYMENT_TARGET_WINDOWS 316#define STACK_BUFFER_DECL(T, N, C) T *N = (T *)_alloca((C) * sizeof(T)) 317#else 318#define STACK_BUFFER_DECL(T, N, C) T N[C] 319#endif 320 321 322CF_EXPORT void * __CFConstantStringClassReferencePtr; 323 324#ifdef __CONSTANT_CFSTRINGS__ 325 326#define CONST_STRING_DECL(S, V) const CFStringRef S = (const CFStringRef)__builtin___CFStringMakeConstantString(V); 327#define PE_CONST_STRING_DECL(S, V) CF_PRIVATE const CFStringRef S = (const CFStringRef)__builtin___CFStringMakeConstantString(V); 328 329#else 330 331struct CF_CONST_STRING { 332 CFRuntimeBase _base; 333 uint8_t *_ptr; 334 uint32_t _length; 335}; 336 337CF_EXPORT int __CFConstantStringClassReference[]; 338 339/* CFNetwork also has a copy of the CONST_STRING_DECL macro (for use on platforms without constant string support in cc); please warn cfnetwork-core@group.apple.com of any necessary changes to this macro. -- REW, 1/28/2002 */ 340 341#if __CF_BIG_ENDIAN__ 342 343#define CONST_STRING_DECL(S, V) \ 344static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, {0x00, 0x00, 0x07, 0xc8}}, (uint8_t *)V, sizeof(V) - 1}; \ 345const CFStringRef S = (CFStringRef) & __ ## S ## __; 346#define PE_CONST_STRING_DECL(S, V) \ 347static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, {0x00, 0x00, 0x07, 0xc8}}, (uint8_t *)V, sizeof(V) - 1}; \ 348CF_PRIVATE const CFStringRef S = (CFStringRef) & __ ## S ## __; 349 350#elif __CF_LITTLE_ENDIAN__ 351 352#define CONST_STRING_DECL(S, V) \ 353static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, {0xc8, 0x07, 0x00, 0x00}}, (uint8_t *)(V), sizeof(V) - 1}; \ 354const CFStringRef S = (CFStringRef) & __ ## S ## __; 355#define PE_CONST_STRING_DECL(S, V) \ 356static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, {0xc8, 0x07, 0x00, 0x00}}, (uint8_t *)(V), sizeof(V) - 1}; \ 357CF_PRIVATE const CFStringRef S = (CFStringRef) & __ ## S ## __; 358 359#endif 360 361#endif // __CONSTANT_CFSTRINGS__ 362 363CF_EXPORT bool __CFOASafe; 364CF_EXPORT void __CFSetLastAllocationEventName(void *ptr, const char *classname); 365 366 367 368/* Comparators are passed the address of the values; this is somewhat different than CFComparatorFunction is used in public API usually. */ 369CF_EXPORT CFIndex CFBSearch(const void *element, CFIndex elementSize, const void *list, CFIndex count, CFComparatorFunction comparator, void *context); 370 371CF_EXPORT CFHashCode CFHashBytes(UInt8 *bytes, CFIndex length); 372 373CF_EXPORT CFStringEncoding CFStringFileSystemEncoding(void); 374 375CF_PRIVATE CFStringRef __CFStringCreateImmutableFunnel3(CFAllocatorRef alloc, const void *bytes, CFIndex numBytes, CFStringEncoding encoding, Boolean possiblyExternalFormat, Boolean tryToReduceUnicode, Boolean hasLengthByte, Boolean hasNullByte, Boolean noCopy, CFAllocatorRef contentsDeallocator, UInt32 converterFlags); 376 377extern const void *__CFStringCollectionCopy(CFAllocatorRef allocator, const void *ptr); 378extern const void *__CFTypeCollectionRetain(CFAllocatorRef allocator, const void *ptr); 379extern void __CFTypeCollectionRelease(CFAllocatorRef allocator, const void *ptr); 380 381extern CFTypeRef CFMakeUncollectable(CFTypeRef cf); 382 383CF_PRIVATE void _CFRaiseMemoryException(CFStringRef reason); 384 385CF_PRIVATE Boolean __CFProphylacticAutofsAccess; 386 387 388#if DEPLOYMENT_TARGET_MACOSX 389 390typedef OSSpinLock CFSpinLock_t; 391 392#define CFSpinLockInit OS_SPINLOCK_INIT 393#define CF_SPINLOCK_INIT_FOR_STRUCTS(X) (X = CFSpinLockInit) 394 395#define __CFSpinLock(LP) ({ \ 396 OSSpinLock *__lockp__ = (LP); \ 397 OSSpinLock __lockv__ = *__lockp__; \ 398 if (0 != __lockv__ && ~0 != __lockv__ && (uintptr_t)__lockp__ != (uintptr_t)__lockv__) { \ 399 CFLog(3, CFSTR("In '%s', file %s, line %d, during lock, spin lock %p has value 0x%x, which is neither locked nor unlocked. The memory has been smashed."), __PRETTY_FUNCTION__, __FILE__, __LINE__, __lockp__, __lockv__); \ 400 /* HALT; */ \ 401 } \ 402 OSSpinLockLock(__lockp__); }) 403 404#define __CFSpinUnlock(LP) ({ \ 405 OSSpinLock *__lockp__ = (LP); \ 406 OSSpinLock __lockv__ = *__lockp__; \ 407 if (~0 != __lockv__ && (uintptr_t)__lockp__ != (uintptr_t)__lockv__) { \ 408 CFLog(3, CFSTR("In '%s', file %s, line %d, during unlock, spin lock %p has value 0x%x, which is not locked. The memory has been smashed or the lock is being unlocked when not locked."), __PRETTY_FUNCTION__, __FILE__, __LINE__, __lockp__, __lockv__); \ 409 /* HALT; */ \ 410 } \ 411 OSSpinLockUnlock(__lockp__); }) 412 413#define __CFSpinLockTry(LP) ({ \ 414 OSSpinLock *__lockp__ = (LP); \ 415 OSSpinLock __lockv__ = *__lockp__; \ 416 if (0 != __lockv__ && ~0 != __lockv__ && (uintptr_t)__lockp__ != (uintptr_t)__lockv__) { \ 417 CFLog(3, CFSTR("In '%s', file %s, line %d, during lock, spin lock %p has value 0x%x, which is neither locked nor unlocked. The memory has been smashed."), __PRETTY_FUNCTION__, __FILE__, __LINE__, __lockp__, __lockv__); \ 418 /* HALT; */ \ 419 } \ 420 OSSpinLockTry(__lockp__); }) 421 422#elif DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI 423 424typedef OSSpinLock CFSpinLock_t; 425 426#define CFSpinLockInit OS_SPINLOCK_INIT 427#define CF_SPINLOCK_INIT_FOR_STRUCTS(X) (X = CFSpinLockInit) 428 429#define __CFSpinLock(LP) ({ \ 430 OSSpinLock *__lockp__ = (LP); \ 431 OSSpinLockLock(__lockp__); }) 432 433#define __CFSpinUnlock(LP) ({ \ 434 OSSpinLock *__lockp__ = (LP); \ 435 OSSpinLockUnlock(__lockp__); }) 436 437#define __CFSpinLockTry(LP) ({ \ 438 OSSpinLock *__lockp__ = (LP); \ 439 OSSpinLockTry(__lockp__); }) 440 441#elif DEPLOYMENT_TARGET_WINDOWS 442 443typedef int32_t CFSpinLock_t; 444#define CFSpinLockInit 0 445#define CF_SPINLOCK_INIT_FOR_STRUCTS(X) (X = CFSpinLockInit) 446 447CF_INLINE void __CFSpinLock(volatile CFSpinLock_t *lock) { 448 while (InterlockedCompareExchange((LONG volatile *)lock, ~0, 0) != 0) { 449 Sleep(0); 450 } 451} 452 453CF_INLINE void __CFSpinUnlock(volatile CFSpinLock_t *lock) { 454 MemoryBarrier(); 455 *lock = 0; 456} 457 458CF_INLINE Boolean __CFSpinLockTry(volatile CFSpinLock_t *lock) { 459 return (InterlockedCompareExchange((LONG volatile *)lock, ~0, 0) == 0); 460} 461 462#elif DEPLOYMENT_TARGET_LINUX 463 464typedef int32_t CFSpinLock_t; 465#define CFSpinLockInit 0 466#define CF_SPINLOCK_INIT_FOR_STRUCTS(X) (X = CFSpinLockInit) 467 468CF_INLINE void __CFSpinLock(volatile CFSpinLock_t *lock) { 469 while (__sync_val_compare_and_swap(lock, 0, ~0) != 0) { 470 sleep(0); 471 } 472} 473 474CF_INLINE void __CFSpinUnlock(volatile CFSpinLock_t *lock) { 475 __sync_synchronize(); 476 *lock = 0; 477} 478 479CF_INLINE Boolean __CFSpinLockTry(volatile CFSpinLock_t *lock) { 480 return (__sync_val_compare_and_swap(lock, 0, ~0) == 0); 481} 482 483#else 484 485#warning CF spin locks not defined for this platform -- CF is not thread-safe 486#define __CFSpinLock(A) do {} while (0) 487#define __CFSpinUnlock(A) do {} while (0) 488 489#endif 490 491 492#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI 493extern uint8_t __CF120293; 494extern uint8_t __CF120290; 495extern void __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__(void); 496#define CHECK_FOR_FORK() do { __CF120290 = true; if (__CF120293) __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__(); } while (0) 497#define CHECK_FOR_FORK_RET(...) do { CHECK_FOR_FORK(); if (__CF120293) return __VA_ARGS__; } while (0) 498#define HAS_FORKED() (__CF120293) 499#endif 500 501#if !defined(CHECK_FOR_FORK) 502#define CHECK_FOR_FORK() do { } while (0) 503#endif 504 505#if !defined(CHECK_FOR_FORK_RET) 506#define CHECK_FOR_FORK_RET(...) do { } while (0) 507#endif 508 509#if !defined(HAS_FORKED) 510#define HAS_FORKED() 0 511#endif 512 513#include <errno.h> 514 515#define thread_errno() errno 516#define thread_set_errno(V) do {errno = (V);} while (0) 517 518extern void *__CFStartSimpleThread(void *func, void *arg); 519 520/* ==================== Simple file access ==================== */ 521/* For dealing with abstract types. MF:!!! These ought to be somewhere else and public. */ 522 523CF_EXPORT CFStringRef _CFCopyExtensionForAbstractType(CFStringRef abstractType); 524 525/* ==================== Simple file access ==================== */ 526/* These functions all act on a c-strings which must be in the file system encoding. */ 527 528CF_EXPORT Boolean _CFCreateDirectory(const char *path); 529CF_EXPORT Boolean _CFRemoveDirectory(const char *path); 530CF_EXPORT Boolean _CFDeleteFile(const char *path); 531 532CF_EXPORT Boolean _CFReadBytesFromPathAndGetFD(CFAllocatorRef alloc, const char *path, void **bytes, CFIndex *length, CFIndex maxLength, int extraOpenFlags, int *fd); 533CF_EXPORT Boolean _CFReadBytesFromPath(CFAllocatorRef alloc, const char *path, void **bytes, CFIndex *length, CFIndex maxLength, int extraOpenFlags); 534CF_EXPORT Boolean _CFReadBytesFromFile(CFAllocatorRef alloc, CFURLRef url, void **bytes, CFIndex *length, CFIndex maxLength, int extraOpenFlags); 535 /* resulting bytes are allocated from alloc which MUST be non-NULL. */ 536 /* maxLength of zero means the whole file. Otherwise it sets a limit on the number of bytes read. */ 537 538CF_EXPORT Boolean _CFWriteBytesToFile(CFURLRef url, const void *bytes, CFIndex length); 539 540CF_PRIVATE CFMutableArrayRef _CFCreateContentsOfDirectory(CFAllocatorRef alloc, char *dirPath, void *dirSpec, CFURLRef dirURL, CFStringRef matchingAbstractType); 541 /* On Mac OS 8/9, one of dirSpec, dirPath and dirURL must be non-NULL */ 542 /* On all other platforms, one of path and dirURL must be non-NULL */ 543 /* If both are present, they are assumed to be in-synch; that is, they both refer to the same directory. */ 544 /* alloc may be NULL */ 545 /* return value is CFArray of CFURLs */ 546 547CF_PRIVATE SInt32 _CFGetPathProperties(CFAllocatorRef alloc, char *path, Boolean *exists, SInt32 *posixMode, SInt64 *size, CFDateRef *modTime, SInt32 *ownerID, CFArrayRef *dirContents); 548 /* alloc may be NULL */ 549 /* any of exists, posixMode, size, modTime, and dirContents can be NULL. Usually it is not a good idea to pass NULL for exists, since interpretting the other values sometimes requires that you know whether the file existed or not. Except for dirContents, it is pretty cheap to compute any of these things as loing as one of them must be computed. */ 550 551CF_PRIVATE SInt32 _CFGetFileProperties(CFAllocatorRef alloc, CFURLRef pathURL, Boolean *exists, SInt32 *posixMode, SInt64 *size, CFDateRef *modTime, SInt32 *ownerID, CFArrayRef *dirContents); 552 /* alloc may be NULL */ 553 /* any of exists, posixMode, size, modTime, and dirContents can be NULL. Usually it is not a good idea to pass NULL for exists, since interpretting the other values sometimes requires that you know whether the file existed or not. Except for dirContents, it is pretty cheap to compute any of these things as loing as one of them must be computed. */ 554 555 556/* ==================== Simple path manipulation ==================== */ 557 558CF_EXPORT UniChar _CFGetSlash(); 559CF_PRIVATE CFStringRef _CFGetSlashStr(); 560CF_EXPORT Boolean _CFIsAbsolutePath(UniChar *unichars, CFIndex length); 561CF_PRIVATE void _CFAppendTrailingPathSlash2(CFMutableStringRef path); 562CF_PRIVATE void _CFAppendConditionalTrailingPathSlash2(CFMutableStringRef path); 563CF_EXPORT Boolean _CFAppendPathComponent(UniChar *unichars, CFIndex *length, CFIndex maxLength, UniChar *component, CFIndex componentLength); 564CF_PRIVATE void _CFAppendPathComponent2(CFMutableStringRef path, CFStringRef component); 565CF_PRIVATE Boolean _CFAppendPathExtension2(CFMutableStringRef path, CFStringRef extension); 566CF_EXPORT Boolean _CFAppendPathExtension(UniChar *unichars, CFIndex *length, CFIndex maxLength, UniChar *extension, CFIndex extensionLength); 567CF_EXPORT Boolean _CFTransmutePathSlashes(UniChar *unichars, CFIndex *length, UniChar replSlash); 568CF_PRIVATE CFStringRef _CFCreateLastPathComponent(CFAllocatorRef alloc, CFStringRef path, CFIndex *slashIndex); 569CF_EXPORT CFIndex _CFStartOfLastPathComponent(UniChar *unichars, CFIndex length); 570CF_PRIVATE CFIndex _CFStartOfLastPathComponent2(CFStringRef path); 571CF_EXPORT CFIndex _CFLengthAfterDeletingLastPathComponent(UniChar *unichars, CFIndex length); 572CF_PRIVATE CFIndex _CFLengthAfterDeletingPathExtension2(CFStringRef path); 573CF_EXPORT CFIndex _CFStartOfPathExtension(UniChar *unichars, CFIndex length); 574CF_PRIVATE CFIndex _CFStartOfPathExtension2(CFStringRef path); 575CF_EXPORT CFIndex _CFLengthAfterDeletingPathExtension(UniChar *unichars, CFIndex length); 576 577#if __BLOCKS__ 578#if DEPLOYMENT_TARGET_WINDOWS 579#define DT_DIR 4 580#define DT_REG 8 581#define DT_LNK 10 582#endif 583 584// This function automatically skips '.' and '..', and '._' files 585CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean (^fileHandler)(CFStringRef fileName, uint8_t fileType)); 586#endif 587 588#define __CFMaxRuntimeTypes 65535 589#define __CFRuntimeClassTableSize 1024 590 591extern void _CFRuntimeSetInstanceTypeIDAndIsa(CFTypeRef cf, CFTypeID newTypeID); 592 593#define CF_OBJC_FUNCDISPATCHV(typeID, obj, ...) do { } while (0) 594#define CF_OBJC_CALLV(obj, ...) (0) 595#define CF_IS_OBJC(typeID, obj) (0) 596#define __CFISAForTypeID(t) (0) 597 598/* See comments in CFBase.c 599*/ 600#define FAULT_CALLBACK(V) 601#define INVOKE_CALLBACK1(P, A) (P)(A) 602#define INVOKE_CALLBACK2(P, A, B) (P)(A, B) 603#define INVOKE_CALLBACK3(P, A, B, C) (P)(A, B, C) 604#define INVOKE_CALLBACK4(P, A, B, C, D) (P)(A, B, C, D) 605#define INVOKE_CALLBACK5(P, A, B, C, D, E) (P)(A, B, C, D, E) 606#define UNFAULT_CALLBACK(V) do { } while (0) 607 608/* For the support of functionality which needs CarbonCore or other frameworks */ 609// These macros define an upcall or weak "symbol-lookup" wrapper function. 610// The parameters are: 611// R : the return type of the function 612// N : the name of the function (in the other library) 613// P : the parenthesized parameter list of the function 614// A : the parenthesized actual argument list to be passed 615// FAILACTION: (only for the _FAIL macros) additional code to be 616// run when the function cannot be found. 617// opt: a fifth optional argument can be passed in which is the 618// return value of the wrapper when the function cannot be 619// found; should be of type R, & can be a function call 620// The name of the resulting wrapper function is: 621// __CFCarbonCore_N (where N is the second parameter) 622// __CFNetwork_N (where N is the second parameter) 623// 624// Example: 625// DEFINE_WEAK_CARBONCORE_FUNC(void, DisposeHandle, (Handle h), (h)) 626// 627 628#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED 629 630extern void *__CFLookupCFNetworkFunction(const char *name); 631 632#define DEFINE_WEAK_CFNETWORK_FUNC(R, N, P, A, ...) \ 633 typedef R (*dyfuncptr)P; \ 634 static dyfuncptr dyfunc = (dyfuncptr)(~(uintptr_t)0); \ 635 if ((dyfuncptr)(~(uintptr_t)0) == dyfunc) { \ 636 dyfunc = (dyfuncptr)__CFLookupCFNetworkFunction(#N); } \ 637 if (dyfunc) { return dyfunc A ; } \ 638 return __VA_ARGS__ ; \ 639} 640 641#define DEFINE_WEAK_CFNETWORK_FUNC_FAIL(R, N, P, A, FAILACTION, ...) \ 642static R __CFNetwork_ ## N P { \ 643 typedef R (*dyfuncptr)P; \ 644 static dyfuncptr dyfunc = (dyfuncptr)(~(uintptr_t)0); \ 645 if ((dyfuncptr)(~(uintptr_t)0) == dyfunc) { \ 646 dyfunc = (dyfuncptr)__CFLookupCFNetworkFunction(#N); } \ 647 if (dyfunc) { return dyfunc A ; } \ 648 FAILACTION ; \ 649 return __VA_ARGS__ ; \ 650} 651 652#else 653#define DEFINE_WEAK_CFNETWORK_FUNC(R, N, P, A, ...) 654#define DEFINE_WEAK_CFNETWORK_FUNC_FAIL(R, N, P, A, ...) 655#endif 656 657#define DEFINE_WEAK_CARBONCORE_FUNC(R, N, P, A, ...) 658 659#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED 660 661extern void *__CFLookupCoreServicesInternalFunction(const char *name); 662 663#define DEFINE_WEAK_CORESERVICESINTERNAL_FUNC(R, N, P, A, ...) \ 664 static R __CFCoreServicesInternal_ ## N P { \ 665 typedef R (*dyfuncptr)P; \ 666 static dyfuncptr dyfunc = (dyfuncptr)(~(uintptr_t)0); \ 667 if ((dyfuncptr)(~(uintptr_t)0) == dyfunc) { \ 668 dyfunc = (dyfuncptr)__CFLookupCoreServicesInternalFunction(#N); \ 669 } \ 670 if (dyfunc) { \ 671 return dyfunc A ; \ 672 } \ 673 return __VA_ARGS__ ; \ 674 } 675 676#else 677#define DEFINE_WEAK_CORESERVICESINTERNAL_FUNC(R, N, P, A, ...) 678#endif 679 680CF_PRIVATE CFComparisonResult _CFCompareStringsWithLocale(CFStringInlineBuffer *str1, CFRange str1Range, CFStringInlineBuffer *str2, CFRange str2Range, CFOptionFlags options, const void *compareLocale); 681 682 683CF_PRIVATE CFArrayRef _CFBundleCopyUserLanguages(); 684 685 686// This should only be used in CF types, not toll-free bridged objects! 687// It should not be used with CFAllocator arguments! 688// Use CFGetAllocator() in the general case, and this inline function in a few limited (but often called) situations. 689CF_INLINE CFAllocatorRef __CFGetAllocator(CFTypeRef cf) { // !!! Use with CF types only, and NOT WITH CFAllocator! 690#if OBJC_HAVE_TAGGED_POINTERS 691 if (_objc_isTaggedPointer(cf)) { 692 return kCFAllocatorSystemDefault; 693 } 694#endif 695 if (__builtin_expect(__CFBitfieldGetValue(((const CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 7, 7), 1)) { 696 return kCFAllocatorSystemDefault; 697 } 698 return *(CFAllocatorRef *)((char *)cf - sizeof(CFAllocatorRef)); 699} 700 701/* !!! Avoid #importing objc.h; e.g. converting this to a .m file */ 702struct __objcFastEnumerationStateEquivalent { 703 unsigned long state; 704 unsigned long *itemsPtr; 705 unsigned long *mutationsPtr; 706 unsigned long extra[5]; 707}; 708 709#if 0 710#pragma mark - 711#pragma mark Windows Compatability 712#endif 713 714// Need to use the _O_BINARY flag on Windows to get the correct behavior 715#if DEPLOYMENT_TARGET_WINDOWS 716#define CF_OPENFLGS (_O_BINARY|_O_NOINHERIT) 717#else 718#define CF_OPENFLGS (0) 719#endif 720 721#if DEPLOYMENT_TARGET_WINDOWS 722 723// These are replacements for pthread calls on Windows 724CF_EXPORT int _NS_pthread_main_np(); 725CF_EXPORT int _NS_pthread_setspecific(pthread_key_t key, const void *val); 726CF_EXPORT void* _NS_pthread_getspecific(pthread_key_t key); 727CF_EXPORT int _NS_pthread_key_init_np(int key, void (*destructor)(void *)); 728CF_EXPORT void _NS_pthread_setname_np(const char *name); 729 730// map use of pthread_set/getspecific to internal API 731#define pthread_setspecific _NS_pthread_setspecific 732#define pthread_getspecific _NS_pthread_getspecific 733#define pthread_key_init_np _NS_pthread_key_init_np 734#define pthread_main_np _NS_pthread_main_np 735#define pthread_setname_np _NS_pthread_setname_np 736#endif 737 738#if DEPLOYMENT_TARGET_WINDOWS 739// replacement for DISPATCH_QUEUE_OVERCOMMIT until we get a bug fix in dispatch on Windows 740// <rdar://problem/7923891> dispatch on Windows: Need queue_private.h 741#define DISPATCH_QUEUE_OVERCOMMIT 2 742#endif 743 744#if DEPLOYMENT_TARGET_WINDOWS 745CF_PRIVATE const wchar_t *_CFDLLPath(void); 746#endif 747 748/* Buffer size for file pathname */ 749#if DEPLOYMENT_TARGET_WINDOWS 750#define CFMaxPathSize ((CFIndex)262) 751#define CFMaxPathLength ((CFIndex)260) 752#define PATH_SEP '\\' 753#define PATH_SEP_STR CFSTR("\\") 754#define PATH_MAX MAX_PATH 755#else 756#define CFMaxPathSize ((CFIndex)1026) 757#define CFMaxPathLength ((CFIndex)1024) 758#define PATH_SEP '/' 759#define PATH_SEP_STR CFSTR("/") 760#endif 761 762CF_INLINE const char *CFPathRelativeToAppleFrameworksRoot(const char *path, Boolean *allocated) { 763 if (path) { 764 const char *platformRoot = __CFgetenv("APPLE_FRAMEWORKS_ROOT"); 765 if (platformRoot) { 766 char *newPath = NULL; 767 asprintf(&newPath, "%s%s", platformRoot, path); 768 if (allocated && newPath) { 769 *allocated = true; 770 } 771 return newPath; 772 } 773 } 774 if (allocated) { 775 *allocated = false; 776 } 777 return path; 778} 779 780CF_EXTERN_C_END 781 782#endif /* ! __COREFOUNDATION_CFINTERNAL__ */ 783 784