Skip to content

Commit 1d3ee23

Browse files
committed
Use swift::once instead of swift_once to clean up the code a little, and make sure we unconditionally set the state from CF to make sure it's set even if we failed a lazy load earlier
(cherry picked from commit 1394a8e)
1 parent 282a9a7 commit 1d3ee23

File tree

1 file changed

+29
-34
lines changed

1 file changed

+29
-34
lines changed

stdlib/public/stubs/FoundationHelpers.mm

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,12 @@
4747
//version 0 ends here
4848
} CFBridgingState;
4949

50-
static CFBridgingState *bridgingState;
50+
static CFBridgingState const * bridgingState;
5151
static swift_once_t initializeBridgingStateOnce;
5252

5353
extern "C" bool _dyld_is_objc_constant(DyldObjCConstantKind kind,
5454
const void *addr) SWIFT_RUNTIME_WEAK_IMPORT;
5555

56-
static void _initializeBridgingFunctionsFromCFImpl(void *ctxt) {
57-
bridgingState = (CFBridgingState *)ctxt;
58-
}
59-
6056
@class __SwiftNativeNSStringBase, __SwiftNativeNSError, __SwiftNativeNSArrayBase, __SwiftNativeNSMutableArrayBase, __SwiftNativeNSDictionaryBase, __SwiftNativeNSSetBase, __SwiftNativeNSEnumeratorBase;
6157

6258
static void _reparentClasses() {
@@ -93,41 +89,40 @@ static void _reparentClasses() {
9389
#pragma clang diagnostic pop
9490
}
9591

96-
static void _initializeBridgingFunctionsImpl(void *ctxt) {
97-
assert(!bridgingState);
98-
auto getStringTypeID = (CFTypeID(*)(void))dlsym(RTLD_DEFAULT, "CFStringGetTypeID");
99-
if (!getStringTypeID) {
100-
return; //CF not loaded
101-
}
102-
bridgingState = (CFBridgingState *)calloc(1, sizeof(CFBridgingState));
103-
bridgingState->version = 0;
104-
bridgingState->_CFStringTypeID = getStringTypeID();
105-
bridgingState->_CFGetTypeID = (CFTypeID(*)(CFTypeRef obj))dlsym(RTLD_DEFAULT, "CFGetTypeID");
106-
bridgingState->_CFStringHashNSString = (CFHashCode(*)(id))dlsym(RTLD_DEFAULT, "CFStringHashNSString");
107-
bridgingState->_CFStringHashCString = (CFHashCode(*)(const uint8_t *, CFIndex))dlsym(RTLD_DEFAULT, "CFStringHashCString");
108-
bridgingState->NSErrorClass = objc_lookUpClass("NSError");
109-
bridgingState->NSStringClass = objc_lookUpClass("NSString");
110-
bridgingState->NSArrayClass = objc_lookUpClass("NSArray");
111-
bridgingState->NSMutableArrayClass = objc_lookUpClass("NSMutableArray");
112-
bridgingState->NSSetClass = objc_lookUpClass("NSSet");
113-
bridgingState->NSDictionaryClass = objc_lookUpClass("NSDictionary");
114-
bridgingState->NSEnumeratorClass = objc_lookUpClass("NSEnumerator");
115-
_reparentClasses();
116-
}
117-
11892
static inline bool initializeBridgingFunctions() {
119-
swift_once(&initializeBridgingStateOnce,
120-
_initializeBridgingFunctionsImpl,
121-
nullptr);
93+
swift::once(initializeBridgingStateOnce, [](){
94+
assert(!bridgingState);
95+
auto getStringTypeID = (CFTypeID(*)(void))dlsym(RTLD_DEFAULT, "CFStringGetTypeID");
96+
if (!getStringTypeID) {
97+
return; //CF not loaded
98+
}
99+
auto state = (CFBridgingState *)calloc(1, sizeof(CFBridgingState));
100+
state->version = 0;
101+
state->_CFStringTypeID = getStringTypeID();
102+
state->_CFGetTypeID = (CFTypeID(*)(CFTypeRef obj))dlsym(RTLD_DEFAULT, "CFGetTypeID");
103+
state->_CFStringHashNSString = (CFHashCode(*)(id))dlsym(RTLD_DEFAULT, "CFStringHashNSString");
104+
state->_CFStringHashCString = (CFHashCode(*)(const uint8_t *, CFIndex))dlsym(RTLD_DEFAULT, "CFStringHashCString");
105+
state->NSErrorClass = objc_lookUpClass("NSError");
106+
state->NSStringClass = objc_lookUpClass("NSString");
107+
state->NSArrayClass = objc_lookUpClass("NSArray");
108+
state->NSMutableArrayClass = objc_lookUpClass("NSMutableArray");
109+
state->NSSetClass = objc_lookUpClass("NSSet");
110+
state->NSDictionaryClass = objc_lookUpClass("NSDictionary");
111+
state->NSEnumeratorClass = objc_lookUpClass("NSEnumerator");
112+
bridgingState = state;
113+
_reparentClasses();
114+
});
122115
return bridgingState && bridgingState->NSStringClass != nullptr;
123116
}
124117

125118
SWIFT_RUNTIME_EXPORT void swift_initializeCoreFoundationState(CFBridgingState const * const state) {
126-
swift_once(&initializeBridgingStateOnce,
127-
_initializeBridgingFunctionsFromCFImpl,
128-
(void *)state);
119+
//Consume the once token to make sure that the lazy version of this in initializeBridgingFunctions only runs if we didn't hit this
120+
swift::once(initializeBridgingStateOnce, [state](){
121+
bridgingState = state;
122+
});
129123
//It's fine if this runs more than once, it's a noop if it's been done before
130-
//and we want to make sure it happens if CF loads late after it failed initially
124+
//and we want to make sure it still happens if CF loads late after it failed initially
125+
bridgingState = state;
131126
_reparentClasses();
132127
}
133128

0 commit comments

Comments
 (0)