cygrunsrv + sshd + rsync = 20 times too slow -- throttled?
Ken Brown
kbrown@cornell.edu
Mon Sep 20 21:21:12 GMT 2021
On 9/20/2021 5:09 PM, Ken Brown wrote:
> On 9/20/2021 3:14 PM, Ken Brown wrote:
>> Hi Takashi,
>>
>> On 9/20/2021 8:52 AM, Takashi Yano wrote:
>>> On Mon, 13 Sep 2021 11:07:42 +0200
>>> Corinna Vinschen wrote:
>>>> On Sep 11 11:35, Takashi Yano wrote:
>>>>> Keeping read handle in write pipe (Corinna's query_hdl) causes problem
>>>>> that write side cannot detect close on read side.
>>>>> Is it possible to open read handle temporally when pipe_data_available()
>>>>> is called?
>>>>
>>>> 1. You would have to know which process keeps the other side of the pipe.
>>>> 2. You would have to have the permission to open the other process to
>>>> duplicate the pipe into your own process
>>>> 3. You would have to know the HANDLE value of the read side of your pipe
>>>> in that other process.
>>>>
>>>> Point 1 is (kind of) doable using GetNamedPipeClientProcessId or
>>>> GetNamedPipeServerProcessId. ZIt's not clear how reliable these
>>>> functions are, given that both pipe sides are created by the same
>>>> process and then usually inherited by two child processes communicating
>>>> over that pipe.
>>>>
>>>> Point 2 is most of the time the case, especially when talking with
>>>> native processes.
>>>>
>>>> Point 3 requires some sort of IPC.
>>>>
>>>> Having said that, I think this is too complicated.
>>>
>>> In the current implementation, there is a potential risk that
>>> write side fails to detect the closure of read side if more than
>>> one writers exist and one of them is non-cygwin process.
>>>
>>> Therefore, I had tried to implement the above idea (tentative
>>> query handle). Finally, I could convince myself to some extent,
>>> so I attach a patch for that.
>>>
>>> As for point 1 and 3, I used NtQuerySystemInformation() with
>>> SystemHandleInformation. I also used NtQueryObject() with
>>> ObjectNameInformation in order to know which handle is the
>>> other side of the pipe. As for point 2, it is not possible to
>>> open the process which is running as a service, so the current
>>> query_hdl is used for such process as an exception.
>>>
>>> Ken, WDYT of this implementation?
>>
>> This looks like a great idea! I'll review it in detail later today or tomorrow.
>
> I only saw one thing that doesn't look right to me:
>
>> + /* Check object name */
>> + status = NtQueryObject (h, ObjectNameInformation, ntfn, 65536, &len);
>> + if (!NT_SUCCESS (status))
>> + goto close_handle;
>> + ntfn->Name.Buffer[ntfn->Name.Length / sizeof (WCHAR)] = L'\0';
>> + if (wcscmp (name, ntfn->Name.Buffer) == 0)
>> + {
>> + query_hdl_proc = proc;
>> + query_hdl_value = (HANDLE)(intptr_t) shi->Handles[i].HandleValue;
>> + qh = h;
>> + break;
>> + }
>> +close_handle:
>> + CloseHandle (h);
>> +close_proc:
>> + CloseHandle (proc);
>
> Doesn't this mean that query_hdl_proc is not a valid handle any more? So the
> attempt to reduce overhead at the beginning of tentative_query_hdl() will never
> work.
Never mind. I see my stupid mistake.
> Other than that, I still think it looks great. But it's complicated enough that
> I think Corinna should review it too when she returns. (It also uses Windows
> functions that I have no experience with.) Nevertheless, I'm tempted to push it
> so that it can get testing, even if Corinna changes it or reverts it later.
>
> Ken
More information about the Cygwin-developers
mailing list