Attached is a patch for -stable that should fix the problem your test
exposes, as well as a problem that your actual program might hit (canceled
threads should not detach).  I also noticed and hopefully fixed a problem
with canceling a thread suspended while joining, but you probably don't do
that. =)

Please give the patch a try and let me know if it works for you.

Thanks,
Jason

P.S. Dan Eischen provided the bulk of this fix.  Thanks Dan!
Index: uthread_cancel.c
===================================================================
RCS file: /home/ncvs/src/lib/libc_r/uthread/uthread_cancel.c,v
retrieving revision 1.3.2.3
diff -u -r1.3.2.3 uthread_cancel.c
--- uthread_cancel.c    2001/06/23 00:47:05     1.3.2.3
+++ uthread_cancel.c    2001/07/12 20:59:13
@@ -59,9 +59,23 @@
                                break;
 
                        case PS_JOIN:
+                               /*
+                                * Disconnect the thread from the joinee and
+                                * detach:
+                                */
+                               if (pthread->data.thread != NULL) {
+                                       pthread->data.thread->joiner = NULL;
+                                       pthread_detach((pthread_t)
+                                           pthread->data.thread);
+                               }
+                               pthread->cancelflags |= PTHREAD_CANCELLING;
+                               PTHREAD_NEW_STATE(pthread, PS_RUNNING);
+                               break;
+
                        case PS_SUSPENDED:
                                if (pthread->suspended == SUSP_NO ||
                                    pthread->suspended == SUSP_YES ||
+                                   pthread->suspended == SUSP_JOIN ||
                                    pthread->suspended == SUSP_NOWAIT) {
                                        /*
                                         * This thread isn't in any scheduling
@@ -180,7 +194,6 @@
                 */
                _thread_run->cancelflags &= ~PTHREAD_CANCELLING;
                _thread_exit_cleanup();
-               pthread_detach((pthread_t)_thread_run);
                pthread_exit(PTHREAD_CANCELED);
                PANIC("cancel");
        }
@@ -211,7 +224,6 @@
        if ((_thread_run->cancelflags & PTHREAD_CANCEL_NEEDED) != 0) {
                _thread_run->cancelflags &= ~PTHREAD_CANCEL_NEEDED;
                _thread_exit_cleanup();
-               pthread_detach((pthread_t)_thread_run);
                pthread_exit(PTHREAD_CANCELED);
        }
 }
Index: uthread_join.c
===================================================================
RCS file: /home/ncvs/src/lib/libc_r/uthread/uthread_join.c,v
retrieving revision 1.12.2.3
diff -u -r1.12.2.3 uthread_join.c
--- uthread_join.c      2001/07/05 16:04:09     1.12.2.3
+++ uthread_join.c      2001/07/12 20:30:29
@@ -119,6 +119,9 @@
                /* Set the running thread to be the joiner: */
                pthread->joiner = _thread_run;
 
+               /* Keep track of which thread we're joining to: */
+               _thread_run->data.thread = pthread;
+
                /* Schedule the next thread: */
                _thread_kern_sched_state(PS_JOIN, __FILE__, __LINE__);
 

Reply via email to