2002-09-30 Robert Collins <rbtcollins@hotmail.com>

* 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.
This commit is contained in:
Robert Collins 2002-09-29 23:47:45 +00:00
parent b2c3ba8ad0
commit eb208df05a
4 changed files with 73 additions and 14 deletions

View File

@ -1,3 +1,24 @@
2002-09-30 Robert Collins <rbtcollins@hotmail.com>
* 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 <cgf@redhat.com> 2002-09-28 Christopher Faylor <cgf@redhat.com>
* thread.h (verifyable_object:~verifyable_object): Make virtual. * thread.h (verifyable_object:~verifyable_object): Make virtual.

View File

@ -234,7 +234,7 @@ pthread_equal (pthread_t t1, pthread_t t2)
int int
pthread_mutex_init (pthread_mutex_t * mutex, const pthread_mutexattr_t * attr) 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 int

View File

@ -190,6 +190,7 @@ MTinterface::Init (int forked)
threadcount = 1; /*1 current thread when Init occurs.*/ threadcount = 1; /*1 current thread when Init occurs.*/
pthread::initMainThread (&mainthread, myself->hProcess); pthread::initMainThread (&mainthread, myself->hProcess);
pthread_mutex::initMutex ();
if (forked) if (forked)
return; return;
@ -1097,6 +1098,21 @@ pthread_mutex::isGoodInitializerOrObject (pthread_mutex_t const *mutex)
return true; 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) pthread_mutex::pthread_mutex (pthread_mutexattr *attr):verifyable_object (PTHREAD_MUTEX_MAGIC)
{ {
/*attr checked in the C call */ /*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. // broadcast occurs - we miss the broadcast. the functions aren't split properly.
int rv; int rv;
pthread_mutex **themutex = NULL; pthread_mutex **themutex = NULL;
if (*mutex == PTHREAD_MUTEX_INITIALIZER) if (pthread_mutex::isGoodInitializer (mutex))
__pthread_mutex_init (mutex, NULL); pthread_mutex::init (mutex, NULL);
themutex = mutex; themutex = mutex;
if (pthread_cond::isGoodInitializer (cond)) if (pthread_cond::isGoodInitializer (cond))
__pthread_cond_init (cond, NULL); __pthread_cond_init (cond, NULL);
@ -2109,7 +2125,8 @@ pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex)
int int
__pthread_condattr_init (pthread_condattr_t *condattr) __pthread_condattr_init (pthread_condattr_t *condattr)
{ {
/* FIXME: we dereference blindly! */ if (check_valid_pointer (condattr))
return EINVAL;
*condattr = new pthread_condattr; *condattr = new pthread_condattr;
if (!pthread_condattr::isGoodObject (condattr)) if (!pthread_condattr::isGoodObject (condattr))
{ {
@ -2210,23 +2227,37 @@ __pthread_equal (pthread_t *t1, pthread_t *t2)
*/ */
int int
__pthread_mutex_init (pthread_mutex_t *mutex, pthread_mutex::init (pthread_mutex_t *mutex,
const pthread_mutexattr_t *attr) const pthread_mutexattr_t *attr)
{ {
if (attr && !pthread_mutexattr::isGoodObject (attr) || check_valid_pointer (mutex)) if (attr && !pthread_mutexattr::isGoodObject (attr) || check_valid_pointer (mutex))
return EINVAL; 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 */ /* FIXME: bugfix: we should check *mutex being a valid address */
if (pthread_mutex::isGoodObject (mutex)) if (isGoodObject (mutex))
return EBUSY; {
if (! ReleaseMutex(mutexInitializationLock))
system_printf ("Recieved a unexpected result releasing mutexInitializationLock %d\n", GetLastError());
return EBUSY;
}
*mutex = new pthread_mutex (attr ? (*attr) : NULL); *mutex = new pthread_mutex (attr ? (*attr) : NULL);
if (!pthread_mutex::isGoodObject (mutex)) if (!isGoodObject (mutex))
{ {
delete (*mutex); delete (*mutex);
*mutex = NULL; *mutex = NULL;
if (! ReleaseMutex(mutexInitializationLock))
system_printf ("Recieved a unexpected result releasing mutexInitializationLock %d\n", GetLastError());
return EAGAIN; return EAGAIN;
} }
if (! ReleaseMutex(mutexInitializationLock))
system_printf ("Recieved a unexpected result releasing mutexInitializationLock %d\n", GetLastError());
return 0; return 0;
} }
@ -2236,7 +2267,7 @@ __pthread_mutex_getprioceiling (const pthread_mutex_t *mutex,
{ {
pthread_mutex_t *themutex = (pthread_mutex_t *) mutex; pthread_mutex_t *themutex = (pthread_mutex_t *) mutex;
if (pthread_mutex::isGoodInitializer (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)) if (!pthread_mutex::isGoodObject (themutex))
return EINVAL; return EINVAL;
/*We don't define _POSIX_THREAD_PRIO_PROTECT because we do't currently support /*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: case VALID_STATIC_OBJECT:
if (pthread_mutex::isGoodInitializer (mutex)) if (pthread_mutex::isGoodInitializer (mutex))
{ {
int rv = __pthread_mutex_init (mutex, NULL); int rv = pthread_mutex::init (mutex, NULL);
if (rv) if (rv)
return rv; return rv;
} }
/* No else needed. If it's been initialized while we waited,
* we can just attempt to lock it
*/
break; break;
case VALID_OBJECT: case VALID_OBJECT:
break; break;
@ -2283,7 +2317,7 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
{ {
pthread_mutex_t *themutex = mutex; pthread_mutex_t *themutex = mutex;
if (pthread_mutex::isGoodInitializer (mutex)) if (pthread_mutex::isGoodInitializer (mutex))
__pthread_mutex_init (mutex, NULL); pthread_mutex::init (mutex, NULL);
if (!pthread_mutex::isGoodObject (themutex)) if (!pthread_mutex::isGoodObject (themutex))
return EINVAL; return EINVAL;
if ((*themutex)->TryLock ()) if ((*themutex)->TryLock ())
@ -2295,7 +2329,7 @@ int
__pthread_mutex_unlock (pthread_mutex_t *mutex) __pthread_mutex_unlock (pthread_mutex_t *mutex)
{ {
if (pthread_mutex::isGoodInitializer (mutex)) if (pthread_mutex::isGoodInitializer (mutex))
__pthread_mutex_init (mutex, NULL); pthread_mutex::init (mutex, NULL);
if (!pthread_mutex::isGoodObject (mutex)) if (!pthread_mutex::isGoodObject (mutex))
return EINVAL; return EINVAL;
(*mutex)->UnLock (); (*mutex)->UnLock ();
@ -2325,7 +2359,7 @@ __pthread_mutex_setprioceiling (pthread_mutex_t *mutex, int prioceiling,
{ {
pthread_mutex_t *themutex = mutex; pthread_mutex_t *themutex = mutex;
if (pthread_mutex::isGoodInitializer (mutex)) if (pthread_mutex::isGoodInitializer (mutex))
__pthread_mutex_init (mutex, NULL); pthread_mutex::init (mutex, NULL);
if (!pthread_mutex::isGoodObject (themutex)) if (!pthread_mutex::isGoodObject (themutex))
return EINVAL; return EINVAL;
return ENOSYS; return ENOSYS;

View File

@ -291,6 +291,9 @@ public:
static bool isGoodObject(pthread_mutex_t const *); static bool isGoodObject(pthread_mutex_t const *);
static bool isGoodInitializer(pthread_mutex_t const *); static bool isGoodInitializer(pthread_mutex_t const *);
static bool isGoodInitializerOrObject(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; CRITICAL_SECTION criticalsection;
HANDLE win32_obj_id; HANDLE win32_obj_id;
LONG condwaits; LONG condwaits;
@ -305,6 +308,8 @@ public:
pthread_mutex (pthread_mutexattr * = NULL); pthread_mutex (pthread_mutexattr * = NULL);
pthread_mutex (pthread_mutex_t *, pthread_mutexattr *); pthread_mutex (pthread_mutex_t *, pthread_mutexattr *);
~pthread_mutex (); ~pthread_mutex ();
private:
static HANDLE mutexInitializationLock;
}; };
class pthread:public verifyable_object 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); int __pthread_equal (pthread_t * t1, pthread_t * t2);
/* Mutexes */ /* Mutexes */
int __pthread_mutex_init (pthread_mutex_t *, const pthread_mutexattr_t *);
int __pthread_mutex_lock (pthread_mutex_t *); int __pthread_mutex_lock (pthread_mutex_t *);
int __pthread_mutex_trylock (pthread_mutex_t *); int __pthread_mutex_trylock (pthread_mutex_t *);
int __pthread_mutex_unlock (pthread_mutex_t *); int __pthread_mutex_unlock (pthread_mutex_t *);