2002-03-19  Thomas Pfaff  <[EMAIL PROTECTED]>

        * thread.h (class List): Move inline code inside class
        declaration.
        (List::forEach): Change callback parameter to member function
        pointer.
        (pthread_keys::fixup_before_fork): Change to inline. Use
        List::forEach to fixup keys.
        (pthread_keys::fixup_after_fork): Ditto.
        (pthread_keys::runAllDestructors): Ditto.
        (pthread_key::saveAKey): Remove.
        (pthread_key::restoreAKey): Ditto.
        (pthread_key::destroyAKey): Ditto.
        (pthread_key::run_destructor): Rename to runDestructor.
        (pthread_mutex::fixup_after_fork): Change to inline. Use
        List::forEach to fixup mutexes after a fork.
        (pthread_mutex::FixupAfterFork): New method.
        (pthread_mutex::mutexes): New member.
        (pthread_cond::fixup_after_fork): Change to inline. Use
        List::forEach to fixup conds after a fork.
        (pthread_cond::FixupAfterFork): New method.
        (pthread_cond::conds): New member.
        (pthread_rwlock::fixup_after_fork): Change to inline. Use
        List::forEach to fixup rwlocks after a fork.
        (pthread_rwlock::FixupAfterFork): New method.
        (pthread_rwlock::rwlocks): New member.
        (semaphore::fixup_after_fork): Change to inline. Use
        List::forEach to fixup mutexes after a fork.
        (semaphore::FixupAfterFork): New method.
        (semaphore::semaphores): New member.
        (MTinterface::mutexs): Remove.
        (MTinterface::conds): Ditto.
        (MTinterface::rwlocks): Ditto.
        (MTinterface::semaphores): Ditto.

        * thread.cc (MTinterface::fixup_after_fork): Change
        fixup_after_fork for pthread objects.
        (semaphore::conds): Instantiate.
        (pthread_cond::pthread_cond): Use List::Insert rather than
        custom list code.
        (pthread_cond::~pthread_cond): Use List::Remove rather than
        custom list code.
        (pthread_cond::fixup_after_fork): Rename to FixupAfterFork.
        (pthread_rwlock::rwlocks): Instantiate.
        (pthread_rwlock::pthread_crwlock): Use List::Insert rather than
        custom list code.
        (pthread_rwlock::~pthread_rwlock): Use List::Remove rather than
        custom list code.
        (pthread_rwlock::fixup_after_fork): Rename to FixupAfterFork.
        (pthread_key::saveAKey): Remove.
        (pthread_key::fixup_before_fork): Ditto.
        (pthread_key::restoreAKey): Ditto.
        (pthread_key::fixup_after_fork): Ditto.
        (pthread_key::destroyAKey): Ditto.
        (pthread_key::runAllDestructors): Ditto.
        (pthread_key::run_destructor): Rename to runDestructor.
        (pthread_mutex::mutexes): Instantiate.
        (pthread_mutex::pthread_mutex): Use List::Insert rather than
        custom list code.
        (pthread_mutex::~pthread_mutex): Use List::Remove rather than
        custom list code.
        (pthread_mutex::fixup_after_fork): Rename to FixupAfterFork.
        (semaphore::conds): Instantiate.
        (semaphore::semaphore): Use List::Insert rather than custom list
        code.
        (semaphores::~semaphore): Use List::Remove rather than custom
        list code.
        (semaphore::fixup_after_fork): Rename to FixupAfterFork.
diff -urp src.old/winsup/cygwin/thread.cc src/winsup/cygwin/thread.cc
--- src.old/winsup/cygwin/thread.cc     2003-03-19 14:31:49.000000000 +0100
+++ src/winsup/cygwin/thread.cc 2003-03-19 13:20:11.000000000 +0100
@@ -217,34 +217,10 @@ MTinterface::fixup_after_fork (void)
   threadcount = 1;
   pthread::initMainThread (true);
 
-  pthread_mutex *mutex = mutexs;
-  debug_printf ("mutexs is %x",mutexs);
-  while (mutex)
-    {
-      mutex->fixup_after_fork ();
-      mutex = mutex->next;
-    }
-  pthread_cond *cond = conds;
-  debug_printf ("conds is %x",conds);
-  while (cond)
-    {
-      cond->fixup_after_fork ();
-      cond = cond->next;
-    }
-  pthread_rwlock *rwlock = rwlocks;
-  debug_printf ("rwlocks is %x",rwlocks);
-  while (rwlock)
-    {
-      rwlock->fixup_after_fork ();
-      rwlock = rwlock->next;
-    }
-  semaphore *sem = semaphores;
-  debug_printf ("semaphores is %x",semaphores);
-  while (sem)
-    {
-      sem->fixup_after_fork ();
-      sem = sem->next;
-    }
+  pthread_mutex::fixup_after_fork ();
+  pthread_cond::fixup_after_fork ();
+  pthread_rwlock::fixup_after_fork ();
+  semaphore::fixup_after_fork ();
 }
 
 /* pthread calls */
@@ -807,6 +783,8 @@ pthread_condattr::~pthread_condattr ()
 {
 }
 
+List<pthread_cond> pthread_cond::conds;
+
 /* This is used for cond creation protection within a single process only */
 nativeMutex NO_COPY pthread_cond::condInitializationLock;
 
@@ -862,8 +840,7 @@ pthread_cond::pthread_cond (pthread_cond
       return;
     }
 
-  /* threadsafe addition is easy */
-  next = (pthread_cond *) InterlockedExchangePointer (&MT_INTERFACE->conds, this);
+  conds.Insert (this);
 }
 
 pthread_cond::~pthread_cond ()
@@ -871,17 +848,7 @@ pthread_cond::~pthread_cond ()
   if (semWait)
     CloseHandle (semWait);
 
-  /* I'm not 100% sure the next bit is threadsafe. I think it is... */
-  if (MT_INTERFACE->conds == this)
-    InterlockedExchangePointer (&MT_INTERFACE->conds, this->next);
-  else
-    {
-      pthread_cond *tempcond = MT_INTERFACE->conds;
-      while (tempcond->next && tempcond->next != this)
-       tempcond = tempcond->next;
-      /* but there may be a race between the loop above and this statement */
-      InterlockedExchangePointer (&tempcond->next, this->next);
-    }
+  conds.Remove (this);
 }
 
 void
@@ -992,7 +959,7 @@ pthread_cond::Wait (pthread_mutex_t mute
 }
 
 void
-pthread_cond::fixup_after_fork ()
+pthread_cond::FixupAfterFork ()
 {
   waiting = pending = 0;
   mtxCond = NULL;
@@ -1003,7 +970,7 @@ pthread_cond::fixup_after_fork ()
 
   semWait = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL);
   if (!semWait)
-    api_fatal ("pthread_cond::fixup_after_fork () failed to recreate win32 
semaphore");
+    api_fatal ("pthread_cond::FixupAfterFork () failed to recreate win32 semaphore");
 }
 
 bool
@@ -1023,6 +990,8 @@ pthread_rwlockattr::~pthread_rwlockattr 
 {
 }
 
+List<pthread_rwlock> pthread_rwlock::rwlocks;
+
 /* This is used for rwlock creation protection within a single process only */
 nativeMutex NO_COPY pthread_rwlock::rwlockInitializationLock;
 
@@ -1078,23 +1047,12 @@ pthread_rwlock::pthread_rwlock (pthread_
     }
 
 
-  /* threadsafe addition is easy */
-  next = (pthread_rwlock *) InterlockedExchangePointer (&MT_INTERFACE->rwlocks, this);
+  rwlocks.Insert (this);
 }
 
 pthread_rwlock::~pthread_rwlock ()
 {
-  /* I'm not 100% sure the next bit is threadsafe. I think it is... */
-  if (MT_INTERFACE->rwlocks == this)
-    InterlockedExchangePointer (&MT_INTERFACE->rwlocks, this->next);
-  else
-    {
-      pthread_rwlock *temprwlock = MT_INTERFACE->rwlocks;
-      while (temprwlock->next && temprwlock->next != this)
-       temprwlock = temprwlock->next;
-      /* but there may be a race between the loop above and this statement */
-      InterlockedExchangePointer (&temprwlock->next, this->next);
-    }
+  rwlocks.Remove (this);
 }
 
 int
@@ -1315,7 +1273,7 @@ pthread_rwlock::WrLockCleanup (void *arg
 }
 
 void
-pthread_rwlock::fixup_after_fork ()
+pthread_rwlock::FixupAfterFork ()
 {
   pthread_t self = pthread::self ();
   struct RWLOCK_READER **temp = &readers;
@@ -1346,42 +1304,6 @@ pthread_rwlock::fixup_after_fork ()
 /* This stores pthread_key information across fork() boundaries */
 List<pthread_key> pthread_key::keys;
 
-void
-pthread_key::saveAKey (pthread_key *key)
-{
-  key->saveKeyToBuffer ();
-}
-
-void
-pthread_key::fixup_before_fork ()
-{
-  keys.forEach (saveAKey);
-}
-
-void
-pthread_key::restoreAKey (pthread_key *key)
-{
-  key->recreateKeyFromBuffer ();
-}
-
-void
-pthread_key::fixup_after_fork ()
-{
-  keys.forEach (restoreAKey);
-}
-
-void
-pthread_key::destroyAKey (pthread_key *key)
-{
-  key->run_destructor ();
-}
-
-void
-pthread_key::runAllDestructors ()
-{
-  keys.forEach (destroyAKey);
-}
-
 bool
 pthread_key::isGoodObject (pthread_key_t const *key)
 {
@@ -1445,7 +1367,7 @@ pthread_key::recreateKeyFromBuffer ()
 }
 
 void
-pthread_key::run_destructor ()
+pthread_key::runDestructor ()
 {
   if (destructor)
     {
@@ -1528,6 +1450,8 @@ pthread_mutex::canBeUnlocked (pthread_mu
   return (pthread::equal ((*mutex)->owner, self)) && 1 == (*mutex)->recursion_counter;
 }
 
+List<pthread_mutex> pthread_mutex::mutexes;
+
 /* This is used for mutex creation protection within a single process only */
 nativeMutex NO_COPY pthread_mutex::mutexInitializationLock;
 
@@ -1567,8 +1491,7 @@ pthread_mutex::pthread_mutex (pthread_mu
       type = attr->mutextype;
     }
 
-  /* threadsafe addition is easy */
-  next = (pthread_mutex *) InterlockedExchangePointer (&MT_INTERFACE->mutexs, this);
+  mutexes.Insert (this);
 }
 
 pthread_mutex::~pthread_mutex ()
@@ -1576,19 +1499,7 @@ pthread_mutex::~pthread_mutex ()
   if (win32_obj_id)
     CloseHandle (win32_obj_id);
 
-  /* I'm not 100% sure the next bit is threadsafe. I think it is... */
-  if (MT_INTERFACE->mutexs == this)
-    /* TODO: printf an error if the return value != this */
-    InterlockedExchangePointer (&MT_INTERFACE->mutexs, next);
-  else
-    {
-      pthread_mutex *tempmutex = MT_INTERFACE->mutexs;
-      while (tempmutex->next && tempmutex->next != this)
-       tempmutex = tempmutex->next;
-      /* but there may be a race between the loop above and this statement */
-      /* TODO: printf an error if the return value != this */
-      InterlockedExchangePointer (&tempmutex->next, this->next);
-    }
+  mutexes.Remove (this);
 }
 
 int
@@ -1665,11 +1576,11 @@ pthread_mutex::_Destroy (pthread_t self)
 }
 
 void
-pthread_mutex::fixup_after_fork ()
+pthread_mutex::FixupAfterFork ()
 {
-  debug_printf ("mutex %x in fixup_after_fork", this);
+  debug_printf ("mutex %x in FixupAfterFork", this);
   if (pshared != PTHREAD_PROCESS_PRIVATE)
-    api_fatal ("pthread_mutex::fixup_after_fork () doesn'tunderstand PROCESS_SHARED 
mutex's");
+    api_fatal ("pthread_mutex::FixupAfterFork () doesn'tunderstand PROCESS_SHARED 
mutex's");
 
   if (NULL == owner)
     /* mutex has no owner, reset to initial */
@@ -1680,7 +1591,7 @@ pthread_mutex::fixup_after_fork ()
 
   win32_obj_id = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL);
   if (!win32_obj_id)
-    api_fatal ("pthread_mutex::fixup_after_fork () failed to recreate win32 semaphore 
for mutex");
+    api_fatal ("pthread_mutex::FixupAfterFork () failed to recreate win32 semaphore 
for mutex");
 
   condwaits = 0;
 }
@@ -1702,6 +1613,8 @@ pthread_mutexattr::~pthread_mutexattr ()
 {
 }
 
+List<semaphore> semaphore::semaphores;
+
 semaphore::semaphore (int pshared, unsigned int value):verifyable_object (SEM_MAGIC)
 {
   this->win32_obj_id = ::CreateSemaphore (&sec_none_nih, value, LONG_MAX,
@@ -1710,25 +1623,16 @@ semaphore::semaphore (int pshared, unsig
     magic = 0;
   this->shared = pshared;
   currentvalue = value;
-  /* threadsafe addition is easy */
-  next = (semaphore *) InterlockedExchangePointer (&MT_INTERFACE->semaphores, this);
+
+  semaphores.Insert (this);
 }
 
 semaphore::~semaphore ()
 {
   if (win32_obj_id)
     CloseHandle (win32_obj_id);
-  /* I'm not 100% sure the next bit is threadsafe. I think it is... */
-  if (MT_INTERFACE->semaphores == this)
-    InterlockedExchangePointer (&MT_INTERFACE->semaphores, this->next);
-  else
-    {
-      semaphore *tempsem = MT_INTERFACE->semaphores;
-      while (tempsem->next && tempsem->next != this)
-       tempsem = tempsem->next;
-      /* but there may be a race between the loop above and this statement */
-      InterlockedExchangePointer (&tempsem->next, this->next);
-    }
+
+  semaphores.Remove (this);
 }
 
 void
@@ -1769,9 +1673,9 @@ semaphore::Wait ()
 }
 
 void
-semaphore::fixup_after_fork ()
+semaphore::FixupAfterFork ()
 {
-  debug_printf ("sem %x in fixup_after_fork", this);
+  debug_printf ("sem %x in FixupAfterFork", this);
   if (shared != PTHREAD_PROCESS_PRIVATE)
     api_fatal ("doesn't understand PROCESS_SHARED semaphores variables");
   /* FIXME: duplicate code here and in the constructor. */
@@ -2913,7 +2817,7 @@ pthread_mutex_getprioceiling (const pthr
   return ENOSYS;
 }
 
-int
+extern "C" int
 pthread_mutex_lock (pthread_mutex_t *mutex)
 {
   pthread_mutex_t *themutex = mutex;
diff -urp src.old/winsup/cygwin/thread.h src/winsup/cygwin/thread.h
--- src.old/winsup/cygwin/thread.h      2003-03-19 14:31:49.000000000 +0100
+++ src/winsup/cygwin/thread.h  2003-03-19 14:36:03.000000000 +0100
@@ -189,14 +189,50 @@ typedef enum
 verifyable_object_state verifyable_object_isvalid (void const *, long);
 verifyable_object_state verifyable_object_isvalid (void const *, long, void *);
 
-/* interface */
 template <class ListNode> class List {
 public:
-  List();
-  void Insert (ListNode *aNode);
-  ListNode *Remove ( ListNode *aNode);
-  ListNode *Pop ();
-  void forEach (void (*)(ListNode *aNode));
+  List() : head(NULL)
+  {
+  }
+
+  void Insert (ListNode *aNode)
+  {
+    if (!aNode)
+      return;
+    aNode->next = (ListNode *) InterlockedExchangePointer (&head, aNode);
+  }
+
+  ListNode *Remove ( ListNode *aNode)
+  {
+    if (!aNode || !head)
+      return NULL;
+    if (aNode == head)
+      return Pop ();
+
+    ListNode *resultPrev = head;
+    while (resultPrev && resultPrev->next && !(aNode == resultPrev->next))
+      resultPrev = resultPrev->next;
+    if (resultPrev)
+      return (ListNode *)InterlockedExchangePointer (&resultPrev->next, 
resultPrev->next->next);
+    return NULL;
+  }
+
+  ListNode *Pop ()
+  {
+    return (ListNode *) InterlockedExchangePointer (&head, head->next);
+  }
+
+  /* poor mans generic programming. */
+  void forEach (void (ListNode::*callback) ())
+  {
+    ListNode *aNode = head;
+    while (aNode)
+      {
+        (aNode->*callback) ();
+        aNode = aNode->next;
+      }
+  }
+
 protected:
   ListNode *head;
 };
@@ -205,8 +241,6 @@ class pthread_key:public verifyable_obje
 {
 public:
   static bool isGoodObject (pthread_key_t const *);
-  static void runAllDestructors ();
-
   DWORD dwTlsIndex;
 
   int set (const void *);
@@ -214,69 +248,32 @@ public:
 
   pthread_key (void (*)(void *));
   ~pthread_key ();
-  static void fixup_before_fork();
-  static void fixup_after_fork();
+  static void fixup_before_fork()
+  {
+    keys.forEach (&pthread_key::saveKeyToBuffer);
+  }
+
+  static void fixup_after_fork()
+  {
+    keys.forEach (&pthread_key::recreateKeyFromBuffer);
+  }
+
+  static void runAllDestructors ()
+  {
+    keys.forEach (&pthread_key::runDestructor);
+  }
 
   /* List support calls */
   class pthread_key *next;
 private:
-  // lists of objects. USE THREADSAFE INSERTS AND DELETES.
   static List<pthread_key> keys;
-  static void saveAKey (pthread_key *);
-  static void restoreAKey (pthread_key *);
-  static void destroyAKey (pthread_key *);
   void saveKeyToBuffer ();
   void recreateKeyFromBuffer ();
   void (*destructor) (void *);
-  void run_destructor ();
+  void runDestructor ();
   void *fork_buf;
 };
 
-/* implementation */
-template <class ListNode>
-List<ListNode>::List<ListNode> () : head(NULL)
-{
-}
-template <class ListNode> void
-List<ListNode>::Insert (ListNode *aNode)
-{
-  if (!aNode)
-  return;
-  aNode->next = (ListNode *) InterlockedExchangePointer (&head, aNode);
-}
-template <class ListNode> ListNode *
-List<ListNode>::Remove ( ListNode *aNode)
-{
-  if (!aNode)
-  return NULL;
-  if (!head)
-  return NULL;
-  if (aNode == head)
-  return Pop ();
-  ListNode *resultPrev = head;
-  while (resultPrev && resultPrev->next && !(aNode == resultPrev->next))
-  resultPrev = resultPrev->next;
-  if (resultPrev)
-  return (ListNode *)InterlockedExchangePointer (&resultPrev->next, 
resultPrev->next->next);
-  return NULL;
-}
-template <class ListNode> ListNode *
-List<ListNode>::Pop ()
-{
-  return (ListNode *) InterlockedExchangePointer (&head, head->next);
-}
-/* poor mans generic programming. */
-template <class ListNode> void
-List<ListNode>::forEach (void (*callback)(ListNode *))
-{
-  ListNode *aNode = head;
-  while (aNode)
-  {
-    callback (aNode);
-    aNode = aNode->next;
-  }
-}
-
 class pthread_attr:public verifyable_object
 {
 public:
@@ -319,7 +316,6 @@ public:
   pthread_t owner;
   int type;
   int pshared;
-  class pthread_mutex * next;
 
   pthread_t GetPthreadSelf () const
   {
@@ -358,18 +354,25 @@ public:
     return 0;
   }
 
-  void fixup_after_fork ();
-
   pthread_mutex (pthread_mutexattr * = NULL);
   pthread_mutex (pthread_mutex_t *, pthread_mutexattr *);
   ~pthread_mutex ();
 
+  class pthread_mutex * next;
+  static void fixup_after_fork ()
+  {
+    mutexes.forEach (&pthread_mutex::FixupAfterFork);
+  }
+
+  void FixupAfterFork ();
+
 private:
   int _Lock (pthread_t self);
   int _TryLock (pthread_t self);
   int _UnLock (pthread_t self);
   int _Destroy (pthread_t self);
 
+  static List<pthread_mutex> mutexes;
   static nativeMutex mutexInitializationLock;
 };
 
@@ -511,16 +514,22 @@ public:
 
   pthread_mutex_t mtxCond;
 
-  class pthread_cond * next;
-
   void UnBlock (const bool all);
   int Wait (pthread_mutex_t mutex, DWORD dwMilliseconds = INFINITE);
-  void fixup_after_fork ();
 
   pthread_cond (pthread_condattr *);
   ~pthread_cond ();
 
+  class pthread_cond * next;
+  static void fixup_after_fork ()
+  {
+    conds.forEach (&pthread_cond::FixupAfterFork);
+  }
+
+  void FixupAfterFork ();
+
 private:
+  static List<pthread_cond> conds;
   static nativeMutex condInitializationLock;
 };
 
@@ -567,14 +576,20 @@ public:
   pthread_cond condReaders;
   pthread_cond condWriters;
 
-  class pthread_rwlock * next;
-
-  void fixup_after_fork ();
-
   pthread_rwlock (pthread_rwlockattr *);
   ~pthread_rwlock ();
 
+  class pthread_rwlock * next;
+  static void fixup_after_fork ()
+  {
+    rwlocks.forEach (&pthread_rwlock::FixupAfterFork);
+  }
+
+  void FixupAfterFork ();
+
 private:
+  static List<pthread_rwlock> rwlocks;
+
   void addReader (struct RWLOCK_READER *rd);
   void removeReader (struct RWLOCK_READER *rd);
   struct RWLOCK_READER *lookupReader (pthread_t thread);
@@ -605,16 +620,25 @@ public:
   static int post (sem_t * sem);
 
   HANDLE win32_obj_id;
-  class semaphore * next;
   int shared;
   long currentvalue;
   void Wait ();
   void Post ();
   int TryWait ();
-  void fixup_after_fork ();
 
   semaphore (int, unsigned int);
   ~semaphore ();
+
+  class semaphore * next;
+  static void fixup_after_fork ()
+  {
+    semaphores.forEach (&semaphore::FixupAfterFork);
+  }
+
+  void FixupAfterFork ();
+
+private:
+  static List<semaphore> semaphores;
 };
 
 class callback
@@ -639,12 +663,6 @@ public:
   callback *pthread_child;
   callback *pthread_parent;
 
-  // lists of pthread objects. USE THREADSAFE INSERTS AND DELETES.
-  class pthread_mutex * mutexs;
-  class pthread_cond  * conds;
-  class pthread_rwlock * rwlocks;
-  class semaphore     * semaphores;
-
   pthread_key reent_key;
   pthread_key thread_self_key;
 
@@ -655,7 +673,6 @@ public:
   MTinterface () :
     concurrency (0), threadcount (1),
     pthread_prepare (NULL), pthread_child (NULL), pthread_parent (NULL),
-    mutexs (NULL), conds (NULL), rwlocks (NULL), semaphores (NULL),
     reent_key (NULL), thread_self_key (NULL)
   {
   }

Reply via email to