Skip to content

Commit 2642df9

Browse files
Concurrency: Replace swjs_thread_local_closures with LazyThreadLocal
1 parent 30f78ff commit 2642df9

File tree

3 files changed

+8
-21
lines changed

3 files changed

+8
-21
lines changed

Diff for: Sources/JavaScriptKit/FundamentalObjects/JSClosure.swift

+8-14
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public class JSOneshotClosure: JSObject, JSClosureProtocol {
2626
}
2727

2828
// 3. Retain the given body in static storage by `funcRef`.
29-
JSClosure.sharedClosures[hostFuncRef] = (self, {
29+
JSClosure.sharedClosures.wrappedValue[hostFuncRef] = (self, {
3030
defer { self.release() }
3131
return body($0)
3232
})
@@ -42,7 +42,7 @@ public class JSOneshotClosure: JSObject, JSClosureProtocol {
4242
/// Release this function resource.
4343
/// After calling `release`, calling this function from JavaScript will fail.
4444
public func release() {
45-
JSClosure.sharedClosures[hostFuncRef] = nil
45+
JSClosure.sharedClosures.wrappedValue[hostFuncRef] = nil
4646
}
4747
}
4848

@@ -74,14 +74,8 @@ public class JSClosure: JSFunction, JSClosureProtocol {
7474
}
7575

7676
// Note: Retain the closure object itself also to avoid funcRef conflicts
77-
fileprivate static var sharedClosures: SharedJSClosure {
78-
if let swjs_thread_local_closures {
79-
return Unmanaged<SharedJSClosure>.fromOpaque(swjs_thread_local_closures).takeUnretainedValue()
80-
} else {
81-
let shared = SharedJSClosure()
82-
swjs_thread_local_closures = Unmanaged.passRetained(shared).toOpaque()
83-
return shared
84-
}
77+
fileprivate static let sharedClosures = LazyThreadLocal {
78+
SharedJSClosure()
8579
}
8680

8781
private var hostFuncRef: JavaScriptHostFuncRef = 0
@@ -110,7 +104,7 @@ public class JSClosure: JSFunction, JSClosureProtocol {
110104
}
111105

112106
// 3. Retain the given body in static storage by `funcRef`.
113-
Self.sharedClosures[hostFuncRef] = (self, body)
107+
Self.sharedClosures.wrappedValue[hostFuncRef] = (self, body)
114108
}
115109

116110
#if compiler(>=5.5) && !hasFeature(Embedded)
@@ -192,7 +186,7 @@ func _call_host_function_impl(
192186
_ argv: UnsafePointer<RawJSValue>, _ argc: Int32,
193187
_ callbackFuncRef: JavaScriptObjectRef
194188
) -> Bool {
195-
guard let (_, hostFunc) = JSClosure.sharedClosures[hostFuncRef] else {
189+
guard let (_, hostFunc) = JSClosure.sharedClosures.wrappedValue[hostFuncRef] else {
196190
return true
197191
}
198192
let arguments = UnsafeBufferPointer(start: argv, count: Int(argc)).map { $0.jsValue}
@@ -232,7 +226,7 @@ extension JSClosure {
232226

233227
@_cdecl("_free_host_function_impl")
234228
func _free_host_function_impl(_ hostFuncRef: JavaScriptHostFuncRef) {
235-
JSClosure.sharedClosures[hostFuncRef] = nil
229+
JSClosure.sharedClosures.wrappedValue[hostFuncRef] = nil
236230
}
237231
#endif
238232

@@ -251,4 +245,4 @@ public func _swjs_call_host_function(
251245
public func _swjs_free_host_function(_ hostFuncRef: JavaScriptHostFuncRef) {
252246
_free_host_function_impl(hostFuncRef)
253247
}
254-
#endif
248+
#endif

Diff for: Sources/_CJavaScriptKit/_CJavaScriptKit.c

-2
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,3 @@ int swjs_library_features(void) {
6161
}
6262
#endif
6363
#endif
64-
65-
_Thread_local void *swjs_thread_local_closures;

Diff for: Sources/_CJavaScriptKit/include/_CJavaScriptKit.h

-5
Original file line numberDiff line numberDiff line change
@@ -308,9 +308,4 @@ IMPORT_JS_FUNCTION(swjs_terminate_worker_thread, void, (int tid))
308308

309309
IMPORT_JS_FUNCTION(swjs_get_worker_thread_id, int, (void))
310310

311-
/// MARK: - thread local storage
312-
313-
// TODO: Rewrite closure system without global storage
314-
extern _Thread_local void * _Nullable swjs_thread_local_closures;
315-
316311
#endif /* _CJavaScriptKit_h */

0 commit comments

Comments
 (0)