Explorar o código

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.
Robin Burchell %!s(int64=6) %!d(string=hai) anos
pai
achega
99dd60611f
Modificáronse 1 ficheiros con 2 adicións e 2 borrados
  1. 2 2
      Kernel/Process.cpp

+ 2 - 2
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;