https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=c5bc7a806521ce8d72f8ffc1c5c4c5efac87606f

commit c5bc7a806521ce8d72f8ffc1c5c4c5efac87606f
Author: Ken Brown <[email protected]>
Date:   Sun Apr 14 19:16:02 2019 +0000

    Cygwin: FIFO: use a retry loop when opening a writer
    
    There may be short periods when there's no pipe instance available.
    Keep trying.

Diff:
---
 winsup/cygwin/fhandler_fifo.cc | 52 +++++++++++++++++++++++++-----------------
 1 file changed, 31 insertions(+), 21 deletions(-)

diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc
index 479021e..d4d2b38 100644
--- a/winsup/cygwin/fhandler_fifo.cc
+++ b/winsup/cygwin/fhandler_fifo.cc
@@ -30,6 +30,12 @@ STATUS_PIPE_EMPTY simply means there's no data to be read. */
                   || _s == STATUS_PIPE_BROKEN \
                   || _s == STATUS_PIPE_EMPTY; })
 
+#define STATUS_PIPE_NO_INSTANCE_AVAILABLE(status)      \
+               ({ NTSTATUS _s = (status); \
+                  _s == STATUS_INSTANCE_NOT_AVAILABLE \
+                  || _s == STATUS_PIPE_NOT_AVAILABLE \
+                  || _s == STATUS_PIPE_BUSY; })
+
 fhandler_fifo::fhandler_fifo ():
   fhandler_base (), read_ready (NULL), write_ready (NULL),
   listen_client_thr (NULL), lct_termination_evt (NULL), nhandlers (0),
@@ -543,28 +549,32 @@ fhandler_fifo::open (int flags, mode_t)
      listen_client thread is running.  Then signal write_ready.  */
   if (writer)
     {
-      if (!wait (read_ready))
-       {
-         res = error_errno_set;
-         goto out;
-       }
-      NTSTATUS status = open_pipe ();
-      if (!NT_SUCCESS (status))
-       {
-         debug_printf ("create of writer failed");
-         __seterrno_from_nt_status (status);
-         res = error_errno_set;
-         goto out;
-       }
-      else if (!arm (write_ready))
+      while (1)
        {
-         res = error_set_errno;
-         goto out;
-       }
-      else
-       {
-         set_pipe_non_blocking (get_handle (), true);
-         res = success;
+         if (!wait (read_ready))
+           {
+             res = error_errno_set;
+             goto out;
+           }
+         NTSTATUS status = open_pipe ();
+         if (NT_SUCCESS (status))
+           {
+             set_pipe_non_blocking (get_handle (), true);
+             if (!arm (write_ready))
+               res = error_set_errno;
+             else
+               res = success;
+             goto out;
+           }
+         else if (STATUS_PIPE_NO_INSTANCE_AVAILABLE (status))
+           Sleep (1);
+         else
+           {
+             debug_printf ("create of writer failed");
+             __seterrno_from_nt_status (status);
+             res = error_errno_set;
+             goto out;
+           }
        }
     }
 out:

Reply via email to