cygrunsrv + sshd + rsync = 20 times too slow -- throttled?

Ken Brown kbrown@cornell.edu
Sat Sep 11 02:17:21 GMT 2021


On 9/10/2021 6:57 PM, Takashi Yano wrote:
> On Fri, 10 Sep 2021 11:17:58 -0400
> Ken Brown wrote:
>> I've rerun your test with the latest version, and the test results are similar.
>>    I've also run a suite of fifo tests that I've accumulated, and they all pass
>> also, so I pushed your patch.
>>
>> I think we're in pretty good shape now.  The only detail remaining, AFAIK, is
>> how to best avoid a deadlock if the pipe has been created by a non-Cygwin
>> process.  I've proposed a timeout, but maybe there's a better idea.
> 
> I am not pretty sure what is the problem, but is not the following
> patch enough?
> 
> diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
> index d309be2f7..13fba9a14 100644
> --- a/winsup/cygwin/fhandler.h
> +++ b/winsup/cygwin/fhandler.h
> @@ -1205,6 +1205,7 @@ public:
>     select_record *select_except (select_stuff *);
>     char *get_proc_fd_name (char *buf);
>     int open (int flags, mode_t mode = 0);
> +  void open_setup (int flags);
>     void fixup_after_fork (HANDLE);
>     int dup (fhandler_base *child, int);
>     int close ();
> diff --git a/winsup/cygwin/fhandler_pipe.cc b/winsup/cygwin/fhandler_pipe.cc
> index 6994a5dce..d84e6ad84 100644
> --- a/winsup/cygwin/fhandler_pipe.cc
> +++ b/winsup/cygwin/fhandler_pipe.cc
> @@ -191,6 +191,17 @@ out:
>     return 0;
>   }
> 
> +void
> +fhandler_pipe::open_setup (int flags)
> +{
> +  fhandler_base::open_setup (flags);
> +  if (get_dev () == FH_PIPER && !read_mtx)
> +    {
> +      SECURITY_ATTRIBUTES *sa = sec_none_cloexec (flags);
> +      read_mtx = CreateMutexW (sa, FALSE, NULL);
> +    }
> +}
> +
>   off_t
>   fhandler_pipe::lseek (off_t offset, int whence)
>   {
> 
> 
> AFAIK, another problem remaining is:
> 
> On Mon, 6 Sep 2021 14:49:55 +0200
> Corinna Vinschen wrote:
>> - What about calling select for writing on pipes read by non-Cygwin
>>    processes?  In that case, we still can't rely on WriteQuotaAvailable,
>>    just as before.

This is the problem I was talking about.  In this case the non-Cygwin process 
might have a large pending read, so that the Cygwin process calling select on 
the write side will see WriteQuotaAvailable == 0.  This could lead to a deadlock 
with the Cygwin process waiting for write ready while the non-Cygwin process is 
blocked trying to read.

My suggestion is that we impose a timeout in this situation, after which select 
reports write ready.

Ken


More information about the Cygwin-developers mailing list