Browse Source

fix(subprocess): defer native wait allocation

pku-xht 3 weeks ago
parent
commit
ae77bc0b2f

+ 1 - 1
packages/subprocess/subprocess-local/src/runner-launch.ts

@@ -17,7 +17,6 @@ import type { RunnerEvent, RunnerFiles, RunnerRequest } from './runner-protocol.
 import { DirectResultUnavailableError } from './managed-owner.ts'
 import { childEnv } from './spawn.ts'
 
-const handshakeWait = new Int32Array(new SharedArrayBuffer(4))
 const RUNNER_HANDSHAKE_TIMEOUT_MS = 10_000
 const RUNNER_EVENT_POLL_MS = 100
 const PACKAGED_RUNNER_ARG = '--dsh-internal-subprocess-runner'
@@ -99,6 +98,7 @@ function runnerExited(child: ChildProcess, pid: number): boolean {
 
 /** Wait synchronously only until the runner reports target start or spawn failure. */
 function waitForRunnerHandshake(child: ChildProcess, files: RunnerFiles): RunnerHandshake {
+  const handshakeWait = new Int32Array(new SharedArrayBuffer(4))
   const deadline = Date.now() + RUNNER_HANDSHAKE_TIMEOUT_MS
   while (Date.now() < deadline) {
     const events = readRunnerEvents(files.eventsPath)

+ 14 - 0
packages/subprocess/subprocess-local/tests/spawn-runner.spec.ts

@@ -64,6 +64,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')