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);