summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kernel/Scheduler.cpp5
-rw-r--r--Kernel/Thread.cpp10
2 files changed, 11 insertions, 4 deletions
diff --git a/Kernel/Scheduler.cpp b/Kernel/Scheduler.cpp
index 754f7c7911..1c7d9313d2 100644
--- a/Kernel/Scheduler.cpp
+++ b/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)
diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp
index 6f5e6338d3..93cf27c0a8 100644
--- a/Kernel/Thread.cpp
+++ b/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);