@@ -138,34 +138,37 @@ public final class WebWorkerTaskExecutor: TaskExecutor {
138
138
/// Enqueue a job to the worker.
139
139
func enqueue( _ job: UnownedJob ) {
140
140
statsIncrement ( \. enqueuedJobs)
141
- jobQueue. withLock { queue in
142
- queue. append ( job)
143
-
144
- // Wake up the worker to process a job.
145
- switch state. exchange ( . running, ordering: . sequentiallyConsistent) {
146
- case . idle:
147
- if Self . currentThread === self {
148
- // Enqueueing a new job to the current worker thread, but it's idle now.
149
- // This is usually the case when a continuation is resumed by JS events
150
- // like `setTimeout` or `addEventListener`.
151
- // We can run the job and subsequently spawned jobs immediately.
152
- // JSPromise.resolve(JSValue.undefined).then { _ in
153
- _ = JSObject . global. queueMicrotask!( JSOneshotClosure { _ in
154
- self . run ( )
155
- return JSValue . undefined
156
- } )
157
- } else {
158
- let tid = self . tid. load ( ordering: . sequentiallyConsistent)
159
- swjs_wake_up_worker_thread ( tid)
141
+ var locked : Bool
142
+ repeat {
143
+ let result : Void ? = jobQueue. withLockIfAvailable { queue in
144
+ queue. append ( job)
145
+ // Wake up the worker to process a job.
146
+ switch state. exchange ( . running, ordering: . sequentiallyConsistent) {
147
+ case . idle:
148
+ if Self . currentThread === self {
149
+ // Enqueueing a new job to the current worker thread, but it's idle now.
150
+ // This is usually the case when a continuation is resumed by JS events
151
+ // like `setTimeout` or `addEventListener`.
152
+ // We can run the job and subsequently spawned jobs immediately.
153
+ // JSPromise.resolve(JSValue.undefined).then { _ in
154
+ _ = JSObject . global. queueMicrotask!( JSOneshotClosure { _ in
155
+ self . run ( )
156
+ return JSValue . undefined
157
+ } )
158
+ } else {
159
+ let tid = self . tid. load ( ordering: . sequentiallyConsistent)
160
+ swjs_wake_up_worker_thread ( tid)
161
+ }
162
+ case . running:
163
+ // The worker is already running, no need to wake up.
164
+ break
165
+ case . terminated:
166
+ // Will not wake up the worker because it's already terminated.
167
+ break
160
168
}
161
- case . running:
162
- // The worker is already running, no need to wake up.
163
- break
164
- case . terminated:
165
- // Will not wake up the worker because it's already terminated.
166
- break
167
169
}
168
- }
170
+ locked = result != nil
171
+ } while !locked
169
172
}
170
173
171
174
func scheduleNextRun( ) {
0 commit comments