diff -urp src.old/winsup/cygwin/thread.cc src/winsup/cygwin/thread.cc
--- src.old/winsup/cygwin/thread.cc	Fri Apr 26 10:23:26 2002
+++ src/winsup/cygwin/thread.cc	Fri Apr 26 10:08:36 2002
@@ -2101,33 +2101,63 @@ __pthread_equal (pthread_t *t1, pthread_
 
 /*Mutexes  */
 
-/*FIXME: there's a potential race with PTHREAD_MUTEX_INITALIZER:
- *the mutex is not actually inited until the first use.
- *So two threads trying to lock/trylock may collide.
- *Solution: we need a global mutex on mutex creation, or possibly simply
- *on all constructors that allow INITIALIZER macros.
- *the lock should be very small: only around the init routine, not
- *every test, or all mutex access will be synchronised.
- */
-
 int
 __pthread_mutex_init (pthread_mutex_t *mutex,
 		      const pthread_mutexattr_t *attr)
 {
+  static pthread_mutex_t init_mutex;
+  int result = 0;
+
+  {
+    // Initialize init_mutex for the PTHREAD_MUTEX_INITIALIZER race
+    // To work around a chicken/egg problem (pthread_once requires mutex_init)
+    // this is done with an InterlockedIncremented counter
+    static struct
+      {
+        bool done;
+        LONG counter;
+      } interlocked_once = { false, -1 };
+
+    if( !interlocked_once.done )
+      {
+         if( 0 == InterlockedIncrement (&interlocked_once.counter) )
+           {
+             init_mutex = new pthread_mutex ((pthread_mutexattr *)NULL);
+             interlocked_once.done = true;
+           }
+         else
+           {
+             InterlockedDecrement (&interlocked_once.counter);
+             while(!interlocked_once.done)
+               {
+                 Sleep(0);
+               }
+           }
+      }
+  }
+
   if (attr && verifyable_object_isvalid (attr, PTHREAD_MUTEXATTR_MAGIC) != VALID_OBJECT || check_valid_pointer (mutex))
     return EINVAL;
 
+  __pthread_mutex_lock (&init_mutex);
+
   if (verifyable_object_isvalid (mutex, PTHREAD_MUTEX_MAGIC, PTHREAD_MUTEX_INITIALIZER) == VALID_OBJECT)
-    return EBUSY;
+    result = EBUSY;
 
-  *mutex = new pthread_mutex (attr ? (*attr) : NULL);
-  if (verifyable_object_isvalid (mutex, PTHREAD_MUTEX_MAGIC) != VALID_OBJECT)
+  else
     {
-      delete (*mutex);
-      *mutex = NULL;
-      return EAGAIN;
+      *mutex = new pthread_mutex (attr ? (*attr) : NULL);
+      if (verifyable_object_isvalid (mutex, PTHREAD_MUTEX_MAGIC) != VALID_OBJECT)
+        {
+          delete (*mutex);
+          *mutex = NULL;
+          result = EAGAIN;
+        }
     }
-  return 0;
+
+  __pthread_mutex_unlock (&init_mutex);
+  
+  return result;
 }
 
 int
