WL_SOCKET_ACCEPT fairness on Windows
От | Thomas Munro |
---|---|
Тема | WL_SOCKET_ACCEPT fairness on Windows |
Дата | |
Msg-id | CA+hUKG+A2dk29hr5zRP3HVJQ-_PncNJM6HVQ7aaYLXLRBZU-xw@mail.gmail.com обсуждение исходный текст |
Ответы |
Re: WL_SOCKET_ACCEPT fairness on Windows
|
Список | pgsql-hackers |
Hi, Commit 7389aad6 started using WaitEventSetWait() to wait for incoming connections. Before that, we used select(), for which we have our own implementation for Windows. While hacking on patches to rip a bunch of unused Win32 socket wrapper code out, I twigged that the old pgwin32_select() code was careful to report multiple sockets at once by brute force polling of all of them, while WaitEventSetWait() doesn't do that: it reports just one event, because that's what the Windows WaitForMultipleEvents() syscall does. I guess this means you can probably fill up the listen queue of server socket 1 to prevent server socket 2 from ever being serviced, whereas on Unix we'll accept one connection at a time from each in round-robin fashion. I think we could get the same effect as pgwin32_select() more cheaply by doing the initial WaitForMultipleEvents() call with the caller's timeout exactly as we do today, and then, while we have space, repeatedly calling WaitForMultipleEvents(handles=&events[last_signaled_event_index + 1], timeout=0) until it reports timeout. Windows always reports the signaled event with the lowest index in the array, so the idea is to poll the remaining part of the array without waiting, to check for any more. In the most common case of FEBE socket waits etc there would be no extra system call (because it uses nevents=1, so no space for more), and in the postmaster's main loop there would commonly be only one extra system call to determine that no other events have been signaled. The attached patch shows the idea. It's using an ugly goto, but I guess it should be made decent with a real loop; I just didn't want to change the indentation level for this POC. I mention this now because I'm not sure whether to consider this an 'open item' for 16, or merely an enhancement for 17. I guess the former, because someone might call that a new denial of service vector. On the other hand, if you fill up the listen queue for socket 1 with enough vigour, you're also denying service to socket 1, so I don't know if it's worth worrying about. Opinions on that? I don't have Windows to test any of this. Although this patch passes on CI, that means nothing, as I don't expect the new code to be reached, so I'm hoping to find a someone who would be able to set up such a test on Windows, ie putting elog in to the new code path and trying to reach it by connecting to two different ports fast enough to exercise the multiple event case. Or maybe latch.c really needs its own test suite.
Вложения
В списке pgsql-hackers по дате отправления: