aboutsummaryrefslogtreecommitdiff
path: root/lib/libc_r/uthread/uthread_sig.c
diff options
context:
space:
mode:
authorDaniel Eischen <deischen@FreeBSD.org>2000-03-15 13:59:27 +0000
committerDaniel Eischen <deischen@FreeBSD.org>2000-03-15 13:59:27 +0000
commit1d013a86edb866de00bf57761c845388c8d9a467 (patch)
tree935feb03e56c674b055ccf5f23861c18e476211a /lib/libc_r/uthread/uthread_sig.c
parent8d548e1f88b83ea07e628bc6ddb7144ee8379bcd (diff)
downloadsrc-1d013a86edb866de00bf57761c845388c8d9a467.tar.gz
src-1d013a86edb866de00bf57761c845388c8d9a467.zip
Fix pthread_suspend_np/pthread_resume_np. For the record, suspending a
thread waiting on an event (I/O, condvar, etc) will, when resumed using pthread_resume_np, return with EINTR. For example, suspending and resuming a thread blocked on read() will not requeue the thread for the read, but will return -1 with errno = EINTR. If the suspended thread is in a critical region, the thread is suspended as soon as it leaves the critical region. Fix a bogon in pthread_kill() where a signal was being delivered twice to threads waiting in sigwait(). Reported by (suspend/resume bug): jdp Reviewed by: jasone
Notes
Notes: svn path=/head/; revision=58094
Diffstat (limited to 'lib/libc_r/uthread/uthread_sig.c')
-rw-r--r--lib/libc_r/uthread/uthread_sig.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/lib/libc_r/uthread/uthread_sig.c b/lib/libc_r/uthread/uthread_sig.c
index dc6d209f85b0..86ded7f12cbb 100644
--- a/lib/libc_r/uthread/uthread_sig.c
+++ b/lib/libc_r/uthread/uthread_sig.c
@@ -149,7 +149,7 @@ _thread_sig_handler(int sig, int code, ucontext_t * scp)
signal_lock.access_lock = 0;
else {
sigaddset(&pthread->sigmask, sig);
-
+
/*
* Make sure not to deliver the same signal to
* the thread twice. sigpend is potentially
@@ -160,7 +160,7 @@ _thread_sig_handler(int sig, int code, ucontext_t * scp)
*/
if (sigismember(&pthread->sigpend, sig))
sigdelset(&pthread->sigpend, sig);
-
+
signal_lock.access_lock = 0;
_thread_sig_deliver(pthread, sig);
sigdelset(&pthread->sigmask, sig);
@@ -461,6 +461,7 @@ handle_state_change(pthread_t pthread)
case PS_RUNNING:
case PS_SIGTHREAD:
case PS_STATE_MAX:
+ case PS_SUSPENDED:
break;
/*
@@ -492,7 +493,6 @@ handle_state_change(pthread_t pthread)
case PS_SIGWAIT:
case PS_SLEEP_WAIT:
case PS_SPINBLOCK:
- case PS_SUSPENDED:
case PS_WAIT_WAIT:
if ((pthread->flags & PTHREAD_FLAGS_IN_WAITQ) != 0) {
PTHREAD_WAITQ_REMOVE(pthread);
@@ -628,10 +628,12 @@ _thread_sig_send(pthread_t pthread, int sig)
!sigismember(&pthread->sigmask, sig)) {
/* Perform any state changes due to signal arrival: */
thread_sig_check_state(pthread, sig);
+ /* Increment the pending signal count. */
+ sigaddset(&pthread->sigpend,sig);
+ } else {
+ /* Increment the pending signal count. */
+ sigaddset(&pthread->sigpend,sig);
}
-
- /* Increment the pending signal count. */
- sigaddset(&pthread->sigpend,sig);
}
}