cygrunsrv + sshd + rsync = 20 times too slow -- throttled?
Takashi Yano
takashi.yano@nifty.ne.jp
Sat Sep 4 12:37:13 GMT 2021
On Sat, 4 Sep 2021 21:02:58 +0900
Takashi Yano wrote:
> Hi Corinna, Ken,
>
> On Fri, 3 Sep 2021 09:27:37 -0400
> Ken Brown wrote:
> > On 9/3/2021 8:22 AM, Takashi Yano wrote:
> > > POSIX says:
> > > The value returned may be less than nbyte if the number of bytes left
> > > in the file is less than nbyte, if the read() request was interrupted
> > > by a signal, or if the file is a pipe or FIFO or special file and has
> > > ~~~
> > > fewer than nbyte bytes immediately available for reading.
> > > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > >
> > > https://pubs.opengroup.org/onlinepubs/009604599/functions/read.html
> > >
> > > If it is turned over, read() should read all data immediately available,
> > > I think.
> >
> > I understand the reasoning now, but I think your patch isn't quite right. As it
> > stands, if the call to NtQueryInformationFile fails but total_length != 0,
> > you're trying to read again without knowing that there's data in the pipe.
> >
> > Also, I think you need the following:
> >
> > diff --git a/winsup/cygwin/fhandler_pipe.cc b/winsup/cygwin/fhandler_pipe.cc
> > index ef7823ae5..46bb96961 100644
> > --- a/winsup/cygwin/fhandler_pipe.cc
> > +++ b/winsup/cygwin/fhandler_pipe.cc
> > @@ -348,8 +348,13 @@ fhandler_pipe::raw_read (void *ptr, size_t& len)
> > CloseHandle (evt);
> > if (status == STATUS_THREAD_SIGNALED)
> > {
> > - set_errno (EINTR);
> > - len = (size_t) -1;
> > + if (total_len == 0)
> > + {
> > + set_errno (EINTR);
> > + len = (size_t) -1;
> > + }
> > + else
> > + len = total_len;
> > }
> > else if (status == STATUS_THREAD_CANCELED)
> > pthread::static_cancel_self ();
>
> Thanks for your advice. I fixed the issue and attached new patch.
>
> On Fri, 3 Sep 2021 17:37:13 +0200
> Corinna Vinschen wrote:
> > Hmm, I see the point, but we might have another problem with that.
> >
> > We can't keep the mutex while waiting on the pending read, and there
> > could be more than one pending read running at the time. if so,
> > chances are extremly high, that the data written to the buffer gets
> > split like this:
> >
> > reader 1 reader 2
> >
> > calls read(65536) calls read(65536)
> >
> > calls NtReadFile(16384 bytes)
> > calls NtReadFile(16384 bytes)
> >
> > writer writes 65536 bytes
> >
> > wakes up and gets 16384 bytes
> > wakes up and gets 16384 bytes
> > gets the mutex, calls
> > NtReadFile(32768) which
> > returns immediately with
> > 32768 bytes added to the
> > caller's buffer.
> >
> > so the buffer returned to reader 1 is 49152 bytes, with 16384 bytes
> > missing in the middle of it, *without* the reader knowing about that
> > fact. If reader 1 gets the first 16384 bytes, the 16384 bytes have
> > been read in a single call, at least, so the byte order is not
> > unknowingly broken on the application level.
> >
> > Does that make sense?
>
> Why can't we keep the mutex while waiting on the pending read?
> If we can keep the mutex, the issue above mentioned does not
> happen, right?
>
> What about the patch attached? This keeps the mutex while read()
> but I do not see any defects so far.
Sorry, I forgot to attach the patch.
--
Takashi Yano <takashi.yano@nifty.ne.jp>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pipe-corinna4-fix.patch
Type: application/octet-stream
Size: 3540 bytes
Desc: not available
URL: <https://cygwin.com/pipermail/cygwin-developers/attachments/20210904/e154a6ed/attachment.obj>
More information about the Cygwin-developers
mailing list