Index: /trunk/ccl/lisp-kernel/thread_manager.c
===================================================================
--- /trunk/ccl/lisp-kernel/thread_manager.c	(revision 470)
+++ /trunk/ccl/lisp-kernel/thread_manager.c	(revision 471)
@@ -435,5 +435,5 @@
     tcr->tlb_pointer[i] = (LispObj) no_thread_local_binding_marker;
   }
-
+  tcr->shutdown_count = PTHREAD_DESTRUCTOR_ITERATIONS;
   return tcr;
 }
@@ -456,7 +456,8 @@
   }
   
-  if (tcr->flags & (1<<TCR_FLAG_BIT_SHUTDOWN_REQUEST)) {
-    tcr->flags &= ~(1<<TCR_FLAG_BIT_SHUTDOWN_REQUEST);
-
+  if (--(tcr->shutdown_count) == 0) {
+#ifdef DEBUG_THREAD_CLEANUP
+    fprintf(stderr, "\nprocessing final shutdown request for pthread 0x%x tcr 0x%x", pthread_self(), tcr);
+#endif
 #ifdef DARWIN
     darwin_exception_cleanup(tcr);
@@ -484,6 +485,9 @@
     tcr->osid = 0;
   } else {
-    tcr->flags |= (1<<TCR_FLAG_BIT_SHUTDOWN_REQUEST);
     tsd_set(lisp_global(TCR_KEY), tcr);
+#ifdef DEBUG_THREAD_CLEANUP
+    fprintf(stderr, "\nprocessing early shutdown request for pthread 0x%x tcr 0x%x, tsd = 0x%x",
+	    pthread_self(), tcr, tsd_get(lisp_global(TCR_KEY)));
+#endif
   }
 }
@@ -725,5 +729,7 @@
     current->flags |= (1<<TCR_FLAG_BIT_FOREIGN);
     register_thread_tcr(current);
-
+#ifdef DEBUG_TCR_CREATION
+    fprintf(stderr, "\ncreating TCR for pthread 0x%x", pthread_self());
+#endif
     current->vs_area->active -= 4;
     *(--current->save_vsp) = lisp_nil;
@@ -746,8 +752,25 @@
   int suspend_count = atomic_incf(&(tcr->suspend_count));
   if (suspend_count == 1) {
-    pthread_kill((pthread_t)tcr->osid, thread_suspend_signal);
-    SEM_WAIT(tcr->suspend);
-  }
-  return suspend_count == 1;
+    if (pthread_kill((pthread_t)tcr->osid, thread_suspend_signal) == 0) {
+      SEM_WAIT(tcr->suspend);
+    } else {
+      /* A problem using pthread_kill.  On Darwin, this can happen
+	 if the thread has had its signal mask surgically removed
+	 by pthread_exit.  If the native (Mach) thread can be suspended,
+	 do that and return true; otherwise, flag the tcr as belonging
+	 to a dead thread by setting tcr->osid to 0.
+      */
+#ifdef DARWIN
+      if (mach_suspend_tcr(tcr)) {
+	tcr->flags |= TCR_FLAG_BIT_ALT_SUSPEND;
+	return true;
+      }
+#endif
+      tcr->osid = 0;
+      return false;
+    }
+    return true;
+  }
+  return false;
 }
 
@@ -770,7 +793,15 @@
   int suspend_count = atomic_decf(&(tcr->suspend_count));
   if (suspend_count == 0) {
+#ifdef DARWIN
+    if (tcr->flags & TCR_FLAG_BIT_ALT_SUSPEND) {
+      tcr->flags &= ~TCR_FLAG_BIT_ALT_SUSPEND;
+      mach_resume_tcr(tcr);
+      return true;
+    }
+#endif
     pthread_kill((pthread_t)tcr->osid, thread_resume_signal);
-  }
-  return (suspend_count == 0);
+    return true;
+  }
+  return false;
 }
 
@@ -799,6 +830,9 @@
   LOCK(lisp_global(TCR_LOCK), current);
   for (other = current->next; other != current; other = other->next) {
-    if (other->osid != 0) {
+    if ((other->osid != 0)) {
       suspend_tcr(other);
+      if (other->osid == 0) {
+	dead_tcr_count++;
+      }
     } else {
       dead_tcr_count++;
@@ -809,5 +843,5 @@
     for (other = current->next; other != current; other = next) {
       next = other->next;
-      if (other->osid == 0) {
+      if ((other->osid == 0))  {
 	dequeue_tcr(other);
 	free(other);
