diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bun.js/api/bun/subprocess.zig | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/src/bun.js/api/bun/subprocess.zig b/src/bun.js/api/bun/subprocess.zig index 5695c15ad..b6e27d287 100644 --- a/src/bun.js/api/bun/subprocess.zig +++ b/src/bun.js/api/bun/subprocess.zig @@ -68,6 +68,7 @@ pub const Subprocess = struct { ipc_callback: JSC.Strong = .{}, ipc_buffer: bun.ByteList, + has_pending_unref: bool = false, pub const SignalCode = bun.SignalCode; pub const IPCMode = enum { @@ -82,7 +83,7 @@ pub const Subprocess = struct { pub fn updateHasPendingActivityFlag(this: *Subprocess) void { @fence(.SeqCst); - this.has_pending_activity.store(this.waitpid_err == null and this.exit_code == null and this.ipc == .none, .SeqCst); + this.has_pending_activity.store(this.waitpid_err == null and this.exit_code == null and this.ipc == .none and this.has_pending_unref, .SeqCst); } pub fn hasPendingActivity(this: *Subprocess) callconv(.C) bool { @@ -92,7 +93,7 @@ pub const Subprocess = struct { pub fn updateHasPendingActivity(this: *Subprocess) void { @fence(.Release); - this.has_pending_activity.store(this.waitpid_err == null and this.exit_code == null and this.ipc == .none, .Release); + this.has_pending_activity.store(this.waitpid_err == null and this.exit_code == null and this.ipc == .none and this.has_pending_unref, .Release); } pub fn ref(this: *Subprocess) void { @@ -111,8 +112,10 @@ pub const Subprocess = struct { } } + /// This disables the keeping process alive flag on the poll and also in the stdin, stdout, and stderr pub fn unref(this: *Subprocess) void { var vm = this.globalThis.bunVM(); + if (this.poll_ref) |poll| poll.disableKeepingProcessAlive(vm); if (!this.hasCalledGetter(.stdin)) { this.stdin.unref(); @@ -1805,8 +1808,29 @@ pub const Subprocess = struct { } } - if (this.hasExited()) - this.unref(); + if (this.hasExited()) { + const Holder = struct { + process: *Subprocess, + task: JSC.AnyTask, + + pub fn unref(self: *@This()) void { + // this calls disableKeepingProcessAlive on pool_ref and stdin, stdout, stderr + self.process.unref(); + self.process.has_pending_unref = false; + self.process.updateHasPendingActivity(); + bun.default_allocator.destroy(self); + } + }; + + var holder = bun.default_allocator.create(Holder) catch @panic("OOM"); + this.has_pending_unref = true; + holder.* = .{ + .process = this, + .task = JSC.AnyTask.New(Holder, Holder.unref).init(holder), + }; + + this.globalThis.bunVM().enqueueTask(JSC.Task.init(&holder.task)); + } } const os = std.os; |