cygrunsrv + sshd + rsync = 20 times too slow -- throttled?
Ken Brown
kbrown@cornell.edu
Wed Sep 15 11:41:40 GMT 2021
On 9/15/2021 7:13 AM, Corinna Vinschen wrote:
> 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;
Maybe we want to call NtQueryInformationFile in all cases except FH_PIPER,
keeping in mind that there are callers of pipe_data_available other than pipes.
That way we can still test for FILE_PIPE_CLOSING_STATE at the end in many cases.
Ken
More information about the Cygwin-developers
mailing list