public inbox for cygwin-cvs@sourceware.org help / color / mirror / Atom feed
From: Ken Brown <kbrown@sourceware.org> To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin/cygwin-3_3-branch] Cygwin: fhandler_fifo::raw_read: handle STATUS_PENDING Date: Wed, 24 Nov 2021 14:03:31 +0000 (GMT) [thread overview] Message-ID: <20211124140331.C1C92385803A@sourceware.org> (raw) https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=da32bafaac2d6d7f1fd49df97a828e20ac77b978 commit da32bafaac2d6d7f1fd49df97a828e20ac77b978 Author: Ken Brown <kbrown@cornell.edu> Date: Tue Nov 23 11:40:56 2021 -0500 Cygwin: fhandler_fifo::raw_read: handle STATUS_PENDING NtReadFile can return STATUS_PENDING occasionally even in non-blocking mode. Check for this and wait for NtReadFile to complete. To avoid code repetition, do this in a static helper function nt_read. Diff: --- winsup/cygwin/fhandler_fifo.cc | 70 ++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 489ba528c..34bd835ae 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -1201,12 +1201,39 @@ fhandler_fifo::release_select_sem (const char *from) ReleaseSemaphore (select_sem, n_release, NULL); } +/* Read from a non-blocking pipe and wait for completion. */ +static NTSTATUS +nt_read (HANDLE h, HANDLE evt, PIO_STATUS_BLOCK pio, void *in_ptr, size_t& len) +{ + NTSTATUS status; + + ResetEvent (evt); + status = NtReadFile (h, evt, NULL, NULL, pio, in_ptr, len, NULL, NULL); + if (status == STATUS_PENDING) + { + /* Very short-lived */ + status = NtWaitForSingleObject (evt, FALSE, NULL); + if (NT_SUCCESS (status)) + status = pio->Status; + } + return status; +} + void __reg3 fhandler_fifo::raw_read (void *in_ptr, size_t& len) { + HANDLE evt; + if (!len) return; + if (!(evt = CreateEvent (NULL, false, false, NULL))) + { + __seterrno (); + len = (size_t) -1; + return; + } + while (1) { int nconnected = 0; @@ -1244,17 +1271,15 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) NTSTATUS status; IO_STATUS_BLOCK io; - status = NtReadFile (fc_handler[j].h, NULL, NULL, NULL, - &io, in_ptr, len, NULL, NULL); + status = nt_read (fc_handler[j].h, evt, &io, in_ptr, len); switch (status) { case STATUS_SUCCESS: case STATUS_BUFFER_OVERFLOW: - /* io.Information is supposedly valid in latter case. */ if (io.Information > 0) { len = io.Information; - goto out; + goto unlock_out; } break; case STATUS_PIPE_EMPTY: @@ -1265,7 +1290,7 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) fc_handler[j].set_state (fc_disconnected); break; default: - debug_printf ("NtReadFile status %y", status); + debug_printf ("nt_read status %y", status); fc_handler[j].set_state (fc_error); break; } @@ -1278,8 +1303,7 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) NTSTATUS status; IO_STATUS_BLOCK io; - status = NtReadFile (fc_handler[i].h, NULL, NULL, NULL, - &io, in_ptr, len, NULL, NULL); + status = nt_read (fc_handler[i].h, evt, &io, in_ptr, len); switch (status) { case STATUS_SUCCESS: @@ -1290,7 +1314,7 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) if (j < nhandlers) fc_handler[j].last_read = false; fc_handler[i].last_read = true; - goto out; + goto unlock_out; } break; case STATUS_PIPE_EMPTY: @@ -1301,7 +1325,7 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) fc_handler[i].set_state (fc_disconnected); break; default: - debug_printf ("NtReadFile status %y", status); + debug_printf ("nt_read status %y", status); fc_handler[i].set_state (fc_error); break; } @@ -1315,8 +1339,7 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) IO_STATUS_BLOCK io; nconnected++; - status = NtReadFile (fc_handler[i].h, NULL, NULL, NULL, - &io, in_ptr, len, NULL, NULL); + status = nt_read (fc_handler[i].h, evt, &io, in_ptr, len); switch (status) { case STATUS_SUCCESS: @@ -1327,7 +1350,7 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) if (j < nhandlers) fc_handler[j].last_read = false; fc_handler[i].last_read = true; - goto out; + goto unlock_out; } break; case STATUS_PIPE_EMPTY: @@ -1337,25 +1360,25 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) nconnected--; break; default: - debug_printf ("NtReadFile status %y", status); + debug_printf ("nt_read status %y", status); fc_handler[i].set_state (fc_error); nconnected--; break; } } - fifo_client_unlock (); if (!nconnected && hit_eof ()) { - reading_unlock (); len = 0; - return; + goto unlock_out; } + fifo_client_unlock (); maybe_retry: reading_unlock (); if (is_nonblocking ()) { set_errno (EAGAIN); - goto errout; + len = (size_t) -1; + goto out; } else { @@ -1370,7 +1393,8 @@ maybe_retry: else { set_errno (EINTR); - goto errout; + len = (size_t) -1; + goto out; } } } @@ -1378,17 +1402,17 @@ maybe_retry: if (isclosed ()) { set_errno (EBADF); - goto errout; + len = (size_t) -1; + goto out; } } -errout: - len = (size_t) -1; - return; -out: +unlock_out: fifo_client_unlock (); reading_unlock (); +out: if (select_sem) release_select_sem ("raw_read"); + CloseHandle (evt); } int __reg2
reply other threads:[~2021-11-24 14:03 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20211124140331.C1C92385803A@sourceware.org \ --to=kbrown@sourceware.org \ --cc=cygwin-cvs@sourceware.org \ /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: linkBe 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).