p155 3.05 KB
Newer Older
unknown's avatar
unknown committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
<HEAD><TITLE>discuss@charon.mit.edu: [155] in "Pthreads Bugs"</TITLE>
<H1>[155] in Pthreads Bugs</H1></HEAD>
<A HREF="/"><IMG SRC="/i-d.gif" ALT="root"></A>
<A HREF="?155"><IMG SRC="/i-back.gif" ALT="meeting"></A>
<A HREF="/help.html"><IMG SRC="/i-help.gif" ALT="help"></A>
<A HREF="1"><IMG SRC="/i-first.gif" ALT="first"></A>
<IMG SRC="/n-fref.gif" ALT="">
<IMG SRC="/n-pref.gif" ALT="">
<A HREF="154"><IMG SRC="/i-prev.gif" ALT="previous"></A>
<A HREF="156"><IMG SRC="/i-next.gif" ALT="next"></A>
<IMG SRC="/n-nref.gif" ALT="">
<IMG SRC="/n-lref.gif" ALT="">
<A HREF="161"><IMG SRC="/i-last.gif" ALT="last"></A>
<HR><H2>pthread_kill() Bug</H2>
<H3>daemon@ATHENA.MIT.EDU (Thu Dec 26 20:34:45 1996
)</H3>
<PRE>
From: Chris Colohan &lt;colohan@eecg.toronto.edu&gt;
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 &lt;pthread.h&gt;
  
+ /* 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-&gt;state == PS_SIGWAIT) {
! 			if (sigismember(pthread-&gt;data.sigwait, sig)) {
! 				*(int *)(pthread-&gt;ret) = sig;
! 				pthread_sched_other_resume(pthread);
! 				return(OK);
  			}
  		}
  		sigaddset(&amp;(pthread-&gt;sigpending), sig);
--- 60,84 ----
  	if (0) {
  	} else {
  		if (pthread-&gt;state == PS_SIGWAIT) {
! 			if(sigismember(pthread-&gt;data.sigwait, sig)) {
! 			    for (pthread_ptr = &amp;pthread_sigwait;
! 				 (*pthread_ptr);
! 				 pthread_ptr = &amp;((*pthread_ptr)-&gt;next)) {
! 				if ((*pthread_ptr) == pthread) {
! 
! 				    /* Take the thread out of the
! 				     * pthread_sigwait linked list: */
! 				    *pthread_ptr=(*pthread_ptr)-&gt;next;
! 			
! 				    *(int *)(pthread-&gt;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(&amp;(pthread-&gt;sigpending), sig);