fix(subprocess): defer native handshake allocation

This commit is contained in:
pku-xht committed 2026-08-21 23:03:59 +08:00
1 parent 4997fb7706
commit fa8b83816e
2 files changed
+16 -1

No files matched your search

@@ -16,7 +16,7 @@ import {
import type { RunnerEvent, RunnerFiles, RunnerRequest } from './runner-protocol.ts'
import { childEnv } from './spawn.ts'
const handshakeWait = new Int32Array(new SharedArrayBuffer(4))
let handshakeWait: Int32Array | undefined
const RUNNER_HANDSHAKE_TIMEOUT_MS = 10_000
const RUNNER_EVENT_POLL_MS = 100
const PACKAGED_RUNNER_ARG = '--dsh-internal-subprocess-runner'
@@ -102,6 +102,7 @@ function waitForRunnerHandshake(child: ChildProcess, files: RunnerFiles): Runner
if (terminal?.type === 'spawn-error' || terminal?.type === 'runner-error') return { pid: -1, events }
if (child.pid === undefined) throw new Error('native subprocess runner failed to start')
if (runnerExited(child, child.pid)) throw new Error('native subprocess runner exited before reporting target start')
handshakeWait ??= new Int32Array(new SharedArrayBuffer(4))
Atomics.wait(handshakeWait, 0, 0, 5)
}
throw new Error(`native subprocess runner did not report target start within ${String(RUNNER_HANDSHAKE_TIMEOUT_MS)}ms`)
@@ -63,6 +63,20 @@ describe('spawn runner transport', () => {
expect(spawnRunnerInvocation()).toEqual(sourceInvocation)
})
it('does not require SharedArrayBuffer until a native handshake runs', async () => {
const descriptor = Object.getOwnPropertyDescriptor(globalThis, 'SharedArrayBuffer')
Object.defineProperty(globalThis, 'SharedArrayBuffer', { configurable: true, value: undefined })
vi.resetModules()
try {
const isolated = await import('../src/runner-launch.ts')
expect(isolated.runnerStdio(spec())).toEqual(['ignore', 'pipe', 'pipe'])
} finally {
if (descriptor === undefined) Reflect.deleteProperty(globalThis, 'SharedArrayBuffer')
else Object.defineProperty(globalThis, 'SharedArrayBuffer', descriptor)
vi.resetModules()
}
})
it('re-enters a packaged executable through its private runner dispatch', () => {
const packagedProcess = process as NodeJS.Process & { pkg?: unknown }
const original = Object.getOwnPropertyDescriptor(packagedProcess, 'pkg')