From ee766fda6847aa449557885ad82b0da86ac1c799 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Wed, 1 Feb 2012 05:27:42 +0000 Subject: [PATCH] * fhandler.cc (fhandler_base_overlapped::has_ongoing_io): Don't block GetOverlappedResult since previous IsEventSignalled will have reset the handle. * select.cc (cygwin_select): Remove space before parentheses in syscall debugging output. (pipe_data_available): Streamline if block. --- winsup/cygwin/ChangeLog | 9 +++++ winsup/cygwin/fhandler.cc | 2 +- winsup/cygwin/select.cc | 83 +++++++++++++++++---------------------- 3 files changed, 46 insertions(+), 48 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 3b2e1c7f0..53f9491c6 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,12 @@ +2012-02-01 Christopher Faylor + + * fhandler.cc (fhandler_base_overlapped::has_ongoing_io): Don't block + GetOverlappedResult since previous IsEventSignalled will have reset the + handle. + * select.cc (cygwin_select): Remove space before parentheses in syscall + debugging output. + (pipe_data_available): Streamline if block. + 2012-01-31 Christopher Faylor * syscalls.cc (dup3): Fix debug typo. diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 0997c9abb..ef25a07b8 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1900,7 +1900,7 @@ fhandler_base_overlapped::has_ongoing_io () return true; io_pending = false; DWORD nbytes; - GetOverlappedResult (get_output_handle (), get_overlapped (), &nbytes, true); + GetOverlappedResult (get_output_handle (), get_overlapped (), &nbytes, false); return false; } diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc index ff63b1e5e..316073e00 100644 --- a/winsup/cygwin/select.cc +++ b/winsup/cygwin/select.cc @@ -164,7 +164,7 @@ cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, res = (res > 0) ? 0 : sel.poll (readfds, writefds, exceptfds); } - syscall_printf ("%R = select (%d, %p, %p, %p, %p)", res, maxfds, readfds, + syscall_printf ("%R = select(%d, %p, %p, %p, %p)", res, maxfds, readfds, writefds, exceptfds, to); return res; } @@ -490,54 +490,43 @@ pipe_data_available (int fd, fhandler_base *fh, HANDLE h, bool writing) IO_STATUS_BLOCK iosb = {0}; FILE_PIPE_LOCAL_INFORMATION fpli = {0}; - bool res = false; - if (!fh->has_ongoing_io ()) + bool res; + if (fh->has_ongoing_io ()) + res = false; + else if (NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli), + FilePipeLocalInformation)) { - if (NtQueryInformationFile (h, - &iosb, - &fpli, - sizeof (fpli), - FilePipeLocalInformation)) - { - /* If NtQueryInformationFile fails, optimistically assume the - pipe is writable. This could happen if we somehow - inherit a pipe that doesn't permit FILE_READ_ATTRIBUTES - access on the write end. */ - select_printf ("fd %d, %s, NtQueryInformationFile failed", - fd, fh->get_name ()); - res = writing ? true : -1; - } - else if (!writing) - { - res = !!fpli.ReadDataAvailable; - paranoid_printf ("fd %d, %s, read avail %u", fd, fh->get_name (), fpli.ReadDataAvailable); - } - else - { - /* If there is anything available in the pipe buffer then signal - that. This means that a pipe could still block since you could - be trying to write more to the pipe than is available in the - buffer but that is the hazard of select(). */ - if ((fpli.WriteQuotaAvailable = (fpli.OutboundQuota - fpli.ReadDataAvailable))) - { - paranoid_printf ("fd %d, %s, write: size %lu, avail %lu", fd, - fh->get_name (), fpli.OutboundQuota, - fpli.WriteQuotaAvailable); - res = true; - } - /* If we somehow inherit a tiny pipe (size < PIPE_BUF), then consider - the pipe writable only if it is completely empty, to minimize the - probability that a subsequent write will block. */ - else if (fpli.OutboundQuota < PIPE_BUF && - fpli.WriteQuotaAvailable == fpli.OutboundQuota) - { - select_printf ("fd, %s, write tiny pipe: size %lu, avail %lu", - fd, fh->get_name (), fpli.OutboundQuota, - fpli.WriteQuotaAvailable); - res = true; - } - } + /* If NtQueryInformationFile fails, optimistically assume the + pipe is writable. This could happen if we somehow + inherit a pipe that doesn't permit FILE_READ_ATTRIBUTES + access on the write end. */ + select_printf ("fd %d, %s, NtQueryInformationFile failed", + fd, fh->get_name ()); + res = writing ? true : -1; } + else if (!writing) + { + paranoid_printf ("fd %d, %s, read avail %u", fd, fh->get_name (), + fpli.ReadDataAvailable); + res = !!fpli.ReadDataAvailable; + } + else if ((res = (fpli.WriteQuotaAvailable = (fpli.OutboundQuota - + fpli.ReadDataAvailable)))) + /* If there is anything available in the pipe buffer then signal + that. This means that a pipe could still block since you could + be trying to write more to the pipe than is available in the + buffer but that is the hazard of select(). */ + paranoid_printf ("fd %d, %s, write: size %lu, avail %lu", fd, + fh->get_name (), fpli.OutboundQuota, + fpli.WriteQuotaAvailable); + else if ((res = (fpli.OutboundQuota < PIPE_BUF && + fpli.WriteQuotaAvailable == fpli.OutboundQuota))) + /* If we somehow inherit a tiny pipe (size < PIPE_BUF), then consider + the pipe writable only if it is completely empty, to minimize the + probability that a subsequent write will block. */ + select_printf ("fd, %s, write tiny pipe: size %lu, avail %lu", + fd, fh->get_name (), fpli.OutboundQuota, + fpli.WriteQuotaAvailable); return res ?: -!!(fpli.NamedPipeState & FILE_PIPE_CLOSING_STATE); }