Skip to content

Commit 5bb449b

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 263ce3c commit 5bb449b

File tree

5 files changed

+105
-75
lines changed

5 files changed

+105
-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: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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+
#elif TARGET_OS_WIN32
35+
36+
#define NOMINMAX
37+
#define WIN32_LEAN_AND_MEAN
38+
#define VCEXTRALEAN
39+
#include <Windows.h>
40+
41+
typedef int32_t CFLock_t;
42+
#define CFLockInit 0
43+
#define CF_LOCK_INIT_FOR_STRUCTS(X) (X = CFLockInit)
44+
45+
CF_INLINE void __CFLock(volatile CFLock_t *lock) {
46+
while (InterlockedCompareExchange((LONG volatile *)lock, ~0, 0) != 0) {
47+
Sleep(0);
48+
}
49+
}
50+
51+
CF_INLINE void __CFUnlock(volatile CFLock_t *lock) {
52+
MemoryBarrier();
53+
*lock = 0;
54+
}
55+
56+
CF_INLINE Boolean __CFLockTry(volatile CFLock_t *lock) {
57+
return (InterlockedCompareExchange((LONG volatile *)lock, ~0, 0) == 0);
58+
}
59+
60+
#elif TARGET_OS_LINUX || TARGET_OS_BSD
61+
62+
#include <stdint.h>
63+
64+
typedef int32_t CFLock_t;
65+
#define CFLockInit 0
66+
#define CF_LOCK_INIT_FOR_STRUCTS(X) (X = CFLockInit)
67+
68+
CF_INLINE void __CFLock(volatile CFLock_t *lock) {
69+
while (__sync_val_compare_and_swap(lock, 0, ~0) != 0) {
70+
sleep(0);
71+
}
72+
}
73+
74+
CF_INLINE void __CFUnlock(volatile CFLock_t *lock) {
75+
__sync_synchronize();
76+
*lock = 0;
77+
}
78+
79+
CF_INLINE Boolean __CFLockTry(volatile CFLock_t *lock) {
80+
return (__sync_val_compare_and_swap(lock, 0, ~0) == 0);
81+
}
82+
83+
typedef CFLock_t OSSpinLock;
84+
#define OS_SPINLOCK_INIT CFLockInit
85+
#define OSSpinLockLock(lock) __CFLock(lock)
86+
#define OSSpinLockUnlock(lock) __CFUnlock(lock)
87+
88+
#else
89+
90+
#warning CF locks not defined for this platform -- CF is not thread-safe
91+
#define __CFLock(A) do {} while (0)
92+
#define __CFUnlock(A) do {} while (0)
93+
94+
#endif
95+
96+
#endif
97+

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/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)