Browse Source

Kernel: Don't interrupt blocked syscalls to dispatch ignored signals.

This was just causing syscalls to return EINTR for no reason.
Andreas Kling 6 years ago
parent
commit
4d904340b4
2 changed files with 19 additions and 1 deletions
  1. 18 1
      Kernel/Thread.cpp
  2. 1 0
      Kernel/Thread.h

+ 18 - 1
Kernel/Thread.cpp

@@ -224,13 +224,19 @@ bool Thread::tick()
 void Thread::send_signal(u8 signal, Process* sender)
 {
     ASSERT(signal < 32);
+    InterruptDisabler disabler;
+
+    // FIXME: Figure out what to do for masked signals. Should we also ignore them here?
+    if (should_ignore_signal(signal)) {
+        dbg() << "signal " << signal << " was ignored by " << process();
+        return;
+    }
 
     if (sender)
         dbgprintf("signal: %s(%u) sent %d to %s(%u)\n", sender->name().characters(), sender->pid(), signal, process().name().characters(), pid());
     else
         dbgprintf("signal: kernel sent %d to %s(%u)\n", signal, process().name().characters(), pid());
 
-    InterruptDisabler disabler;
     m_pending_signals |= 1 << signal;
 }
 
@@ -307,6 +313,17 @@ DefaultSignalAction default_signal_action(u8 signal)
     ASSERT_NOT_REACHED();
 }
 
+bool Thread::should_ignore_signal(u8 signal) const
+{
+    ASSERT(signal < 32);
+    auto& action = m_signal_action_data[signal];
+    if (action.handler_or_sigaction.is_null())
+        return default_signal_action(signal) == DefaultSignalAction::Ignore;
+    if (action.handler_or_sigaction.as_ptr() == SIG_IGN)
+        return true;
+    return false;
+}
+
 ShouldUnblockThread Thread::dispatch_signal(u8 signal)
 {
     ASSERT_INTERRUPTS_DISABLED();

+ 1 - 0
Kernel/Thread.h

@@ -121,6 +121,7 @@ public:
     ShouldUnblockThread dispatch_signal(u8 signal);
     bool has_unmasked_pending_signals() const;
     void terminate_due_to_signal(u8 signal);
+    bool should_ignore_signal(u8 signal) const;
 
     FPUState& fpu_state() { return *m_fpu_state; }
     bool has_used_fpu() const { return m_has_used_fpu; }