Skip to content

Commit 1f7cb45

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 5577346 commit 1f7cb45

File tree

6 files changed

+107
-75
lines changed

6 files changed

+107
-75
lines changed

CoreFoundation/Base.subproj/CFInternal.h

Lines changed: 1 addition & 68 deletions
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 DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
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>
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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+
#if TARGET_OS_MAC
18+
19+
#include <pthread.h>
20+
21+
typedef pthread_mutex_t CFLock_t;
22+
23+
#define CFLockInit ((pthread_mutex_t)PTHREAD_ERRORCHECK_MUTEX_INITIALIZER)
24+
#define CF_LOCK_INIT_FOR_STRUCTS(X) (X = CFLockInit)
25+
26+
#define __CFLock(LP) ({ (void)pthread_mutex_lock(LP); })
27+
28+
#define __CFUnlock(LP) ({ (void)pthread_mutex_unlock(LP); })
29+
30+
#define __CFLockTry(LP) ({ pthread_mutex_trylock(LP) == 0; })
31+
32+
#elif DEPLOYMENT_TARGET_WINDOWS
33+
34+
#define NOMINMAX
35+
#define WIN32_LEAN_AND_MEAN
36+
#define VCEXTRALEAN
37+
#include <Windows.h>
38+
39+
typedef int32_t CFLock_t;
40+
#define CFLockInit 0
41+
#define CF_LOCK_INIT_FOR_STRUCTS(X) (X = CFLockInit)
42+
43+
CF_INLINE void __CFLock(volatile CFLock_t *lock) {
44+
while (InterlockedCompareExchange((LONG volatile *)lock, ~0, 0) != 0) {
45+
Sleep(0);
46+
}
47+
}
48+
49+
CF_INLINE void __CFUnlock(volatile CFLock_t *lock) {
50+
MemoryBarrier();
51+
*lock = 0;
52+
}
53+
54+
CF_INLINE Boolean __CFLockTry(volatile CFLock_t *lock) {
55+
return (InterlockedCompareExchange((LONG volatile *)lock, ~0, 0) == 0);
56+
}
57+
58+
#elif DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
59+
60+
#include <stdint.h>
61+
62+
typedef int32_t CFLock_t;
63+
#define CFLockInit 0
64+
#define CF_LOCK_INIT_FOR_STRUCTS(X) (X = CFLockInit)
65+
66+
CF_INLINE void __CFLock(volatile CFLock_t *lock) {
67+
while (__sync_val_compare_and_swap(lock, 0, ~0) != 0) {
68+
sleep(0);
69+
}
70+
}
71+
72+
CF_INLINE void __CFUnlock(volatile CFLock_t *lock) {
73+
__sync_synchronize();
74+
*lock = 0;
75+
}
76+
77+
CF_INLINE Boolean __CFLockTry(volatile CFLock_t *lock) {
78+
return (__sync_val_compare_and_swap(lock, 0, ~0) == 0);
79+
}
80+
81+
typedef CFLock_t OSSpinLock;
82+
#define OS_SPINLOCK_INIT CFLockInit
83+
#define OSSpinLockLock(lock) __CFLock(lock)
84+
#define OSSpinLockUnlock(lock) __CFUnlock(lock)
85+
86+
#else
87+
88+
#warning CF locks not defined for this platform -- CF is not thread-safe
89+
#define __CFLock(A) do {} while (0)
90+
#define __CFUnlock(A) do {} while (0)
91+
92+
#endif
93+
94+
#endif
95+

CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h

Lines changed: 1 addition & 0 deletions
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>

CoreFoundation/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
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

Foundation.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@
485485
EADE0BCB1BD15E0000C49C64 /* XMLNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADE0B8D1BD15DFF00C49C64 /* XMLNode.swift */; };
486486
EADE0BCD1BD15E0000C49C64 /* XMLParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADE0B8F1BD15DFF00C49C64 /* XMLParser.swift */; };
487487
F03A43181D4877DD00A7791E /* CFAsmMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = F03A43161D48778200A7791E /* CFAsmMacros.h */; settings = {ATTRIBUTES = (Private, ); }; };
488+
F085A1302283C5B700F909F9 /* CFLocking.h in Headers */ = {isa = PBXBuildFile; fileRef = F085A12E2283C50A00F909F9 /* CFLocking.h */; settings = {ATTRIBUTES = (Private, ); }; };
488489
F9E0BB371CA70B8000F7FF3C /* TestURLCredential.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9E0BB361CA70B8000F7FF3C /* TestURLCredential.swift */; };
489490
/* End PBXBuildFile section */
490491

@@ -1049,6 +1050,7 @@
10491050
EADE0B8D1BD15DFF00C49C64 /* XMLNode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XMLNode.swift; sourceTree = "<group>"; };
10501051
EADE0B8F1BD15DFF00C49C64 /* XMLParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XMLParser.swift; sourceTree = "<group>"; };
10511052
F03A43161D48778200A7791E /* CFAsmMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFAsmMacros.h; sourceTree = "<group>"; };
1053+
F085A12E2283C50A00F909F9 /* CFLocking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFLocking.h; sourceTree = "<group>"; };
10521054
F9E0BB361CA70B8000F7FF3C /* TestURLCredential.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestURLCredential.swift; sourceTree = "<group>"; };
10531055
/* End PBXFileReference section */
10541056

@@ -1174,6 +1176,7 @@
11741176
5B5D88711BBC951A00234F36 /* Base */ = {
11751177
isa = PBXGroup;
11761178
children = (
1179+
F085A12E2283C50A00F909F9 /* CFLocking.h */,
11771180
1578DA12212B4C35003C9516 /* CFOverflow.h */,
11781181
F03A43161D48778200A7791E /* CFAsmMacros.h */,
11791182
5BDC3F721BCC60EF00ED97BB /* module.map */,
@@ -2107,6 +2110,7 @@
21072110
5B7C8AF91BEA81AC00C5B690 /* CFStringEncodingDatabase.h in Headers */,
21082111
EA66F6361BEED03E00136161 /* TargetConditionals.h in Headers */,
21092112
1569BFAE2187D529009518FA /* CFDateComponents.h in Headers */,
2113+
F085A1302283C5B700F909F9 /* CFLocking.h in Headers */,
21102114
5B7C8B001BEA82ED00C5B690 /* CFRuntime.h in Headers */,
21112115
5BF9B7F31FABBDB900EE1A7C /* CFPropertyList_Private.h in Headers */,
21122116
5B7C8ABE1BEA807A00C5B690 /* CFByteOrder.h in Headers */,

Foundation/NSLocale.swift

Lines changed: 5 additions & 7 deletions
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)