1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 10:28:10 +00:00

Kernel: Fix select with a 0 timeout

select essentially has 3 modes (which is presumably why we're finding it
so hard to get this right in a reliable way :)).

1. NULL timeout -- no timeout on blocking
2. non-NULL timeout that is not zero'd -- timeout on blocking
3. non-NULL but zero timeout -- no blocking at all (immediate poll)

For cases 1 and 2, we want to block the thread. We have a timeout set
only for case 2, though.

Case 3 should not block the thread, and does not have a timeout set.
This commit is contained in:
Robin Burchell 2019-05-18 18:55:56 +02:00 committed by Andreas Kling
parent d2c3749cf3
commit 99dd60611f

View file

@ -1757,7 +1757,7 @@ int Process::sys$select(const Syscall::SC_select_params* params)
// FIXME: Implement exceptfds support.
(void)exceptfds;
if (timeout) {
if (timeout && (timeout->tv_sec || timeout->tv_usec)) {
struct timeval now;
kgettimeofday(now);
AK::timeval_add(&now, timeout, &current->m_select_timeout);
@ -1802,7 +1802,7 @@ int Process::sys$select(const Syscall::SC_select_params* params)
dbgprintf("%s<%u> selecting on (read:%u, write:%u), timeout=%p\n", name().characters(), pid(), current->m_select_read_fds.size(), current->m_select_write_fds.size(), timeout);
#endif
if (!timeout || (timeout->tv_sec || timeout->tv_usec))
if (!timeout || current->m_select_has_timeout)
current->block(Thread::State::BlockedSelect);
int markedfds = 0;