Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog21
-rw-r--r--winsup/cygwin/pthread.cc2
-rw-r--r--winsup/cygwin/thread.cc58
-rw-r--r--winsup/cygwin/thread.h6
4 files changed, 73 insertions, 14 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 5f280307a..970291ac3 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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>
* thread.h (verifyable_object:~verifyable_object): Make virtual.
diff --git a/winsup/cygwin/pthread.cc b/winsup/cygwin/pthread.cc
index cfa0c28ea..30d048047 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 6b05cffb2..ca992d3d2 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 0ac429e14..77a461ffd 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 *);