summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Burchell <robin+git@viroteck.net>2019-05-18 18:55:56 +0200
committerAndreas Kling <awesomekling@gmail.com>2019-05-18 19:01:08 +0200
commit99dd60611fd9abe5a4c9ef81682c0d7f1d91e5cb (patch)
tree5a69f732003704c9dcea70c75f216d484818c2a4
parentd2c3749cf3269d28726589b7c077d824dd97b1dd (diff)
downloadserenity-99dd60611fd9abe5a4c9ef81682c0d7f1d91e5cb.zip
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.
-rw-r--r--Kernel/Process.cpp4
1 files changed, 2 insertions, 2 deletions
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp
index 274cacd851..3770954931 100644
--- a/Kernel/Process.cpp
+++ b/Kernel/Process.cpp
@@ -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;