mirror of
https://github.com/oven-sh/bun
synced 2026-02-15 13:22:07 +00:00
Drain microtasks in the Bun Shell
This commit is contained in:
@@ -843,6 +843,7 @@ pub const Interpreter = struct {
|
||||
async_commands_executing: u32 = 0,
|
||||
|
||||
globalThis: *JSC.JSGlobalObject,
|
||||
ref: bun.Async.KeepAlive = .{},
|
||||
|
||||
flags: packed struct(u8) {
|
||||
done: bool = false,
|
||||
@@ -1235,7 +1236,7 @@ pub const Interpreter = struct {
|
||||
interpreter.this_jsvalue = JSC.Codegen.JSShellInterpreter.toJS(interpreter, globalThis);
|
||||
JSC.Codegen.JSShellInterpreter.resolveSetCached(interpreter.this_jsvalue, globalThis, resolve);
|
||||
JSC.Codegen.JSShellInterpreter.rejectSetCached(interpreter.this_jsvalue, globalThis, reject);
|
||||
|
||||
interpreter.ref.activate(JSC.VirtualMachine.get().uwsLoop());
|
||||
bun.Analytics.Features.shell += 1;
|
||||
return interpreter.this_jsvalue;
|
||||
}
|
||||
@@ -1656,6 +1657,8 @@ pub const Interpreter = struct {
|
||||
defer decrPendingActivityFlag(&this.has_pending_activity);
|
||||
|
||||
if (this.event_loop == .js) {
|
||||
this.ref.disable();
|
||||
|
||||
defer this.deinitAfterJSRun();
|
||||
this.exit_code = exit_code;
|
||||
if (this.this_jsvalue != .zero) {
|
||||
@@ -1676,6 +1679,8 @@ pub const Interpreter = struct {
|
||||
defer decrPendingActivityFlag(&this.has_pending_activity);
|
||||
|
||||
if (this.event_loop == .js) {
|
||||
this.ref.disable();
|
||||
|
||||
if (this.this_jsvalue != .zero) {
|
||||
if (JSC.Codegen.JSShellInterpreter.rejectGetCached(this.this_jsvalue)) |reject| {
|
||||
reject.call(this.globalThis, &[_]JSValue{ JSValue.jsNumberFromChar(1), this.getBufferedStdout(), this.getBufferedStderr() });
|
||||
@@ -1692,6 +1697,7 @@ pub const Interpreter = struct {
|
||||
for (this.jsobjs) |jsobj| {
|
||||
jsobj.unprotect();
|
||||
}
|
||||
this.ref.disable();
|
||||
this.root_io.deref();
|
||||
this.root_shell.deinitImpl(false, false);
|
||||
this.this_jsvalue = .zero;
|
||||
@@ -1705,6 +1711,7 @@ pub const Interpreter = struct {
|
||||
this.root_shell._buffered_stdout.owned.deinitWithAllocator(bun.default_allocator);
|
||||
}
|
||||
this.this_jsvalue = .zero;
|
||||
this.ref.disable();
|
||||
this.allocator.destroy(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -949,7 +949,15 @@ pub const ShellSubprocess = struct {
|
||||
if (exit_code) |code| {
|
||||
if (this.cmd_parent) |cmd| {
|
||||
if (cmd.exit_code == null) {
|
||||
cmd.onExit(code);
|
||||
if (this.event_loop == .js) {
|
||||
const loop = this.event_loop.js;
|
||||
|
||||
loop.enter();
|
||||
defer loop.exit();
|
||||
cmd.onExit(code);
|
||||
} else {
|
||||
cmd.onExit(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
6
test/js/bun/shell/shell-keepalive-fixture-1.js
generated
Normal file
6
test/js/bun/shell/shell-keepalive-fixture-1.js
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
process.exitCode = 1;
|
||||
|
||||
(async () => {
|
||||
await Bun.$`ls .`;
|
||||
process.exit(0);
|
||||
})();
|
||||
6
test/js/bun/shell/shell-keepalive-fixture-2.js
generated
Normal file
6
test/js/bun/shell/shell-keepalive-fixture-2.js
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
process.exitCode = 1;
|
||||
|
||||
(async () => {
|
||||
await Bun.$`${process.execPath} -e "console.log('hi')"`;
|
||||
process.exit(0);
|
||||
})();
|
||||
11
test/js/bun/shell/shell-keepalive.test.ts
Normal file
11
test/js/bun/shell/shell-keepalive.test.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { join } from "path";
|
||||
import "harness";
|
||||
|
||||
test("shell should stay alive while a builtin command is in progress", async () => {
|
||||
expect([join(import.meta.dir, "shell-keepalive-fixture-1.js")]).toRun();
|
||||
});
|
||||
|
||||
test("shell should stay alive while a non-builtin command is in progress", async () => {
|
||||
expect([join(import.meta.dir, "shell-keepalive-fixture-2.js")]).toRun();
|
||||
});
|
||||
Reference in New Issue
Block a user