diff --git a/scripts/build/deps/libuv.ts b/scripts/build/deps/libuv.ts index 97482ebe6112..36aa54ce7be0 100644 --- a/scripts/build/deps/libuv.ts +++ b/scripts/build/deps/libuv.ts @@ -12,8 +12,9 @@ import type { Dependency } from "../source.ts"; // Tip of oven-sh/libuv's `bun` branch: upstream f3ce527e + win-pipe CancelIoEx // fix, ConPTY uv_spawn, AppContainer pipe namespace (oven-sh/libuv#7), fs/tty -// fixes (oven-sh/libuv#8). To bump, update `bun`. -const LIBUV_COMMIT = "f6e75a7efdc8651ace3b0d07efbfd0b3e5037278"; +// fixes (oven-sh/libuv#8), high-res poll timeouts (oven-sh/libuv#9). To bump, +// update `bun`. +const LIBUV_COMMIT = "96873308d4505884ba4f82ac89905fe0fd97eb9e"; // prettier-ignore const SHARED = [ diff --git a/test/js/web/timers/setTimeout.test.js b/test/js/web/timers/setTimeout.test.js index 651d066a444c..2d58c88271b2 100644 --- a/test/js/web/timers/setTimeout.test.js +++ b/test/js/web/timers/setTimeout.test.js @@ -644,6 +644,44 @@ it("clearTimeout with a numeric id is a no-op after a timeout promoted to an int expect(exitCode).toBe(0); }); +it("setTimeout(1) is not quantized to the ~15.6ms Windows system tick", async () => { + // Subprocess so no other in-process work has raised the Windows tick + // resolution; median of 50 so a single scheduler hiccup on a busy CI + // runner does not fail the assertion. + await using proc = Bun.spawn({ + cmd: [ + bunExe(), + "-e", + ` + const samples = []; + for (let i = 0; i < 50; i++) { + const t0 = process.hrtime.bigint(); + await new Promise(r => setTimeout(r, 1)); + samples.push(Number(process.hrtime.bigint() - t0) / 1e6); + } + samples.sort((a, b) => a - b); + const median = samples[samples.length >> 1]; + process.stdout.write(JSON.stringify({ median, min: samples[0] })); + `, + ], + env: bunEnv, + stdout: "pipe", + stderr: "pipe", + }); + const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]); + const filteredStderr = stderr + .split("\n") + .filter(l => l && !l.startsWith("WARNING: ASAN interferes")) + .join("\n"); + expect(filteredStderr).toBe(""); + const { median, min } = JSON.parse(stdout); + // Before: median ~15.6ms. After: median ~1-2ms. 8ms splits the two with + // plenty of headroom for CI jitter. Also assert we never fire early. + expect(median).toBeLessThan(8); + expect(min).toBeGreaterThanOrEqual(1); + expect(exitCode).toBe(0); +}); + it("timer heap clock is monotonic, not wall-clock", () => { // The clock that schedules setTimeout/setInterval deadlines must be monotonic // (boot-relative) on every platform so NTP steps / user clock changes can't