* 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.
This commit is contained in:
Christopher Faylor 2012-02-01 05:27:42 +00:00
parent d3cb1dffef
commit ee766fda68
3 changed files with 46 additions and 48 deletions

View File

@ -1,3 +1,12 @@
2012-02-01 Christopher Faylor <me.cygwin2012@cgf.cx>
* 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 <me.cygwin2012@cgf.cx> 2012-01-31 Christopher Faylor <me.cygwin2012@cgf.cx>
* syscalls.cc (dup3): Fix debug typo. * syscalls.cc (dup3): Fix debug typo.

View File

@ -1900,7 +1900,7 @@ fhandler_base_overlapped::has_ongoing_io ()
return true; return true;
io_pending = false; io_pending = false;
DWORD nbytes; DWORD nbytes;
GetOverlappedResult (get_output_handle (), get_overlapped (), &nbytes, true); GetOverlappedResult (get_output_handle (), get_overlapped (), &nbytes, false);
return false; return false;
} }

View File

@ -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); 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); writefds, exceptfds, to);
return res; return res;
} }
@ -490,54 +490,43 @@ pipe_data_available (int fd, fhandler_base *fh, HANDLE h, bool writing)
IO_STATUS_BLOCK iosb = {0}; IO_STATUS_BLOCK iosb = {0};
FILE_PIPE_LOCAL_INFORMATION fpli = {0}; FILE_PIPE_LOCAL_INFORMATION fpli = {0};
bool res = false; bool res;
if (!fh->has_ongoing_io ()) if (fh->has_ongoing_io ())
res = false;
else if (NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
FilePipeLocalInformation))
{ {
if (NtQueryInformationFile (h, /* If NtQueryInformationFile fails, optimistically assume the
&iosb, pipe is writable. This could happen if we somehow
&fpli, inherit a pipe that doesn't permit FILE_READ_ATTRIBUTES
sizeof (fpli), access on the write end. */
FilePipeLocalInformation)) select_printf ("fd %d, %s, NtQueryInformationFile failed",
{ fd, fh->get_name ());
/* If NtQueryInformationFile fails, optimistically assume the res = writing ? true : -1;
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;
}
}
} }
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); return res ?: -!!(fpli.NamedPipeState & FILE_PIPE_CLOSING_STATE);
} }