diff --git a/headers/private/kernel/thread_types.h b/headers/private/kernel/thread_types.h index 25a6249f5f..ef3d48a75a 100644 --- a/headers/private/kernel/thread_types.h +++ b/headers/private/kernel/thread_types.h @@ -252,6 +252,7 @@ struct thread { sigset_t sig_pending; sigset_t sig_block_mask; + sigset_t sig_temp_enabled; struct sigaction sig_action[32]; addr_t signal_stack_base; size_t signal_stack_size; diff --git a/src/system/kernel/signal.cpp b/src/system/kernel/signal.cpp index 850db7ee35..d5d3144418 100644 --- a/src/system/kernel/signal.cpp +++ b/src/system/kernel/signal.cpp @@ -263,7 +263,9 @@ class SigSuspendDone : public AbstractTraceEntry { static void update_thread_signals_flag(struct thread* thread) { - if (atomic_get(&thread->sig_pending) & ~atomic_get(&thread->sig_block_mask)) + sigset_t mask = ~atomic_get(&thread->sig_block_mask) + | thread->sig_temp_enabled; + if (atomic_get(&thread->sig_pending) & mask) atomic_or(&thread->flags, THREAD_FLAGS_SIGNALS_PENDING); else atomic_and(&thread->flags, ~THREAD_FLAGS_SIGNALS_PENDING); @@ -307,7 +309,8 @@ bool handle_signals(struct thread *thread) { uint32 signalMask = atomic_get(&thread->sig_pending) - & ~atomic_get(&thread->sig_block_mask); + & (~atomic_get(&thread->sig_block_mask) | thread->sig_temp_enabled); + thread->sig_temp_enabled = 0; // If SIGKILL[THR] are pending, we ignore other signals. // Otherwise check, if the thread shall stop for debugging. @@ -904,6 +907,8 @@ sigsuspend(const sigset_t *mask) // restore the original block mask atomic_set(&thread->sig_block_mask, oldMask); + thread->sig_temp_enabled = ~*mask; + update_current_thread_signals_flag(); T(SigSuspendDone()); diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp index aaee20e32a..a766f06d69 100644 --- a/src/system/kernel/thread.cpp +++ b/src/system/kernel/thread.cpp @@ -195,6 +195,7 @@ reset_signals(struct thread *thread) { thread->sig_pending = 0; thread->sig_block_mask = 0; + thread->sig_temp_enabled = 0; memset(thread->sig_action, 0, 32 * sizeof(struct sigaction)); thread->signal_stack_base = 0; thread->signal_stack_size = 0; @@ -1164,8 +1165,9 @@ _dump_thread_info(struct thread *thread, bool shortInfo) kprintf("(%d)\n", thread->cpu->cpu_num); else kprintf("\n"); - kprintf("sig_pending: %#lx (blocked: %#lx)\n", thread->sig_pending, - thread->sig_block_mask); + kprintf("sig_pending: %#" B_PRIx32 " (blocked: %#" B_PRIx32 + ", temp enabled: %#" B_PRIx32 ")\n", thread->sig_pending, + thread->sig_block_mask, thread->sig_temp_enabled); kprintf("in_kernel: %d\n", thread->in_kernel); if (thread->state == B_THREAD_WAITING) {