diff options
author | Daniel Eischen <deischen@FreeBSD.org> | 2000-03-15 13:59:27 +0000 |
---|---|---|
committer | Daniel Eischen <deischen@FreeBSD.org> | 2000-03-15 13:59:27 +0000 |
commit | 1d013a86edb866de00bf57761c845388c8d9a467 (patch) | |
tree | 935feb03e56c674b055ccf5f23861c18e476211a /lib/libc_r/uthread/uthread_sig.c | |
parent | 8d548e1f88b83ea07e628bc6ddb7144ee8379bcd (diff) | |
download | src-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.c | 14 |
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); } } |