@@ -138,34 +138,37 @@ public final class WebWorkerTaskExecutor: TaskExecutor {
138138 /// Enqueue a job to the worker.
139139 func enqueue( _ job: UnownedJob ) {
140140 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
160168 }
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
167169 }
168- }
170+ locked = result != nil
171+ } while !locked
169172 }
170173
171174 func scheduleNextRun( ) {
0 commit comments