Ver código fonte

Kernel: Try to dispatch pending signals on context switch

This ensures that processes that don't perform any syscalls will also
eventually receive signals.
Idan Horowitz 3 anos atrás
pai
commit
5fa75dbcda
2 arquivos alterados com 11 adições e 4 exclusões
  1. 5 0
      Kernel/Scheduler.cpp
  2. 6 4
      Kernel/Thread.cpp

+ 5 - 0
Kernel/Scheduler.cpp

@@ -304,6 +304,11 @@ void Scheduler::context_switch(Thread* thread)
     // switched from, and thread reflects Thread::current()
     enter_current(*from_thread);
     VERIFY(thread == Thread::current());
+
+    {
+        SpinlockLocker lock(thread->get_lock());
+        thread->dispatch_one_pending_signal();
+    }
 }
 
 void Scheduler::enter_current(Thread& prev_thread)

+ 6 - 4
Kernel/Thread.cpp

@@ -975,8 +975,6 @@ DispatchSignalResult Thread::dispatch_signal(u8 signal)
         return DispatchSignalResult::Deferred;
     }
 
-    VERIFY(previous_mode() == PreviousMode::UserMode);
-
     auto& action = m_signal_action_data[signal];
     // FIXME: Implement SA_SIGINFO signal handlers.
     VERIFY(!(action.flags & SA_SIGINFO));
@@ -1037,8 +1035,12 @@ DispatchSignalResult Thread::dispatch_signal(u8 signal)
         return DispatchSignalResult::Continue;
     }
 
-    VERIFY(previous_mode() == PreviousMode::UserMode);
-    VERIFY(current_trap());
+    if (!current_trap()) {
+        // We're trying dispatch a signal to a user process that was scheduled after
+        // a yielding/blocking kernel thread, we don't have a register capture of the
+        // thread, so just defer processing the signal to later.
+        return DispatchSignalResult::Deferred;
+    }
 
     ScopedAddressSpaceSwitcher switcher(m_process);