bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: execute, spawn-pipe: Make multithread-safe on native Windows


From: Bruno Haible
Subject: Re: execute, spawn-pipe: Make multithread-safe on native Windows
Date: Sun, 13 Dec 2020 21:46:45 +0100
User-agent: KMail/5.1.3 (Linux/4.4.0-193-generic; KDE/5.18.0; x86_64; ; )

> 2020-11-30  Bruno Haible  <bruno@clisp.org>
> 
>       execute, spawn-pipe: Make multithread-safe on native Windows.

Oops, there was a mistake in this change: it caused two tests
(test-pipe-filter-ii1.sh, test-pipe-filter-gi1.sh) to hang. The hang is
a symptom that there is one extra handle left open to a pipe. (The OS
knows that a pipe is done when there is no reader or no writer any more.)
This patch fixes it.


2020-12-13  Bruno Haible  <bruno@clisp.org>

        spawn-pipe: Fix hanging processes on Windows (regression 2020-11-30).
        * lib/spawn-pipe.c (create_pipe): After spawning the subprocess, close
        the stdin_handle and/or stdout_handle.

diff --git a/lib/spawn-pipe.c b/lib/spawn-pipe.c
index ba07d20..bd34959 100644
--- a/lib/spawn-pipe.c
+++ b/lib/spawn-pipe.c
@@ -222,6 +222,8 @@ create_pipe (const char *progname,
   bool must_close_ofd0 = pipe_stdin;
 
   /* Create standard file handles of child process.  */
+  HANDLE stdin_handle = INVALID_HANDLE_VALUE;
+  HANDLE stdout_handle = INVALID_HANDLE_VALUE;
   nulloutfd = -1;
   stdinfd = -1;
   stdoutfd = -1;
@@ -243,7 +245,7 @@ create_pipe (const char *progname,
        to pass NULL, the child process would inherit a copy of the environment
        block - ignoring the effects of putenv() and [un]setenv().  */
     {
-      HANDLE stdin_handle =
+      stdin_handle =
         (HANDLE) _get_osfhandle (pipe_stdin ? ofd[0] :
                                  prog_stdin == NULL ? STDIN_FILENO : stdinfd);
       if (pipe_stdin)
@@ -261,7 +263,7 @@ create_pipe (const char *progname,
           close (ofd[0]); /* implies CloseHandle (stdin_handle); */
           stdin_handle = duplicate;
         }
-      HANDLE stdout_handle =
+      stdout_handle =
         (HANDLE) _get_osfhandle (pipe_stdout ? ifd[1] :
                                  prog_stdout == NULL ? STDOUT_FILENO : 
stdoutfd);
       if (pipe_stdout)
@@ -306,10 +308,22 @@ create_pipe (const char *progname,
   if (nulloutfd >= 0)
     close (nulloutfd);
 
-  if (must_close_ofd0)
-    close (ofd[0]);
-  if (must_close_ifd1)
-    close (ifd[1]);
+  if (pipe_stdin)
+    {
+      if (must_close_ofd0)
+        close (ofd[0]);
+      else
+        if (stdin_handle != INVALID_HANDLE_VALUE)
+          CloseHandle (stdin_handle);
+    }
+  if (pipe_stdout)
+    {
+      if (must_close_ifd1)
+        close (ifd[1]);
+      else
+        if (stdout_handle != INVALID_HANDLE_VALUE)
+          CloseHandle (stdout_handle);
+    }
 
 # else /* __KLIBC__ */
   if (!(directory == NULL && strcmp (directory, ".") == 0))




reply via email to

[Prev in Thread] Current Thread [Next in Thread]