public inbox for cygwin-patches@cygwin.com
 help / color / mirror / Atom feed
From: Ken Brown <kbrown@cornell.edu>
To: cygwin-patches@cygwin.com
Subject: [PATCH 10/12] Cygwin: FIFO: allow take_ownership to be interrupted
Date: Thu, 16 Jul 2020 12:19:13 -0400	[thread overview]
Message-ID: <20200716161915.16994-11-kbrown@cornell.edu> (raw)
In-Reply-To: <20200716161915.16994-1-kbrown@cornell.edu>

Use cygwait in take_ownership to allow interruption while waiting to
become owner.  Return the cygwait return value or a suitable value to
indicate an error.

raw_read now checks the return value and acts accordingly.
---
 winsup/cygwin/fhandler.h       |  2 +-
 winsup/cygwin/fhandler_fifo.cc | 54 ++++++++++++++++++++++++++++++----
 winsup/cygwin/select.cc        | 11 ++++++-
 3 files changed, 59 insertions(+), 8 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 221c856e6..0e0cfbd71 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -1489,7 +1489,7 @@ public:
   void owner_lock () { shmem->owner_lock (); }
   void owner_unlock () { shmem->owner_unlock (); }
 
-  void take_ownership ();
+  DWORD take_ownership ();
   void reading_lock () { shmem->reading_lock (); }
   void reading_unlock () { shmem->reading_unlock (); }
 
diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc
index fd1695f40..30486304f 100644
--- a/winsup/cygwin/fhandler_fifo.cc
+++ b/winsup/cygwin/fhandler_fifo.cc
@@ -1175,15 +1175,16 @@ fhandler_fifo::raw_write (const void *ptr, size_t len)
   return ret;
 }
 
-/* Called from raw_read and select.cc:peek_fifo. */
-void
+/* Called from raw_read and select.cc:peek_fifo.  Return WAIT_OBJECT_0
+   on success.  */
+DWORD
 fhandler_fifo::take_ownership ()
 {
   owner_lock ();
   if (get_owner () == me)
     {
       owner_unlock ();
-      return;
+      return WAIT_OBJECT_0;
     }
   set_pending_owner (me);
   /* Wake up my fifo_reader_thread. */
@@ -1192,8 +1193,19 @@ fhandler_fifo::take_ownership ()
     /* Wake up owner's fifo_reader_thread. */
     SetEvent (update_needed_evt);
   owner_unlock ();
-  /* The reader threads should now do the transfer.  */
-  WaitForSingleObject (owner_found_evt, INFINITE);
+  /* The reader threads should now do the transfer. */
+  DWORD waitret = cygwait (owner_found_evt, cw_cancel | cw_sig_eintr);
+  owner_lock ();
+  if (waitret == WAIT_OBJECT_0
+      && (get_owner () != me || get_pending_owner ()))
+    {
+      /* Something went wrong.  Return WAIT_TIMEOUT, which can't be
+	 returned by the above cygwait call. */
+      set_pending_owner (null_fr_id);
+      waitret = WAIT_TIMEOUT;
+    }
+  owner_unlock ();
+  return waitret;
 }
 
 void __reg3
@@ -1206,7 +1218,37 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len)
     {
       /* No one else can take ownership while we hold the reading_lock. */
       reading_lock ();
-      take_ownership ();
+      switch (take_ownership ())
+	{
+	case WAIT_OBJECT_0:
+	  break;
+	case WAIT_SIGNALED:
+	  if (_my_tls.call_signal_handler ())
+	    {
+	      reading_unlock ();
+	      continue;
+	    }
+	  else
+	    {
+	      set_errno (EINTR);
+	      reading_unlock ();
+	      goto errout;
+	    }
+	  break;
+	case WAIT_CANCELED:
+	  reading_unlock ();
+	  pthread::static_cancel_self ();
+	  break;
+	case WAIT_TIMEOUT:
+	  reading_unlock ();
+	  debug_printf ("take_ownership returned an unexpected result; retry");
+	  continue;
+	default:
+	  reading_unlock ();
+	  debug_printf ("unknown error while trying to take ownership, %E");
+	  goto errout;
+	}
+
       /* Poll the connected clients for input.  Make two passes.  On
 	 the first pass, just try to read from the client from which
 	 we last read successfully.  This should minimize
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index 80d16f2a7..3f3f33fb5 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -867,7 +867,16 @@ peek_fifo (select_record *s, bool from_select)
 	}
 
       fh->reading_lock ();
-      fh->take_ownership ();
+      if (fh->take_ownership () != WAIT_OBJECT_0)
+	{
+	  select_printf ("%s, unable to take ownership", fh->get_name ());
+	  fh->reading_unlock ();
+	  gotone += s->read_ready = true;
+	  if (s->except_selected)
+	    gotone += s->except_ready = true;
+	  goto out;
+	}
+
       fh->fifo_client_lock ();
       int nconnected = 0;
       for (int i = 0; i < fh->get_nhandlers (); i++)
-- 
2.27.0


  parent reply	other threads:[~2020-07-16 16:19 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-16 16:19 [PATCH 00/12] FIFO: fix multiple reader support Ken Brown
2020-07-16 16:19 ` [PATCH 01/12] Cygwin: FIFO: fix problems finding new owner Ken Brown
2020-07-16 16:19 ` [PATCH 02/12] Cygwin: FIFO: keep a writer count in shared memory Ken Brown
2020-07-16 16:19 ` [PATCH 03/12] Cygwin: fhandler_fifo::hit_eof: improve reliability Ken Brown
2020-07-16 16:19 ` [PATCH 04/12] Cygwin: FIFO: reduce I/O interleaving Ken Brown
2020-07-16 16:19 ` [PATCH 05/12] Cygwin: FIFO: improve taking ownership in fifo_reader_thread Ken Brown
2020-07-16 16:19 ` [PATCH 06/12] Cygwin: FIFO: fix indentation Ken Brown
2020-07-16 16:19 ` [PATCH 07/12] Cygwin: FIFO: make certain errors non-fatal Ken Brown
2020-07-16 16:19 ` [PATCH 08/12] Cygwin: FIFO: add missing lock Ken Brown
2020-07-16 16:19 ` [PATCH 09/12] Cygwin: fhandler_fifo::take_ownership: don't set event unnecessarily Ken Brown
2020-07-16 16:19 ` Ken Brown [this message]
2020-07-16 16:19 ` [PATCH 11/12] Cygwin: FIFO: clean up Ken Brown
2020-07-16 16:19 ` [PATCH 12/12] Cygwin: FIFO: update commentary Ken Brown
2020-07-16 19:57 ` [PATCH 00/12] FIFO: fix multiple reader support Corinna Vinschen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200716161915.16994-11-kbrown@cornell.edu \
    --to=kbrown@cornell.edu \
    --cc=cygwin-patches@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).