OSDN Git Service

2002-09-30 Robert Collins <rbtcollins@hotmail.com>
authorrbcollins <rbcollins>
Sun, 29 Sep 2002 23:47:45 +0000 (23:47 +0000)
committerrbcollins <rbcollins>
Sun, 29 Sep 2002 23:47:45 +0000 (23:47 +0000)
        * 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.

winsup/cygwin/ChangeLog
winsup/cygwin/pthread.cc
winsup/cygwin/thread.cc
winsup/cygwin/thread.h

index 5f28030..970291a 100644 (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>
 
        * thread.h (verifyable_object:~verifyable_object): Make virtual.
index cfa0c28..30d0480 100644 (file)
@@ -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
index 6b05cff..ca992d3 100644 (file)
@@ -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;
index 0ac429e..77a461f 100644 (file)
@@ -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 *);