From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2210) id 17A243857C58; Thu, 16 Jul 2020 20:00:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 17A243857C58 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Ken Brown To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin] Cygwin: FIFO: allow take_ownership to be interrupted X-Act-Checkin: newlib-cygwin X-Git-Author: Ken Brown X-Git-Refname: refs/heads/master X-Git-Oldrev: a4dc0eb15c534396b199b6aa350475b62bae32d5 X-Git-Newrev: 4eaa55463d97596310c1793fb877502dabec397c Message-Id: <20200716200056.17A243857C58@sourceware.org> Date: Thu, 16 Jul 2020 20:00:56 +0000 (GMT) X-BeenThere: cygwin-cvs@cygwin.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Cygwin core component git logs List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 16 Jul 2020 20:00:56 -0000 https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=4eaa55463d97596310c1793fb877502dabec397c commit 4eaa55463d97596310c1793fb877502dabec397c Author: Ken Brown Date: Mon Jul 13 07:01:57 2020 -0400 Cygwin: FIFO: allow take_ownership to be interrupted 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. Diff: --- 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++)