Skip to content

Commit f00918c

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 3cd1f79 commit f00918c

File tree

5 files changed

+103
-75
lines changed

5 files changed

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