Просмотр исходного кода

fix(subprocess): close runner pipe handles

pku-xht 1 месяц назад
Родитель
Сommit
43b093a502
1 измененных файлов с 13 добавлено и 5 удалено
  1. 13 5
      packages/subprocess/subprocess-local/src/spawn-runner.ts

+ 13 - 5
packages/subprocess/subprocess-local/src/spawn-runner.ts

@@ -97,17 +97,20 @@ function replaceEnvironment(env: Record<string, string>): void {
   Object.assign(process.env, env)
 }
 
+interface MaterializedStdioStream {
+  readonly _handle?: { close(): void } | null
+}
+
+function closeMaterializedStdio(stream: NodeJS.WriteStream): void {
+  (stream as unknown as MaterializedStdioStream)._handle?.close()
+}
+
 /** Release the runner's copies after the Windows target inherits its standard handles. */
 function releaseRunnerStdio(): void {
   const stdin = process.stdin
   const stdout = process.stdout
   const stderr = process.stderr
-  // A loader may already have materialized Node's libuv stdio wrappers. Their
-  // shutdown must be requested before the CRT descriptors close; the target
-  // keeps the handles CreateProcessW inherited and remains the only pipe writer.
   stdin.destroy()
-  stdout.end()
-  stderr.end()
   for (const fd of [0, 1, 2]) {
     try {
       closeSync(fd)
@@ -115,6 +118,11 @@ function releaseRunnerStdio(): void {
       if ((error as NodeJS.ErrnoException).code !== 'EBADF') throw error
     }
   }
+  // Node deliberately keeps stdout/stderr alive when destroy() is called. A
+  // loader may already have materialized their libuv handles, so close those
+  // runner-owned references explicitly; the target keeps its inherited copies.
+  closeMaterializedStdio(stdout)
+  closeMaterializedStdio(stderr)
 }
 
 async function runWin32(request: RunnerRequest, eventsPath: string): Promise<void> {