From 85c4e87cccec3d426afaabe6839b56baa1d64738 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Thu, 14 Mar 2024 08:00:24 +0100 Subject: [PATCH] Fixes #9404 --- packages/bun-types/bun.d.ts | 8 +++--- src/bun.js/api/bun/process.zig | 8 ++++-- .../bun/spawn/spawn_waiter_thread-fixture.js | 7 +++++ test/js/bun/spawn/spawn_waiter_thread.test.ts | 27 +++++++++++++++++++ 4 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 test/js/bun/spawn/spawn_waiter_thread-fixture.js create mode 100644 test/js/bun/spawn/spawn_waiter_thread.test.ts diff --git a/packages/bun-types/bun.d.ts b/packages/bun-types/bun.d.ts index eba5406587..5e32060423 100644 --- a/packages/bun-types/bun.d.ts +++ b/packages/bun-types/bun.d.ts @@ -4195,19 +4195,19 @@ declare module "bun" { }; /** - * The amount of CPU time used by the process, in nanoseconds. + * The amount of CPU time used by the process, in microseconds. */ cpuTime: { /** - * User CPU time used by the process, in nanoseconds. + * User CPU time used by the process, in microseconds. */ user: number; /** - * System CPU time used by the process, in nanoseconds. + * System CPU time used by the process, in microseconds. */ system: number; /** - * Total CPU time used by the process, in nanoseconds. + * Total CPU time used by the process, in microseconds. */ total: number; }; diff --git a/src/bun.js/api/bun/process.zig b/src/bun.js/api/bun/process.zig index 4c2f86a336..ebfec7f0fb 100644 --- a/src/bun.js/api/bun/process.zig +++ b/src/bun.js/api/bun/process.zig @@ -849,9 +849,13 @@ const WaiterThreadPosix = struct { _ = std.os.poll(&polls, std.math.maxInt(i32)) catch 0; - // Make sure we consume any pending signals + // Make sure we consume any pending: + // - signals + // - eventfd + // See https://github.com/oven-sh/bun/issues/9404 var buf: [1024]u8 = undefined; - _ = std.os.read(this.signalfd.cast(), &buf) catch 0; + while (bun.sys.read(this.signalfd.cast(), &buf).unwrap() catch 0 > 0) {} + while (bun.sys.read(this.eventfd.cast(), &buf).unwrap() catch 0 > 0) {} } else { var mask = std.os.empty_sigset; var signal: c_int = std.os.SIG.CHLD; diff --git a/test/js/bun/spawn/spawn_waiter_thread-fixture.js b/test/js/bun/spawn/spawn_waiter_thread-fixture.js new file mode 100644 index 0000000000..f1cb253d8f --- /dev/null +++ b/test/js/bun/spawn/spawn_waiter_thread-fixture.js @@ -0,0 +1,7 @@ +const { spawn } = require("child_process"); + +if (!process.env.BUN_GARBAGE_COLLECTOR_LEVEL || !process.env.BUN_FEATURE_FLAG_FORCE_WAITER_THREAD) { + throw new Error("This test must be run with BUN_GARBAGE_COLLECTOR_LEVEL and BUN_FEATURE_FLAG_FORCE_WAITER_THREAD"); +} + +spawn("sleep", ["infinity"]).ref(); diff --git a/test/js/bun/spawn/spawn_waiter_thread.test.ts b/test/js/bun/spawn/spawn_waiter_thread.test.ts new file mode 100644 index 0000000000..4d90f7020a --- /dev/null +++ b/test/js/bun/spawn/spawn_waiter_thread.test.ts @@ -0,0 +1,27 @@ +import { test, expect } from "bun:test"; +import { spawn } from "bun"; +import { bunEnv, bunExe } from "harness"; +import { join } from "path"; + +if (process.platform === "linux") { + test("issue #9404", async () => { + const proc = spawn({ + env: { + ...bunEnv, + BUN_GARBAGE_COLLECTOR_LEVEL: "1", + BUN_FEATURE_FLAG_FORCE_WAITER_THREAD: "1", + }, + stderr: "inherit", + cmd: [bunExe(), join(__dirname, "spawn_waiter_thread-fixture.js")], + }); + + setTimeout(() => { + proc.kill(); + }, 1000); + + await proc.exited; + + const resourceUsage = proc.resourceUsage(); + expect(resourceUsage?.cpuTime.total).toBeLessThan(750_000n); + }); +}