diff -urp src.old/winsup/cygwin/thread.cc src/winsup/cygwin/thread.cc
--- src.old/winsup/cygwin/thread.cc	Mon May 27 12:28:12 2002
+++ src/winsup/cygwin/thread.cc	Mon May 27 12:29:01 2002
@@ -368,7 +368,7 @@ MTinterface::fixup_after_fork (void)
 pthread::pthread ():verifyable_object (PTHREAD_MAGIC), win32_obj_id (0),
                     cancelstate (0), canceltype (0), cancel_event (0),
                     mutex ((pthread_mutex *)PTHREAD_MUTEX_INITIALIZER),
-                    cleanup_handlers(NULL), joiner(NULL)
+                    cleanup_stack(NULL), joiner(NULL)
 {
 }
 
@@ -1038,22 +1038,24 @@ __pthread_cancel (pthread_t thread)
   if (verifyable_object_isvalid (&thread, PTHREAD_MAGIC) != VALID_OBJECT)
     return ESRCH;
 
-  if( __pthread_equal(&thread, &self ) )
-    {
-      __pthread_cancel_self ();
-    }
-
   __pthread_mutex_lock (&thread->mutex);
 
   if (thread->canceltype == PTHREAD_CANCEL_DEFERRED ||
       thread->cancelstate == PTHREAD_CANCEL_DISABLE)
 	{
       // cancel deferred
-      SetEvent (thread->cancel_event);
       __pthread_mutex_unlock (&thread->mutex);
+      SetEvent (thread->cancel_event);
       return 0;
 	}
 
+  else if (__pthread_equal(&thread, &self))
+    {
+      __pthread_mutex_unlock (&thread->mutex);
+      __pthread_cancel_self ();
+      return 0; // Never reached
+    }
+
   // cancel asynchronous
   SuspendThread (thread->win32_obj_id);
   if (WaitForSingleObject (thread->win32_obj_id, 0) == WAIT_TIMEOUT)
@@ -1064,9 +1066,8 @@ __pthread_cancel (pthread_t thread)
       PROGCTR(context) = (DWORD) __pthread_cancel_self;
       SetThreadContext (thread->win32_obj_id, &context);
     }
-  ResumeThread (thread->win32_obj_id);
-
   __pthread_mutex_unlock (&thread->mutex);
+  ResumeThread (thread->win32_obj_id);
 
   return 0;
 /*
@@ -1314,8 +1315,8 @@ __pthread_cleanup_push (__pthread_cleanu
   // cleanup_push is not async cancel safe
   __pthread_mutex_lock(&thread->mutex);
 
-  handler->next = thread->cleanup_handlers;
-  thread->cleanup_handlers = handler;
+  handler->next = thread->cleanup_stack;
+  thread->cleanup_stack = handler;
 
   __pthread_mutex_unlock(&thread->mutex);
 }
@@ -1325,15 +1326,15 @@ __pthread_cleanup_pop (int execute)
 {
   pthread_t thread = __pthread_self ();
 
-  if( thread->cleanup_handlers != NULL )
-  {
-     __pthread_cleanup_handler *handler = thread->cleanup_handlers;
+  if (thread->cleanup_stack != NULL)
+    {
+      __pthread_cleanup_handler *handler = thread->cleanup_stack;
 
-     if (execute)
-       (*handler->function) (handler->arg);
+      if (execute)
+        (*handler->function) (handler->arg);
 
-     thread->cleanup_handlers = handler->next;
-  }
+      thread->cleanup_stack = handler->next;
+    }
 }
 
 void
@@ -1341,10 +1342,10 @@ __pthread_cleanup_pop_all (void)
 {
   pthread_t thread = __pthread_self ();
 
-  while(thread->cleanup_handlers != NULL)
-  {
+  while (thread->cleanup_stack != NULL)
+   {
      __pthread_cleanup_pop (1);
-  }
+   }
 }
 
 /*
diff -urp src.old/winsup/cygwin/thread.h src/winsup/cygwin/thread.h
--- src.old/winsup/cygwin/thread.h	Mon May 27 12:28:12 2002
+++ src/winsup/cygwin/thread.h	Mon May 27 12:28:27 2002
@@ -243,7 +243,7 @@ public:
   int cancelstate, canceltype;
   HANDLE cancel_event;
   pthread_mutex *mutex;
-  __pthread_cleanup_handler *cleanup_handlers;
+  __pthread_cleanup_handler *cleanup_stack;
   pthread_t joiner;
   // int joinable;
 
