diff --git a/src/bun.js/web_worker.zig b/src/bun.js/web_worker.zig index d9202314dd..a1ef9c2103 100644 --- a/src/bun.js/web_worker.zig +++ b/src/bun.js/web_worker.zig @@ -688,9 +688,18 @@ const WebWorkerLifecycleHandle = struct { } pub fn requestTermination(self: *WebWorkerLifecycleHandle) void { + if (self.requested_terminate.load(.acquire)) { + return; + } + self.ref(); self.mutex.lock(); - self.requested_terminate.store(true, .monotonic); + + if (self.requested_terminate.swap(true, .monotonic)) { + self.mutex.unlock(); + self.deref(); + return; + } if (self.worker) |worker| { self.worker = null; @@ -699,25 +708,28 @@ const WebWorkerLifecycleHandle = struct { worker.deref(); } else { self.mutex.unlock(); + // Let the reference counting system handle deinitialization self.deref(); - self.deinit(); } self.deref(); } pub fn onTermination(self: *WebWorkerLifecycleHandle) void { + self.ref(); self.mutex.lock(); if (self.requested_terminate.swap(false, .acquire)) { // we already requested to terminate, therefore this handle has // already been consumed on the other thread and we are able to free - // it. + // it. Let the reference counting system handle deinitialization. self.mutex.unlock(); - self.deinit(); + self.deref(); + self.deref(); // Extra deref to match the ref in requestTermination return; } self.worker = null; self.mutex.unlock(); + self.deref(); } };