@@ -57,7 +57,28 @@ public final class JavaScriptEventLoop: SerialExecutor, @unchecked Sendable {
57
57
}
58
58
59
59
/// 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 {
61
82
let promise = JSPromise ( resolver: { resolver -> Void in
62
83
resolver ( . success( . undefined) )
63
84
} )
@@ -79,7 +100,7 @@ public final class JavaScriptEventLoop: SerialExecutor, @unchecked Sendable {
79
100
}
80
101
)
81
102
return eventLoop
82
- } ( )
103
+ }
83
104
84
105
private static var didInstallGlobalExecutor = false
85
106
@@ -124,7 +145,7 @@ public final class JavaScriptEventLoop: SerialExecutor, @unchecked Sendable {
124
145
JavaScriptEventLoop . shared. unsafeEnqueue ( job)
125
146
}
126
147
swift_task_enqueueMainExecutor_hook = unsafeBitCast ( swift_task_enqueueMainExecutor_hook_impl, to: UnsafeMutableRawPointer ? . self)
127
-
148
+
128
149
didInstallGlobalExecutor = true
129
150
}
130
151
0 commit comments