[155] in Pthreads Bugs
pthread_kill() Bug
daemon@ATHENA.MIT.EDU (Thu Dec 26 20:34:45 1996
)
From: Chris Colohan <colohan@eecg.toronto.edu>
To: pthreads-bugs@MIT.EDU, proven@MIT.EDU
Date: Thu, 26 Dec 1996 20:33:48 -0500
pthread_kill() has a problem in PThreads 1.60beta6. It checks to see
if the target thread is in the state PS_SIGWAIT, and if it is it
reschedules it. But it does not check if there is more than one
thread in the PS_SIGWAIT state, and hence mangles the pthread_sigwait
linked list, potentially resulting in threads getting blocked forever,
and signals never being delivered. I have a *very* contrived test
case that demonstrates this problem if you would like it. Please let
me know...
Chris
===
Diffs created with diff -c:
*** /home/colohan/thesis/t/pthreads-1_60_beta6/pthreads/pthread_kill.c Tue Feb 21 03:07:18 1995
--- pthread_kill.c Thu Dec 26 19:50:22 1996
***************
*** 41,51 ****
--- 41,58 ----
#include <pthread.h>
+ /* Defined in sig.c, a linked list of threads currently
+ * blocked in sigwait(): */
+ extern struct pthread * pthread_sigwait;
+
+
/* ==========================================================================
* pthread_kill()
*/
int pthread_kill(struct pthread * pthread, int sig)
{
+ struct pthread ** pthread_ptr;
+
pthread_sched_prevent();
/* Check who is the current owner of pthread */
***************
*** 53,62 ****
if (0) {
} else {
if (pthread->state == PS_SIGWAIT) {
! if (sigismember(pthread->data.sigwait, sig)) {
! *(int *)(pthread->ret) = sig;
! pthread_sched_other_resume(pthread);
! return(OK);
}
}
sigaddset(&(pthread->sigpending), sig);
--- 60,84 ----
if (0) {
} else {
if (pthread->state == PS_SIGWAIT) {
! if(sigismember(pthread->data.sigwait, sig)) {
! for (pthread_ptr = &pthread_sigwait;
! (*pthread_ptr);
! pthread_ptr = &((*pthread_ptr)->next)) {
! if ((*pthread_ptr) == pthread) {
!
! /* Take the thread out of the
! * pthread_sigwait linked list: */
! *pthread_ptr=(*pthread_ptr)->next;
!
! *(int *)(pthread->ret) = sig;
! pthread_sched_other_resume(pthread);
! return(OK);
! }
! }
! /* A thread should not be in the state PS_SIGWAIT
! * without being in the pthread_sigwait linked
! * list: */
! PANIC();
}
}
sigaddset(&(pthread->sigpending), sig);