Skip to content

Commit 568a1ac

Browse files
committed
Foundation/CoreFoundation: repair bridging for NSLocale
`NSLocale` is toll-free bridged to `CFLocale`. The types must match. On many targets, the backing store for `_lock` was being elided as the value was conditionally defined. Extract the locking macros/types into a `CFLocking.h` and then include that into `CFInternal.h` and `ForSwiftFoundationOnly.h`. This allows the underlying type information to be shared into Swift permitting the `__CFLocale` type to be reconstructed without guessing as to the underlying type. This repairs the bridging of `NSLocale` on Windows and allows us to get further in the test suite.
1 parent 155f1ce commit 568a1ac

File tree

6 files changed

+118
-75
lines changed

6 files changed

+118
-75
lines changed

Diff for: CoreFoundation/Base.subproj/CFInternal.h

+1-68
Original file line numberDiff line numberDiff line change
@@ -508,74 +508,7 @@ CF_PRIVATE Boolean __CFProphylacticAutofsAccess;
508508
CF_EXPORT id __NSDictionary0__;
509509
CF_EXPORT id __NSArray0__;
510510

511-
512-
#if TARGET_OS_MAC
513-
514-
typedef pthread_mutex_t CFLock_t;
515-
516-
#define CFLockInit ((pthread_mutex_t)PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
517-
#define CF_LOCK_INIT_FOR_STRUCTS(X) (X = CFLockInit)
518-
519-
#define __CFLock(LP) ({ (void)pthread_mutex_lock(LP); })
520-
521-
#define __CFUnlock(LP) ({ (void)pthread_mutex_unlock(LP); })
522-
523-
#define __CFLockTry(LP) ({ pthread_mutex_trylock(LP) == 0; })
524-
525-
#elif DEPLOYMENT_TARGET_WINDOWS
526-
527-
typedef int32_t CFLock_t;
528-
#define CFLockInit 0
529-
#define CF_LOCK_INIT_FOR_STRUCTS(X) (X = CFLockInit)
530-
531-
CF_INLINE void __CFLock(volatile CFLock_t *lock) {
532-
while (InterlockedCompareExchange((LONG volatile *)lock, ~0, 0) != 0) {
533-
Sleep(0);
534-
}
535-
}
536-
537-
CF_INLINE void __CFUnlock(volatile CFLock_t *lock) {
538-
MemoryBarrier();
539-
*lock = 0;
540-
}
541-
542-
CF_INLINE Boolean __CFLockTry(volatile CFLock_t *lock) {
543-
return (InterlockedCompareExchange((LONG volatile *)lock, ~0, 0) == 0);
544-
}
545-
546-
#elif TARGET_OS_LINUX || TARGET_OS_BSD
547-
548-
typedef int32_t CFLock_t;
549-
#define CFLockInit 0
550-
#define CF_LOCK_INIT_FOR_STRUCTS(X) (X = CFLockInit)
551-
552-
CF_INLINE void __CFLock(volatile CFLock_t *lock) {
553-
while (__sync_val_compare_and_swap(lock, 0, ~0) != 0) {
554-
sleep(0);
555-
}
556-
}
557-
558-
CF_INLINE void __CFUnlock(volatile CFLock_t *lock) {
559-
__sync_synchronize();
560-
*lock = 0;
561-
}
562-
563-
CF_INLINE Boolean __CFLockTry(volatile CFLock_t *lock) {
564-
return (__sync_val_compare_and_swap(lock, 0, ~0) == 0);
565-
}
566-
567-
typedef CFLock_t OSSpinLock;
568-
#define OS_SPINLOCK_INIT CFLockInit
569-
#define OSSpinLockLock(lock) __CFLock(lock)
570-
#define OSSpinLockUnlock(lock) __CFUnlock(lock)
571-
572-
#else
573-
574-
#warning CF locks not defined for this platform -- CF is not thread-safe
575-
#define __CFLock(A) do {} while (0)
576-
#define __CFUnlock(A) do {} while (0)
577-
578-
#endif
511+
#include <CoreFoundation/CFLocking.h>
579512

580513
#if __has_include(<os/lock.h>)
581514
#include <os/lock.h>

Diff for: CoreFoundation/Base.subproj/CFLocking.h

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/* CFInternal.h
2+
Copyright (c) 1998-2018, Apple Inc. and the Swift project authors
3+
4+
Portions Copyright (c) 2014-2018, Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
See http://swift.org/LICENSE.txt for license information
7+
See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
8+
*/
9+
10+
/*
11+
NOT TO BE USED OUTSIDE CF!
12+
*/
13+
14+
#if !defined(__COREFOUNDATION_CFLOCKING_H__)
15+
#define __COREFOUNDATION_CFLOCKING_H__ 1
16+
17+
#include <CoreFoundation/TargetConditionals.h>
18+
19+
#if TARGET_OS_MAC
20+
21+
#include <pthread.h>
22+
23+
typedef pthread_mutex_t CFLock_t;
24+
25+
#define CFLockInit ((pthread_mutex_t)PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
26+
#define CF_LOCK_INIT_FOR_STRUCTS(X) (X = CFLockInit)
27+
28+
#define __CFLock(LP) ({ (void)pthread_mutex_lock(LP); })
29+
30+
#define __CFUnlock(LP) ({ (void)pthread_mutex_unlock(LP); })
31+
32+
#define __CFLockTry(LP) ({ pthread_mutex_trylock(LP) == 0; })
33+
34+
// SPI to permit initialization of values in Swift
35+
static inline CFLock_t __CFLockInit(void) { return CFLockInit; }
36+
37+
#elif TARGET_OS_WIN32
38+
39+
#define NOMINMAX
40+
#define WIN32_LEAN_AND_MEAN
41+
#define VCEXTRALEAN
42+
#include <Windows.h>
43+
44+
typedef int32_t CFLock_t;
45+
#define CFLockInit 0
46+
#define CF_LOCK_INIT_FOR_STRUCTS(X) (X = CFLockInit)
47+
48+
CF_INLINE void __CFLock(volatile CFLock_t *lock) {
49+
while (InterlockedCompareExchange((LONG volatile *)lock, ~0, 0) != 0) {
50+
Sleep(0);
51+
}
52+
}
53+
54+
CF_INLINE void __CFUnlock(volatile CFLock_t *lock) {
55+
MemoryBarrier();
56+
*lock = 0;
57+
}
58+
59+
CF_INLINE Boolean __CFLockTry(volatile CFLock_t *lock) {
60+
return (InterlockedCompareExchange((LONG volatile *)lock, ~0, 0) == 0);
61+
}
62+
63+
// SPI to permit initialization of values in Swift
64+
static inline CFLock_t __CFLockInit(void) { return CFLockInit; }
65+
66+
#elif TARGET_OS_LINUX || TARGET_OS_BSD
67+
68+
#include <stdint.h>
69+
70+
typedef int32_t CFLock_t;
71+
#define CFLockInit 0
72+
#define CF_LOCK_INIT_FOR_STRUCTS(X) (X = CFLockInit)
73+
74+
CF_INLINE void __CFLock(volatile CFLock_t *lock) {
75+
while (__sync_val_compare_and_swap(lock, 0, ~0) != 0) {
76+
sleep(0);
77+
}
78+
}
79+
80+
CF_INLINE void __CFUnlock(volatile CFLock_t *lock) {
81+
__sync_synchronize();
82+
*lock = 0;
83+
}
84+
85+
CF_INLINE Boolean __CFLockTry(volatile CFLock_t *lock) {
86+
return (__sync_val_compare_and_swap(lock, 0, ~0) == 0);
87+
}
88+
89+
// SPI to permit initialization of values in Swift
90+
static inline CFLock_t __CFLockInit(void) { return CFLockInit; }
91+
92+
typedef CFLock_t OSSpinLock;
93+
#define OS_SPINLOCK_INIT CFLockInit
94+
#define OSSpinLockLock(lock) __CFLock(lock)
95+
#define OSSpinLockUnlock(lock) __CFUnlock(lock)
96+
97+
#else
98+
99+
#warning CF locks not defined for this platform -- CF is not thread-safe
100+
#define __CFLock(A) do {} while (0)
101+
#define __CFUnlock(A) do {} while (0)
102+
103+
#endif
104+
105+
#endif
106+

Diff for: CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <CoreFoundation/CFBase.h>
1919
#include <CoreFoundation/CFNumber.h>
20+
#include <CoreFoundation/CFLocking.h>
2021
#include <CoreFoundation/CFLocaleInternal.h>
2122
#include <CoreFoundation/CFCalendar.h>
2223
#include <CoreFoundation/CFPriv.h>

Diff for: CoreFoundation/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ add_framework(CoreFoundation
127127
PUBLIC_HEADERS
128128
# FIXME: PrivateHeaders referenced by public headers
129129
Base.subproj/CFKnownLocations.h
130+
Base.subproj/CFLocking.h
130131
Base.subproj/CFLogUtilities.h
131132
Base.subproj/CFPriv.h
132133
Base.subproj/CFRuntime.h

Diff for: Foundation.xcodeproj/project.pbxproj

+4
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@
486486
EADE0BCB1BD15E0000C49C64 /* XMLNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADE0B8D1BD15DFF00C49C64 /* XMLNode.swift */; };
487487
EADE0BCD1BD15E0000C49C64 /* XMLParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADE0B8F1BD15DFF00C49C64 /* XMLParser.swift */; };
488488
F03A43181D4877DD00A7791E /* CFAsmMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = F03A43161D48778200A7791E /* CFAsmMacros.h */; settings = {ATTRIBUTES = (Private, ); }; };
489+
F085A1302283C5B700F909F9 /* CFLocking.h in Headers */ = {isa = PBXBuildFile; fileRef = F085A12E2283C50A00F909F9 /* CFLocking.h */; settings = {ATTRIBUTES = (Private, ); }; };
489490
F9E0BB371CA70B8000F7FF3C /* TestURLCredential.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9E0BB361CA70B8000F7FF3C /* TestURLCredential.swift */; };
490491
/* End PBXBuildFile section */
491492

@@ -1051,6 +1052,7 @@
10511052
EADE0B8D1BD15DFF00C49C64 /* XMLNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XMLNode.swift; sourceTree = "<group>"; };
10521053
EADE0B8F1BD15DFF00C49C64 /* XMLParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XMLParser.swift; sourceTree = "<group>"; };
10531054
F03A43161D48778200A7791E /* CFAsmMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFAsmMacros.h; sourceTree = "<group>"; };
1055+
F085A12E2283C50A00F909F9 /* CFLocking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFLocking.h; sourceTree = "<group>"; };
10541056
F9E0BB361CA70B8000F7FF3C /* TestURLCredential.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestURLCredential.swift; sourceTree = "<group>"; };
10551057
/* End PBXFileReference section */
10561058

@@ -1176,6 +1178,7 @@
11761178
5B5D88711BBC951A00234F36 /* Base */ = {
11771179
isa = PBXGroup;
11781180
children = (
1181+
F085A12E2283C50A00F909F9 /* CFLocking.h */,
11791182
1578DA12212B4C35003C9516 /* CFOverflow.h */,
11801183
F03A43161D48778200A7791E /* CFAsmMacros.h */,
11811184
5BDC3F721BCC60EF00ED97BB /* module.map */,
@@ -2110,6 +2113,7 @@
21102113
5B7C8AF91BEA81AC00C5B690 /* CFStringEncodingDatabase.h in Headers */,
21112114
EA66F6361BEED03E00136161 /* TargetConditionals.h in Headers */,
21122115
1569BFAE2187D529009518FA /* CFDateComponents.h in Headers */,
2116+
F085A1302283C5B700F909F9 /* CFLocking.h in Headers */,
21132117
5B7C8B001BEA82ED00C5B690 /* CFRuntime.h in Headers */,
21142118
5BF9B7F31FABBDB900EE1A7C /* CFPropertyList_Private.h in Headers */,
21152119
5B7C8ABE1BEA807A00C5B690 /* CFByteOrder.h in Headers */,

Diff for: Foundation/NSLocale.swift

+5-7
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,15 @@ import CoreFoundation
1212

1313
open class NSLocale: NSObject, NSCopying, NSSecureCoding, _CFBridgeable {
1414
typealias CFType = CFLocale
15+
16+
// struct __CFLocale
1517
private var _base = _CFInfo(typeID: CFLocaleGetTypeID())
1618
private var _identifier: UnsafeMutableRawPointer? = nil
1719
private var _cache: UnsafeMutableRawPointer? = nil
1820
private var _prefs: UnsafeMutableRawPointer? = nil
19-
#if os(macOS) || os(iOS)
20-
private var _lock = pthread_mutex_t()
21-
#elseif os(Linux) || os(Android) || CYGWIN
22-
private var _lock = Int32(0)
23-
#endif
24-
private var _nullLocale = false
25-
21+
private var _lock: CFLock_t = __CFLockInit()
22+
private var _nullLocale: Bool = false
23+
2624
internal var _cfObject: CFType {
2725
return unsafeBitCast(self, to: CFType.self)
2826
}

0 commit comments

Comments
 (0)