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:
parent
b2c3ba8ad0
commit
eb208df05a
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 *);
|
||||||
|
|
Loading…
Reference in New Issue