sigsuspend() would previously wake up correctly when a matching signal was
received, but if the signal was in the thread's signal block mask, it would not be handled. Added thread::sig_temp_enabled, an additional mask of not blocked signals, which is set by sigsuspend() and evaluated and reset by handle_signals(). Fixes #5567. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35836 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
5975d86a38
commit
7778bccf93
@ -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;
|
||||
|
@ -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());
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user