diff --git a/src/bun.js/api/bun/subprocess.zig b/src/bun.js/api/bun/subprocess.zig index 6999c9a54b..148b47ea05 100644 --- a/src/bun.js/api/bun/subprocess.zig +++ b/src/bun.js/api/bun/subprocess.zig @@ -1506,6 +1506,13 @@ fn consumeOnDisconnectCallback(this_jsvalue: JSValue, globalThis: *JSC.JSGlobalO pub fn onProcessExit(this: *Subprocess, process: *Process, status: bun.spawn.Status, rusage: *const Rusage) void { log("onProcessExit()", .{}); + // Ensure that under no circumstances we cause the subprocess to get freed inside this function. + this.ref(); + defer this.deref(); + + // The process no longer keeps the Subprocess alive. + defer this.deref(); + const this_jsvalue = this.this_jsvalue; const globalThis = this.globalThis; const jsc_vm = globalThis.bunVM(); @@ -1514,7 +1521,6 @@ pub fn onProcessExit(this: *Subprocess, process: *Process, status: bun.spawn.Sta const is_sync = this.flags.is_sync; this.clearAbortSignal(); - defer this.deref(); defer this.disconnectIPC(true); if (this.event_loop_timer.state == .ACTIVE) { @@ -1579,12 +1585,12 @@ pub fn onProcessExit(this: *Subprocess, process: *Process, status: bun.spawn.Sta pipe.onAttachedProcessExit(&status); } - var did_update_has_pending_activity = false; - defer if (!did_update_has_pending_activity) this.updateHasPendingActivity(); - - const loop = jsc_vm.eventLoop(); - if (!is_sync) { + var did_update_has_pending_activity = false; + defer if (!did_update_has_pending_activity) this.updateHasPendingActivity(); + + const loop = jsc_vm.eventLoop(); + if (this_jsvalue != .zero) { if (consumeExitedPromise(this_jsvalue, globalThis)) |promise| { loop.enter(); @@ -1692,6 +1698,8 @@ pub fn finalizeStreams(this: *Subprocess) void { fn deinit(this: *Subprocess) void { log("deinit", .{}); + + this.process.deref(); bun.destroy(this); } @@ -1717,7 +1725,6 @@ pub fn finalize(this: *Subprocess) callconv(.C) void { this.finalizeStreams(); this.process.detach(); - this.process.deref(); if (this.event_loop_timer.state == .ACTIVE) { this.globalThis.bunVM().timer.remove(&this.event_loop_timer);