summaryrefslogtreecommitdiff
path: root/lib/libpthread/uthread/uthread_sig.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libpthread/uthread/uthread_sig.c')
-rw-r--r--lib/libpthread/uthread/uthread_sig.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/lib/libpthread/uthread/uthread_sig.c b/lib/libpthread/uthread/uthread_sig.c
index d833465bf3a..a457af87b50 100644
--- a/lib/libpthread/uthread/uthread_sig.c
+++ b/lib/libpthread/uthread/uthread_sig.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_sig.c,v 1.18 2003/01/27 22:22:30 marc Exp $ */
+/* $OpenBSD: uthread_sig.c,v 1.19 2003/01/31 04:46:17 marc Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -50,6 +50,7 @@ _thread_sig_init(void)
/* Clear local state */
for (i = 1; i < NSIG; i++) {
+ _SPINLOCK_INIT(&_thread_sigq[i - 1].lock);
_thread_sigq[i - 1].pending = 0;
}
}
@@ -104,12 +105,14 @@ _thread_sig_handler(int sig, siginfo_t *info, struct sigcontext * scp)
* one. Per a POSIX suggestion, only the info for the first
* of multiple activations of the same signal is kept.
*/
+ _SPINLOCK(&_thread_sigq[sig - 1].lock);
if (_thread_sigq[sig - 1].pending == 0) {
sigaddset(&_process_sigpending, sig);
_thread_sigq[sig - 1].pending++;
memcpy(&_thread_sigq[sig - 1].siginfo, info,
sizeof *info);
}
+ _SPINUNLOCK(&_thread_sigq[sig - 1].lock);
if ((_queue_signals != 0) ||
((_thread_kern_in_sched == 0) &&
@@ -144,8 +147,8 @@ _thread_clear_pending(int sig, pthread_t thread)
{
pthread_t pthread;
+ _thread_sigq[sig - 1].pending = 0;
if (sigismember(&_process_sigpending, sig)) {
- _thread_sigq[sig - 1].pending = 0;
sigdelset(&_process_sigpending, sig);
TAILQ_FOREACH(pthread, &_thread_list, tle) {
sigdelset(&pthread->sigpend, sig);
@@ -363,8 +366,6 @@ _dispatch_signal(int sig, struct sigcontext * scp)
struct sigaction act;
void (*action)(int, siginfo_t *, void *);
- _thread_clear_pending(sig, curthread);
-
/* save off the action and set the signal mask */
action = _thread_sigact[sig - 1].sa_sigaction;
set = _thread_sigact[sig - 1].sa_mask;
@@ -381,7 +382,11 @@ _dispatch_signal(int sig, struct sigcontext * scp)
sigaction(sig, &act, NULL);
}
- /* call the action and reset the signal mask */
+ /*
+ * clear the pending flag, deliver the signal, then reset the
+ * signal mask
+ */
+ _thread_clear_pending(sig, curthread);
(*action)(sig, &_thread_sigq[sig - 1].siginfo, scp);
curthread->sigmask = oset;
}