cygrunsrv + sshd + rsync = 20 times too slow -- throttled?
Corinna Vinschen
corinna-cygwin@cygwin.com
Wed Sep 15 11:13:25 GMT 2021
On Sep 15 19:48, Takashi Yano wrote:
> On Wed, 15 Sep 2021 11:57:44 +0200
> Corinna Vinschen wrote:
> > ...but we're unconditionally using NtQueryInformationFile at the start
> > of pipe_data_available. If this is the read side of the pipe, isn't
> > there a chance that another (non-Cygwin) process is performing a blocking
> > read and this call will hang?
>
> I will check that.
Something like that comes to mind:
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index fd23122988c3..cf9ad87538f2 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -594,18 +594,6 @@ pipe_data_available (int fd, fhandler_base *fh, HANDLE h, bool writing)
if (fh->has_ongoing_io ())
return 0;
- status = NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
- FilePipeLocalInformation);
- if (!NT_SUCCESS (status))
- {
- /* 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, status %y",
- fd, fh->get_name (), status);
- return writing ? 1 : -1;
- }
if (writing)
{
/* If there is anything available in the pipe buffer then signal
@@ -633,6 +621,18 @@ pipe_data_available (int fd, fhandler_base *fh, HANDLE h, bool writing)
/* Note: Do not use NtQueryInformationFile() for query_hdl because
NtQueryInformationFile() seems to interfere with reading pipes
in non-cygwin apps. Instead, use PeekNamedPipe() here. */
+ status = NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
+ FilePipeLocalInformation);
+ if (!NT_SUCCESS (status))
+ {
+ /* 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, status %y",
+ fd, fh->get_name (), status);
+ return 1;
+ }
if (fh->get_device () == FH_PIPEW && fpli.WriteQuotaAvailable == 0)
{
HANDLE query_hdl = ((fhandler_pipe *) fh)->get_query_handle ();
@@ -652,11 +652,15 @@ pipe_data_available (int fd, fhandler_base *fh, HANDLE h, bool writing)
}
/* TODO: Buffer really full or non-Cygwin reader? */
}
- else if (fpli.ReadDataAvailable)
+ else
{
- paranoid_printf ("fd %d, %s, read avail %u", fd, fh->get_name (),
- fpli.ReadDataAvailable);
- return 1;
+ DWORD nbytes_in_pipe;
+ if (PeekNamedPipe (h, NULL, 0, NULL, &nbytes_in_pipe, NULL))
+ {
+ paranoid_printf ("fd %d, %s, read avail %u", fd, fh->get_name (),
+ nbytes_in_pipe);
+ return nbytes_in_pipe > 0;
+ }
}
if (fpli.NamedPipeState & FILE_PIPE_CLOSING_STATE)
return -1;
Corinna
More information about the Cygwin-developers
mailing list