From 0c86f6dcc91c90fbe0169fa4c2865b48e8a0d4b8 Mon Sep 17 00:00:00 2001 From: Alistair Smith Date: Wed, 11 Jun 2025 15:57:47 -0700 Subject: [PATCH] let's see what ci thinks --- src/bun.js/web_worker.zig | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/bun.js/web_worker.zig b/src/bun.js/web_worker.zig index edc00f5579..3973cb23fc 100644 --- a/src/bun.js/web_worker.zig +++ b/src/bun.js/web_worker.zig @@ -448,7 +448,14 @@ fn onUnhandledRejection(vm: *jsc.VirtualMachine, globalObject: *jsc.JSGlobalObje }; jsc.markBinding(@src()); WebWorker__dispatchError(globalObject, worker.cpp_worker, bun.String.createUTF8(array.slice()), error_instance); - if (vm.worker) |worker_| worker_.lifecycle_handle.requestTermination(); + if (vm.worker) |worker_| { + // During unhandled rejection, we're already holding the API lock - now + // is the right time to set exit_called to true so that + // notifyNeedTermination uses vm.global.requestTermination() instead of + // vm.jsc.notifyNeedTermination() which avoid VMTraps assertion failures + worker_.exit_called = true; + worker_.lifecycle_handle.requestTermination(); + } } fn setStatus(this: *WebWorker, status: Status) void { @@ -572,11 +579,6 @@ pub fn setRefInternal(this: *WebWorker, value: bool) void { /// Implement process.exit(). May only be called from the Worker thread. pub fn exit(this: *WebWorker) void { this.exit_called = true; - - if (this.vm) |vm| { - vm.global.requestTermination(); - } - this.notifyNeedTermination(); } @@ -594,17 +596,15 @@ pub fn notifyNeedTermination(this: *WebWorker) void { if (this.vm) |vm| { vm.eventLoop().wakeup(); - // for process.exit() called from JavaScript, we only need to set the flag - // and wake up the event loop. The event loop will check hasRequestedTerminate() - // and exit cleanly. Calling notifyNeedTermination() while holding the js lock - // causes assertion failures in jsc - if (!this.exit_called) { - // only call jsc traps for external terminate requests - // (e.g worker.terminate() from parent thread) + if (this.exit_called) { + // For process.exit() called from JavaScript, use JSC's termination + // exception mechanism to interrupt ongoing JS execution + vm.global.requestTermination(); + } else { + // For external terminate requests (e.g worker.terminate() from parent thread), + // use VM traps system vm.jsc.notifyNeedTermination(); } - // if exit_called is true we're in process.exit() context and should - // let the event loop handle termination naturally } // TODO(@190n) delete