@@ -57,7 +57,28 @@ public final class JavaScriptEventLoop: SerialExecutor, @unchecked Sendable {
5757 }
5858
5959 /// A singleton instance of the Executor
60- public static let shared : JavaScriptEventLoop = {
60+ public static var shared : JavaScriptEventLoop {
61+ return _shared
62+ }
63+
64+ #if compiler(>=6.0) && _runtime(_multithreaded)
65+ // In multi-threaded environment, we have an event loop executor per
66+ // thread (per Web Worker). A job enqueued in one thread should be
67+ // executed in the same thread under this global executor.
68+ private static var _shared : JavaScriptEventLoop {
69+ if let tls = swjs_thread_local_event_loop {
70+ let eventLoop = Unmanaged < JavaScriptEventLoop > . fromOpaque ( tls) . takeUnretainedValue ( )
71+ return eventLoop
72+ }
73+ let eventLoop = create ( )
74+ swjs_thread_local_event_loop = Unmanaged . passRetained ( eventLoop) . toOpaque ( )
75+ return eventLoop
76+ }
77+ #else
78+ private static let _shared : JavaScriptEventLoop = create ( )
79+ #endif
80+
81+ private static func create( ) -> JavaScriptEventLoop {
6182 let promise = JSPromise ( resolver: { resolver -> Void in
6283 resolver ( . success( . undefined) )
6384 } )
@@ -79,7 +100,7 @@ public final class JavaScriptEventLoop: SerialExecutor, @unchecked Sendable {
79100 }
80101 )
81102 return eventLoop
82- } ( )
103+ }
83104
84105 private static var didInstallGlobalExecutor = false
85106
@@ -124,7 +145,7 @@ public final class JavaScriptEventLoop: SerialExecutor, @unchecked Sendable {
124145 JavaScriptEventLoop . shared. unsafeEnqueue ( job)
125146 }
126147 swift_task_enqueueMainExecutor_hook = unsafeBitCast ( swift_task_enqueueMainExecutor_hook_impl, to: UnsafeMutableRawPointer ? . self)
127-
148+
128149 didInstallGlobalExecutor = true
129150 }
130151
0 commit comments