diff options
| author | Ingo Molnar <mingo@elte.hu> | 2002-10-02 23:32:38 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@penguin.transmeta.com> | 2002-10-02 23:32:38 -0700 |
| commit | 794aa320b79d2cb8643ecb6058f0f3fadd51955d (patch) | |
| tree | 9a104738c8c07e1af2797ee7b2d0b48a64e8c3aa /include | |
| parent | 6a20c6fee5ba95d7244762a1873a1754d006ec7b (diff) | |
[PATCH] sigfix-2.5.40-D6
This fixes all known signal semantics problems.
sigwait() is really evil - i had to re-introduce ->real_blocked. When a
signal has no handler defined then the actual action taken by the kernel
depends on whether the sigwait()-ing thread was blocking the signal
originally or not. If the signal was blocked => specific delivery to the
thread, if the signal was not blocked => kill-all.
fortunately this meant that PF_SIGWAIT could be killed - the real_blocked
field contains all the necessery information to do the right decision at
signal-sending time.
i've also cleaned up and made the shared-pending code more robust: now
there's a single central dequeue_signal() function that handles all the
details. Plus upon unqueueing a shared-pending signal we now re-queue the
signal to the current thread, which this time around is not going to end
up in the shared-pending queue. This change handles the following case
correctly: a signal was blocked in every signal, then one thread unblocks
it and gets the signal delivered - but there's no handler for the signal
=> the correct action is to do a kill-all.
i removed the unused shared_unblocked field as well, reported by Oleg
Nesterov.
now we pass both signal-tst1 and signal-tst2, so i'm confident that we got
most of the details right.
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/sched.h | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index 59dcfad4667e..89c4ead4cf4b 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -378,7 +378,7 @@ struct task_struct { /* signal handlers */ struct signal_struct *sig; - sigset_t blocked, real_blocked, shared_unblocked; + sigset_t blocked, real_blocked; struct sigpending pending; unsigned long sas_ss_sp; @@ -530,7 +530,7 @@ extern void proc_caches_init(void); extern void flush_signals(struct task_struct *); extern void flush_signal_handlers(struct task_struct *); extern void sig_exit(int, int, struct siginfo *); -extern int dequeue_signal(struct sigpending *pending, sigset_t *mask, siginfo_t *info); +extern int dequeue_signal(sigset_t *mask, siginfo_t *info); extern void block_all_signals(int (*notifier)(void *priv), void *priv, sigset_t *mask); extern void unblock_all_signals(void); |
