From: rbcollins Date: Sun, 29 Sep 2002 23:47:45 +0000 (+0000) Subject: 2002-09-30 Robert Collins X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=1cd5c8063f6f984ae624c2e2a18e80dae5777a96;p=pf3gnuchains%2Fsourceware.git 2002-09-30 Robert Collins * pthread.cc (pthread_mutex_init): Use new pthread_mutex::init. * thread.cc: Change __pthread_mutex_init to pthread_mutex::init throughout. (MTinterface::Init): Initialise pthread_mutex support. (pthread_mutex::mutexInitializationLock): Instantiate. (pthread_mutex::initMutex): New method. (__pthread_cond_dowait): Don't dereference untrusted pointers. Use the new pthread_mutex::init method. (__pthread_condattr_init): Don't dereference untrusted pointers. (__pthread_mutex_init): Rename to pthread_mutex::init. Lock and release mutexInitializationLock to prevent races on mutex initialisation. * thread.h (pthread_mutex::initMutex): New method, initialise pthread_mutex supporting state on process initialisation. (pthread_mutex::init): Initialise a single mutex. (pthread_mutex::mutexInitializationLock): A win32 mutex for syncronising pthread mutex initialisation. (__pthread_mutex_init): Remove this. --- diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 5f280307a8..970291ac3c 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,24 @@ +2002-09-30 Robert Collins + + * pthread.cc (pthread_mutex_init): Use new pthread_mutex::init. + * thread.cc: Change __pthread_mutex_init to pthread_mutex::init + throughout. + (MTinterface::Init): Initialise pthread_mutex support. + (pthread_mutex::mutexInitializationLock): Instantiate. + (pthread_mutex::initMutex): New method. + (__pthread_cond_dowait): Don't dereference untrusted pointers. + Use the new pthread_mutex::init method. + (__pthread_condattr_init): Don't dereference untrusted pointers. + (__pthread_mutex_init): Rename to pthread_mutex::init. + Lock and release mutexInitializationLock to prevent races on + mutex initialisation. + * thread.h (pthread_mutex::initMutex): New method, initialise + pthread_mutex supporting state on process initialisation. + (pthread_mutex::init): Initialise a single mutex. + (pthread_mutex::mutexInitializationLock): A win32 mutex for + syncronising pthread mutex initialisation. + (__pthread_mutex_init): Remove this. + 2002-09-28 Christopher Faylor * thread.h (verifyable_object:~verifyable_object): Make virtual. diff --git a/winsup/cygwin/pthread.cc b/winsup/cygwin/pthread.cc index cfa0c28ea9..30d048047e 100644 --- a/winsup/cygwin/pthread.cc +++ b/winsup/cygwin/pthread.cc @@ -234,7 +234,7 @@ pthread_equal (pthread_t t1, pthread_t t2) int pthread_mutex_init (pthread_mutex_t * mutex, const pthread_mutexattr_t * attr) { - return __pthread_mutex_init (mutex, attr); + return pthread_mutex::init (mutex, attr); } int diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index 6b05cffb2e..ca992d3d2d 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -190,6 +190,7 @@ MTinterface::Init (int forked) threadcount = 1; /*1 current thread when Init occurs.*/ pthread::initMainThread (&mainthread, myself->hProcess); + pthread_mutex::initMutex (); if (forked) return; @@ -1097,6 +1098,21 @@ pthread_mutex::isGoodInitializerOrObject (pthread_mutex_t const *mutex) return true; } +HANDLE pthread_mutex::mutexInitializationLock; + +/* We can only be called once. + * TODO: (no rush) use a non copied memory section to + * hold an initialization flag. + */ +void +pthread_mutex::initMutex () +{ + mutexInitializationLock = CreateMutex (NULL, FALSE, NULL); + if (!mutexInitializationLock) + api_fatal ("Could not create win32 Mutex for pthread mutex static initializer support. The error code was %d\n", GetLastError()); + +} + pthread_mutex::pthread_mutex (pthread_mutexattr *attr):verifyable_object (PTHREAD_MUTEX_MAGIC) { /*attr checked in the C call */ @@ -2034,8 +2050,8 @@ __pthread_cond_dowait (pthread_cond_t *cond, pthread_mutex_t *mutex, // broadcast occurs - we miss the broadcast. the functions aren't split properly. int rv; pthread_mutex **themutex = NULL; - if (*mutex == PTHREAD_MUTEX_INITIALIZER) - __pthread_mutex_init (mutex, NULL); + if (pthread_mutex::isGoodInitializer (mutex)) + pthread_mutex::init (mutex, NULL); themutex = mutex; if (pthread_cond::isGoodInitializer (cond)) __pthread_cond_init (cond, NULL); @@ -2109,7 +2125,8 @@ pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex) int __pthread_condattr_init (pthread_condattr_t *condattr) { - /* FIXME: we dereference blindly! */ + if (check_valid_pointer (condattr)) + return EINVAL; *condattr = new pthread_condattr; if (!pthread_condattr::isGoodObject (condattr)) { @@ -2210,23 +2227,37 @@ __pthread_equal (pthread_t *t1, pthread_t *t2) */ int -__pthread_mutex_init (pthread_mutex_t *mutex, +pthread_mutex::init (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) { if (attr && !pthread_mutexattr::isGoodObject (attr) || check_valid_pointer (mutex)) return EINVAL; + DWORD waitResult = WaitForSingleObject (mutexInitializationLock, INFINITE); + if (waitResult != WAIT_OBJECT_0) + { + system_printf ("Recieved a unexpected wait result on mutexInitializationLock %d\n", waitResult); + return EINVAL; + } /* FIXME: bugfix: we should check *mutex being a valid address */ - if (pthread_mutex::isGoodObject (mutex)) - return EBUSY; + if (isGoodObject (mutex)) + { + if (! ReleaseMutex(mutexInitializationLock)) + system_printf ("Recieved a unexpected result releasing mutexInitializationLock %d\n", GetLastError()); + return EBUSY; + } *mutex = new pthread_mutex (attr ? (*attr) : NULL); - if (!pthread_mutex::isGoodObject (mutex)) + if (!isGoodObject (mutex)) { delete (*mutex); *mutex = NULL; + if (! ReleaseMutex(mutexInitializationLock)) + system_printf ("Recieved a unexpected result releasing mutexInitializationLock %d\n", GetLastError()); return EAGAIN; } + if (! ReleaseMutex(mutexInitializationLock)) + system_printf ("Recieved a unexpected result releasing mutexInitializationLock %d\n", GetLastError()); return 0; } @@ -2236,7 +2267,7 @@ __pthread_mutex_getprioceiling (const pthread_mutex_t *mutex, { pthread_mutex_t *themutex = (pthread_mutex_t *) mutex; if (pthread_mutex::isGoodInitializer (mutex)) - __pthread_mutex_init ((pthread_mutex_t *) mutex, NULL); + pthread_mutex::init ((pthread_mutex_t *) mutex, NULL); if (!pthread_mutex::isGoodObject (themutex)) return EINVAL; /*We don't define _POSIX_THREAD_PRIO_PROTECT because we do't currently support @@ -2266,10 +2297,13 @@ __pthread_mutex_lock (pthread_mutex_t *mutex) case VALID_STATIC_OBJECT: if (pthread_mutex::isGoodInitializer (mutex)) { - int rv = __pthread_mutex_init (mutex, NULL); + int rv = pthread_mutex::init (mutex, NULL); if (rv) return rv; } + /* No else needed. If it's been initialized while we waited, + * we can just attempt to lock it + */ break; case VALID_OBJECT: break; @@ -2283,7 +2317,7 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex) { pthread_mutex_t *themutex = mutex; if (pthread_mutex::isGoodInitializer (mutex)) - __pthread_mutex_init (mutex, NULL); + pthread_mutex::init (mutex, NULL); if (!pthread_mutex::isGoodObject (themutex)) return EINVAL; if ((*themutex)->TryLock ()) @@ -2295,7 +2329,7 @@ int __pthread_mutex_unlock (pthread_mutex_t *mutex) { if (pthread_mutex::isGoodInitializer (mutex)) - __pthread_mutex_init (mutex, NULL); + pthread_mutex::init (mutex, NULL); if (!pthread_mutex::isGoodObject (mutex)) return EINVAL; (*mutex)->UnLock (); @@ -2325,7 +2359,7 @@ __pthread_mutex_setprioceiling (pthread_mutex_t *mutex, int prioceiling, { pthread_mutex_t *themutex = mutex; if (pthread_mutex::isGoodInitializer (mutex)) - __pthread_mutex_init (mutex, NULL); + pthread_mutex::init (mutex, NULL); if (!pthread_mutex::isGoodObject (themutex)) return EINVAL; return ENOSYS; diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h index 0ac429e148..77a461ffd8 100644 --- a/winsup/cygwin/thread.h +++ b/winsup/cygwin/thread.h @@ -291,6 +291,9 @@ public: static bool isGoodObject(pthread_mutex_t const *); static bool isGoodInitializer(pthread_mutex_t const *); static bool isGoodInitializerOrObject(pthread_mutex_t const *); + static void initMutex (); + static int init (pthread_mutex_t *, const pthread_mutexattr_t *); + CRITICAL_SECTION criticalsection; HANDLE win32_obj_id; LONG condwaits; @@ -305,6 +308,8 @@ public: pthread_mutex (pthread_mutexattr * = NULL); pthread_mutex (pthread_mutex_t *, pthread_mutexattr *); ~pthread_mutex (); +private: + static HANDLE mutexInitializationLock; }; class pthread:public verifyable_object @@ -561,7 +566,6 @@ int __pthread_sigmask (int operation, const sigset_t * set, int __pthread_equal (pthread_t * t1, pthread_t * t2); /* Mutexes */ -int __pthread_mutex_init (pthread_mutex_t *, const pthread_mutexattr_t *); int __pthread_mutex_lock (pthread_mutex_t *); int __pthread_mutex_trylock (pthread_mutex_t *); int __pthread_mutex_unlock (pthread_mutex_t *);