The patch has been made a little smaller and better readable by not
changing the functions order in thread.cc

2002-12-10  Thomas Pfaff  <[EMAIL PROTECTED]>

        * pthread.cc (pthread_cond_init): Use new pthread_cond::init.
        * thread.cc: Some white spaces cleanups.
        Change __pthread_cond_init to pthread_cond::init throughout.
        (nativeMutex): Move class methods outside pthread_mutex.
        (MTinterface::Init): Initialize pthread_cond init lock.
        (pthread_cond::condInitializationLock): Instantiate.
        (pthread_cond::initMutex): New Method.
        (pthread_cond::isGoodInitializerOrBadObject): Ditto.
        * thread.h: Some white spaces cleanups.
        (nativeMutex): Move class declaration outside pthread_mutex.
        (pthread_cond::condInitializationLock): New static member.
        (pthread_cond::initMutex): New Method.
        (pthread_cond::isGoodInitializerOrBadObject): Ditto.
        (__pthread_cond_init): Remove prototype.


On Fri, 29 Nov 2002, Thomas Pfaff wrote:

>
> Rob has added a native mutex around mutex initialization to avoid a
> race. This is required in pthread_cond_init too.
>
> I have moved the nativeMutex class outside of pthread_mutex and added
> similar calls to pthread_cond to avoid that race.
>
> Thomas
>
diff -urp src.old/winsup/cygwin/pthread.cc src/winsup/cygwin/pthread.cc
--- src.old/winsup/cygwin/pthread.cc    2002-09-30 04:23:52.000000000 +0200
+++ src/winsup/cygwin/pthread.cc        2002-11-29 10:06:31.000000000 +0100
@@ -349,7 +349,7 @@ pthread_cond_destroy (pthread_cond_t * c
 int
 pthread_cond_init (pthread_cond_t * cond, const pthread_condattr_t * attr)
 {
-  return __pthread_cond_init (cond, attr);
+  return pthread_cond::init (cond, attr);
 }
 
 int
diff -urp src.old/winsup/cygwin/thread.cc src/winsup/cygwin/thread.cc
--- src.old/winsup/cygwin/thread.cc     2002-11-27 18:22:45.000000000 +0100
+++ src/winsup/cygwin/thread.cc 2002-12-10 14:34:44.000000000 +0100
@@ -72,6 +72,37 @@ _reent_winsup ()
   return _r->_winsup;
 }
 
+bool
+nativeMutex::init ()
+{
+  theHandle = CreateMutex (&sec_none_nih, FALSE, NULL);
+  if (!theHandle)
+    {
+      debug_printf ("CreateMutex failed. %E");
+      return false;
+    }
+  return true;
+}
+
+bool
+nativeMutex::lock ()
+{
+  DWORD waitResult = WaitForSingleObject (theHandle, INFINITE);
+  if (waitResult != WAIT_OBJECT_0)
+    {
+      system_printf ("Received unexpected wait result %d on handle %p, %E", 
+waitResult, theHandle);
+      return false;
+    }
+  return true;
+}
+
+void
+nativeMutex::unlock ()
+{
+  if (!ReleaseMutex (theHandle))
+    system_printf ("Received a unexpected result releasing mutex. %E");
+}
+
 inline LPCRITICAL_SECTION
 ResourceLocks::Lock (int _resid)
 {
@@ -168,6 +199,7 @@ MTinterface::Init (int forked)
     reent_key.set (&reents);
 
   pthread_mutex::initMutex ();
+  pthread_cond::initMutex ();
 }
 
 void
@@ -743,6 +775,19 @@ pthread_condattr::~pthread_condattr ()
 {
 }
 
+/* This is used for cond creation protection within a single process only */
+nativeMutex NO_COPY pthread_cond::condInitializationLock;
+
+/* We can only be called once.
+   TODO: (no rush) use a non copied memory section to
+   hold an initialization flag.  */
+void
+pthread_cond::initMutex ()
+{
+  if (!condInitializationLock.init ())
+    api_fatal ("Could not create win32 Mutex for pthread cond static initializer 
+support.");
+}
+
 pthread_cond::pthread_cond (pthread_condattr *attr):verifyable_object 
(PTHREAD_COND_MAGIC)
 {
   int temperr;
@@ -1090,14 +1135,14 @@ pthread_mutex::isGoodInitializerOrObject
 bool
 pthread_mutex::isGoodInitializerOrBadObject (pthread_mutex_t const *mutex)
 {
-    verifyable_object_state objectState = verifyable_object_isvalid (mutex, 
PTHREAD_MUTEX_MAGIC, PTHREAD_MUTEX_INITIALIZER);
-    if (objectState == VALID_OBJECT)
+  verifyable_object_state objectState = verifyable_object_isvalid (mutex, 
+PTHREAD_MUTEX_MAGIC, PTHREAD_MUTEX_INITIALIZER);
+  if (objectState == VALID_OBJECT)
        return false;
-    return true;
+  return true;
 }
 
 /* This is used for mutex creation protection within a single process only */
-pthread_mutex::nativeMutex pthread_mutex::mutexInitializationLock NO_COPY;
+nativeMutex NO_COPY pthread_mutex::mutexInitializationLock;
 
 /* We can only be called once.
    TODO: (no rush) use a non copied memory section to
@@ -1213,37 +1258,6 @@ pthread_mutex::fixup_after_fork ()
 }
 
 bool
-pthread_mutex::nativeMutex::init ()
-{
-  theHandle = CreateMutex (&sec_none_nih, FALSE, NULL);
-  if (!theHandle)
-    {
-      debug_printf ("CreateMutex failed. %E");
-      return false;
-    }
-  return true;
-}
-
-bool
-pthread_mutex::nativeMutex::lock ()
-{
-  DWORD waitResult = WaitForSingleObject (theHandle, INFINITE);
-  if (waitResult != WAIT_OBJECT_0)
-    {
-      system_printf ("Received unexpected wait result %d on handle %p, %E", 
waitResult, theHandle);
-      return false;
-    }
-  return true;
-}
-
-void
-pthread_mutex::nativeMutex::unlock ()
-{
-  if (!ReleaseMutex (theHandle))
-    system_printf ("Received a unexpected result releasing mutex. %E");
-}
-
-bool
 pthread_mutexattr::isGoodObject (pthread_mutexattr_t const * attr)
 {
   if (verifyable_object_isvalid (attr, PTHREAD_MUTEXATTR_MAGIC) != VALID_OBJECT)
@@ -2001,6 +2015,15 @@ pthread_cond::isGoodInitializerOrObject 
   return true;
 }
 
+bool
+pthread_cond::isGoodInitializerOrBadObject (pthread_cond_t const *cond)
+{
+  verifyable_object_state objectState = verifyable_object_isvalid (cond, 
+PTHREAD_COND_MAGIC, PTHREAD_COND_INITIALIZER);
+  if (objectState == VALID_OBJECT)
+       return false;
+  return true;
+}
+
 int
 __pthread_cond_destroy (pthread_cond_t *cond)
 {
@@ -2020,23 +2043,28 @@ __pthread_cond_destroy (pthread_cond_t *
 }
 
 int
-__pthread_cond_init (pthread_cond_t *cond, const pthread_condattr_t *attr)
+pthread_cond::init (pthread_cond_t *cond, const pthread_condattr_t *attr)
 {
   if (attr && !pthread_condattr::isGoodObject (attr))
     return EINVAL;
+  if (!condInitializationLock.lock ())
+    return EINVAL;
 
-  if (pthread_cond::isGoodObject (cond))
-    return EBUSY;
+  if (!isGoodInitializerOrBadObject (cond))
+    {
+      condInitializationLock.unlock ();
+      return EBUSY;
+    }
 
   *cond = new pthread_cond (attr ? (*attr) : NULL);
-
-  if (!pthread_cond::isGoodObject (cond))
+  if (!isGoodObject (cond))
     {
       delete (*cond);
       *cond = NULL;
+      condInitializationLock.unlock ();
       return EAGAIN;
     }
-
+  condInitializationLock.unlock ();
   return 0;
 }
 
@@ -2044,7 +2072,7 @@ int
 __pthread_cond_broadcast (pthread_cond_t *cond)
 {
   if (pthread_cond::isGoodInitializer (cond))
-    __pthread_cond_init (cond, NULL);
+    pthread_cond::init (cond, NULL);
   if (!pthread_cond::isGoodObject (cond))
     return EINVAL;
 
@@ -2057,7 +2085,7 @@ int
 __pthread_cond_signal (pthread_cond_t *cond)
 {
   if (pthread_cond::isGoodInitializer (cond))
-    __pthread_cond_init (cond, NULL);
+    pthread_cond::init (cond, NULL);
   if (!pthread_cond::isGoodObject (cond))
     return EINVAL;
 
@@ -2078,7 +2106,7 @@ __pthread_cond_dowait (pthread_cond_t *c
     pthread_mutex::init (mutex, NULL);
   themutex = mutex;
   if (pthread_cond::isGoodInitializer (cond))
-    __pthread_cond_init (cond, NULL);
+    pthread_cond::init (cond, NULL);
 
   if (!pthread_mutex::isGoodObject (themutex))
     return EINVAL;
diff -urp src.old/winsup/cygwin/thread.h src/winsup/cygwin/thread.h
--- src.old/winsup/cygwin/thread.h      2002-11-27 18:22:45.000000000 +0100
+++ src/winsup/cygwin/thread.h  2002-11-29 10:34:55.000000000 +0100
@@ -121,6 +121,16 @@ void AssertResourceOwner (int, int);
 #endif
 }
 
+class nativeMutex
+{
+public:
+  bool init ();
+  bool lock ();
+  void unlock ();
+private:
+  HANDLE theHandle;
+};
+
 class per_process;
 class pinfo;
 
@@ -288,9 +298,9 @@ public:
 class pthread_mutex:public verifyable_object
 {
 public:
-  static bool isGoodObject(pthread_mutex_t const *);
-  static bool isGoodInitializer(pthread_mutex_t const *);
-  static bool isGoodInitializerOrObject(pthread_mutex_t const *);
+  static bool isGoodObject (pthread_mutex_t const *);
+  static bool isGoodInitializer (pthread_mutex_t const *);
+  static bool isGoodInitializerOrObject (pthread_mutex_t const *);
   static bool isGoodInitializerOrBadObject (pthread_mutex_t const *mutex);
   static void initMutex ();
   static int init (pthread_mutex_t *, const pthread_mutexattr_t *);
@@ -309,15 +319,8 @@ public:
   pthread_mutex (pthread_mutexattr * = NULL);
   pthread_mutex (pthread_mutex_t *, pthread_mutexattr *);
   ~pthread_mutex ();
+
 private:
-  class nativeMutex {
-    public:
-      bool init();
-      bool lock();
-      void unlock();
-    private:
-      HANDLE theHandle;
-  };
   static nativeMutex mutexInitializationLock;
 };
 
@@ -432,9 +435,13 @@ public:
 class pthread_cond:public verifyable_object
 {
 public:
-  static bool isGoodObject(pthread_cond_t const *);
-  static bool isGoodInitializer(pthread_cond_t const *);
-  static bool isGoodInitializerOrObject(pthread_cond_t const *);
+  static bool isGoodObject (pthread_cond_t const *);
+  static bool isGoodInitializer (pthread_cond_t const *);
+  static bool isGoodInitializerOrObject (pthread_cond_t const *);
+  static bool isGoodInitializerOrBadObject (pthread_cond_t const *);
+  static void initMutex ();
+  static int init (pthread_cond_t *, const pthread_condattr_t *);
+
   int shared;
   LONG waiting;
   LONG ExitingWait;
@@ -450,6 +457,9 @@ public:
 
   pthread_cond (pthread_condattr *);
   ~pthread_cond ();
+
+private:
+  static nativeMutex condInitializationLock;
 };
 
 class pthread_once
@@ -560,8 +570,6 @@ void *__pthread_getspecific (pthread_key
 
 /* Thead synchroniation */
 int __pthread_cond_destroy (pthread_cond_t * cond);
-int __pthread_cond_init (pthread_cond_t * cond,
-                        const pthread_condattr_t * attr);
 int __pthread_cond_signal (pthread_cond_t * cond);
 int __pthread_cond_broadcast (pthread_cond_t * cond);
 int __pthread_condattr_init (pthread_condattr_t * condattr);

Reply via email to