When a reader takes ownership in fifo_reader_thread, it now goes
directly to the part of the main loop that listens for a connection.
Previously it went back to the beginning of the loop.

Also, if the reader has to delay taking ownership because the previous
owner has not finished updating the shared fifo_client handlers, it
now checks to see if cancel_evt has been set.  Previously it might
have had to spin its wheels unnecessarily only to eventually find that
its thread had been canceled.
---
 winsup/cygwin/fhandler_fifo.cc | 44 ++++++++++++++++++----------------
 1 file changed, 23 insertions(+), 21 deletions(-)

diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc
index afe21a468..1fb319fcf 100644
--- a/winsup/cygwin/fhandler_fifo.cc
+++ b/winsup/cygwin/fhandler_fifo.cc
@@ -462,12 +462,30 @@ fhandler_fifo::fifo_reader_thread_func ()
        take_ownership = true;
       else if (cur_owner != me)
        idle = true;
-      if (take_ownership)
+      else
+       /* I'm the owner. */
+       goto owner_listen;
+      if (idle)
+       {
+         owner_unlock ();
+         HANDLE w[2] = { owner_needed_evt, cancel_evt };
+         switch (WaitForMultipleObjects (2, w, false, INFINITE))
+           {
+           case WAIT_OBJECT_0:
+             continue;
+           case WAIT_OBJECT_0 + 1:
+             goto canceled;
+           default:
+             api_fatal ("WFMO failed, %E");
+           }
+       }
+      else if (take_ownership)
        {
          if (!shared_fc_handler_updated ())
            {
              owner_unlock ();
-             yield ();
+             if (IsEventSignalled (cancel_evt))
+               goto canceled;
              continue;
            }
          else
@@ -478,26 +496,11 @@ fhandler_fifo::fifo_reader_thread_func ()
                api_fatal ("Can't update my handlers, %E");
              owner_found ();
              owner_unlock ();
-             continue;
+             /* Fall through to owner_listen. */
            }
        }
-      else if (idle)
-       {
-         owner_unlock ();
-         HANDLE w[2] = { owner_needed_evt, cancel_evt };
-         switch (WaitForMultipleObjects (2, w, false, INFINITE))
-           {
-           case WAIT_OBJECT_0:
-             continue;
-           case WAIT_OBJECT_0 + 1:
-             goto canceled;
-           default:
-             api_fatal ("WFMO failed, %E");
-           }
-       }
-      else
-       {
-         /* I'm the owner */
+
+owner_listen:
          fifo_client_lock ();
          cleanup_handlers ();
          if (add_client_handler () < 0)
@@ -590,7 +593,6 @@ fhandler_fifo::fifo_reader_thread_func ()
          fifo_client_unlock ();
          if (cancel)
            goto canceled;
-       }
     }
 canceled:
   if (conn_evt)
-- 
2.27.0

Reply via email to