OSDN Git Service

Rename native_mutex to fast_mutex throughout.
authortpfaff <tpfaff>
Fri, 24 Oct 2003 19:34:47 +0000 (19:34 +0000)
committertpfaff <tpfaff>
Fri, 24 Oct 2003 19:34:47 +0000 (19:34 +0000)
Rename pthread_key::save_key_to_buffer to
pthread_key::_fixup_before_fork throughout.
Rename pthread_key::recreate_key_from_buffer to
pthread_key::_fixup_after_fork throughout.

* thread.cc (native_mutex::init): Remove.
(native_mutex::lock): Ditto.
(native_mutex::unlock): Ditto.
(pthread::push_cleanup_handler): InterlockedExchangePointer
is not needed here.
(pthread_rwlock::pthread_rwlock): Initialize readers list mutex.
(pthread_rwlock::add_reader): Add reader via List_insert.
(pthread_rwlock::lookup_reader): Lock list while walking through.
(pthread_cond::init): Locking the init mutex is now void.
(pthread_rwlock::init): Ditto.
(pthread_mutex::init): Ditto.
* thread.h: Include security.h.
(fast_mutex): New class. Replacement for native_mutex.
(List_insert): New template function.
(List_remove): Ditto.
(List::List): Initialize synchronising mutex.
(List::fixup_after_fork): New method.
(List::insert): Add node via List_insert.
(List::remove): Remove node via List_remove.
(List::pop): Remove.
(List::for_each): Lock list while walking through.
(List::mx_init): New method.
(pthread_mutex::fixup_after_fork): Fixup mutex list after fork.
(pthread::fixup_after_fork): Ditto.
(pthread_conds::fixup_after_fork): Ditto.
(pthread_rwlock::fixup_after_fork): Ditto.
(semaphore::fixup_after_fork): Ditto.
(pthread_rwlock::readers_mx): New member.

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

index aea0893..d7006ec 100644 (file)
@@ -1,3 +1,40 @@
+2003-10-24  Thomas Pfaff  <tpfaff@gmx.net>
+
+       Rename native_mutex to fast_mutex throughout.
+       Rename pthread_key::save_key_to_buffer to
+       pthread_key::_fixup_before_fork throughout.
+       Rename pthread_key::recreate_key_from_buffer to
+       pthread_key::_fixup_after_fork throughout.
+
+       * thread.cc (native_mutex::init): Remove.
+       (native_mutex::lock): Ditto.
+       (native_mutex::unlock): Ditto.
+       (pthread::push_cleanup_handler): InterlockedExchangePointer
+       is not needed here.
+       (pthread_rwlock::pthread_rwlock): Initialize readers list mutex.
+       (pthread_rwlock::add_reader): Add reader via List_insert.
+       (pthread_rwlock::lookup_reader): Lock list while walking through.
+       (pthread_cond::init): Locking the init mutex is now void.
+       (pthread_rwlock::init): Ditto.
+       (pthread_mutex::init): Ditto.
+       * thread.h: Include security.h.
+       (fast_mutex): New class. Replacement for native_mutex.
+       (List_insert): New template function.
+       (List_remove): Ditto.
+       (List::List): Initialize synchronising mutex.
+       (List::fixup_after_fork): New method.
+       (List::insert): Add node via List_insert.
+       (List::remove): Remove node via List_remove.
+       (List::pop): Remove.
+       (List::for_each): Lock list while walking through.
+       (List::mx_init): New method.
+       (pthread_mutex::fixup_after_fork): Fixup mutex list after fork.
+       (pthread::fixup_after_fork): Ditto.
+       (pthread_conds::fixup_after_fork): Ditto.
+       (pthread_rwlock::fixup_after_fork): Ditto.
+       (semaphore::fixup_after_fork): Ditto.
+       (pthread_rwlock::readers_mx): New member.
+
 2003-10-24  Brian Ford  <ford@vss.fsi.com>
 
        * fhandler.cc (fhandler_base::fcntl): Don't clobber O_APPEND when
index e108244..bf5f0da 100644 (file)
@@ -79,37 +79,6 @@ _reent_winsup ()
   return _r->_winsup;
 }
 
-bool
-native_mutex::init ()
-{
-  theHandle = CreateMutex (&sec_none_nih, FALSE, NULL);
-  if (!theHandle)
-    {
-      debug_printf ("CreateMutex failed. %E");
-      return false;
-    }
-  return true;
-}
-
-bool
-native_mutex::lock ()
-{
-  DWORD waitResult = WaitForSingleObject (theHandle, INFINITE);
-  if (waitResult != WAIT_OBJECT_0)
-    {
-      system_printf ("Received unexpected wait result %d on handle %p, %E", waitResult, theHandle);
-      return false;
-    }
-  return true;
-}
-
-void
-native_mutex::unlock ()
-{
-  if (!ReleaseMutex (theHandle))
-    system_printf ("Received a unexpected result releasing mutex. %E");
-}
-
 inline LPCRITICAL_SECTION
 ResourceLocks::Lock (int _resid)
 {
@@ -720,7 +689,7 @@ pthread::push_cleanup_handler (__pthread_cleanup_handler *handler)
     // TODO: do it?
     api_fatal ("Attempt to push a cleanup handler across threads");
   handler->next = cleanup_stack;
-  InterlockedExchangePointer (&cleanup_stack, handler);
+  cleanup_stack = handler;
 }
 
 void
@@ -830,7 +799,7 @@ pthread_condattr::~pthread_condattr ()
 List<pthread_cond> pthread_cond::conds;
 
 /* This is used for cond creation protection within a single process only */
-native_mutex NO_COPY pthread_cond::cond_initialization_lock;
+fast_mutex NO_COPY pthread_cond::cond_initialization_lock;
 
 /* We can only be called once.
    TODO: (no rush) use a non copied memory section to
@@ -1040,7 +1009,7 @@ pthread_rwlockattr::~pthread_rwlockattr ()
 List<pthread_rwlock> pthread_rwlock::rwlocks;
 
 /* This is used for rwlock creation protection within a single process only */
-native_mutex NO_COPY pthread_rwlock::rwlock_initialization_lock;
+fast_mutex NO_COPY pthread_rwlock::rwlock_initialization_lock;
 
 /* We can only be called once.
    TODO: (no rush) use a non copied memory section to
@@ -1055,12 +1024,19 @@ pthread_rwlock::init_mutex ()
 pthread_rwlock::pthread_rwlock (pthread_rwlockattr *attr) :
   verifyable_object (PTHREAD_RWLOCK_MAGIC),
   shared (0), waiting_readers (0), waiting_writers (0), writer (NULL),
-  readers (NULL), mtx (NULL), cond_readers (NULL), cond_writers (NULL),
+  readers (NULL), readers_mx (), mtx (NULL), cond_readers (NULL), cond_writers (NULL),
   next (NULL)
 {
   pthread_mutex *verifyable_mutex_obj = &mtx;
   pthread_cond *verifyable_cond_obj;
 
+  if (!readers_mx.init ())
+    {
+      thread_printf ("Internal rwlock synchronisation mutex is not valid. this %p", this);
+      magic = 0;
+      return;
+    }
+
   if (attr)
     if (attr->shared != PTHREAD_PROCESS_PRIVATE)
       {
@@ -1265,34 +1241,28 @@ pthread_rwlock::unlock ()
 void
 pthread_rwlock::add_reader (struct RWLOCK_READER *rd)
 {
-  rd->next = (struct RWLOCK_READER *)
-    InterlockedExchangePointer (&readers, rd);
+  List_insert (readers_mx, readers, rd);
 }
 
 void
 pthread_rwlock::remove_reader (struct RWLOCK_READER *rd)
 {
-  if (readers == rd)
-    InterlockedExchangePointer (&readers, rd->next);
-  else
-    {
-      struct RWLOCK_READER *temp = readers;
-      while (temp->next && temp->next != rd)
-       temp = temp->next;
-      /* but there may be a race between the loop above and this statement */
-      InterlockedExchangePointer (&temp->next, rd->next);
-    }
+  List_remove (readers_mx, readers, rd);
 }
 
 struct pthread_rwlock::RWLOCK_READER *
 pthread_rwlock::lookup_reader (pthread_t thread)
 {
-  struct RWLOCK_READER *temp = readers;
+  readers_mx.lock ();
+
+  struct RWLOCK_READER *cur = readers;
 
-  while (temp && temp->thread != thread)
-    temp = temp->next;
+  while (cur && cur->thread != thread)
+    cur = cur->next;
 
-  return temp;
+  readers_mx.unlock ();
+
+  return cur;
 }
 
 void
@@ -1324,6 +1294,9 @@ pthread_rwlock::_fixup_after_fork ()
   waiting_readers = 0;
   waiting_writers = 0;
 
+  if (!readers_mx.init ())
+    api_fatal ("pthread_rwlock::_fixup_after_fork () failed to recreate mutex");
+
   /* Unlock eventually locked mutex */
   mtx.unlock ();
   /*
@@ -1395,13 +1368,13 @@ pthread_key::get () const
 }
 
 void
-pthread_key::save_key_to_buffer ()
+pthread_key::_fixup_before_fork ()
 {
   fork_buf = get ();
 }
 
 void
-pthread_key::recreate_key_from_buffer ()
+pthread_key::_fixup_after_fork ()
 {
   tls_index = TlsAlloc ();
   if (tls_index == TLS_OUT_OF_INDEXES)
@@ -1496,7 +1469,7 @@ pthread_mutex::can_be_unlocked (pthread_mutex_t const *mutex)
 List<pthread_mutex> pthread_mutex::mutexes;
 
 /* This is used for mutex creation protection within a single process only */
-native_mutex NO_COPY pthread_mutex::mutex_initialization_lock;
+fast_mutex NO_COPY pthread_mutex::mutex_initialization_lock;
 
 /* We can only be called once.
    TODO: (no rush) use a non copied memory section to
@@ -2452,8 +2425,8 @@ pthread_cond::init (pthread_cond_t *cond, const pthread_condattr_t *attr)
 {
   if (attr && !pthread_condattr::is_good_object (attr))
     return EINVAL;
-  if (!cond_initialization_lock.lock ())
-    return EINVAL;
+
+  cond_initialization_lock.lock ();
 
   if (!is_good_initializer_or_bad_object (cond))
     {
@@ -2650,8 +2623,8 @@ pthread_rwlock::init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr
 {
   if (attr && !pthread_rwlockattr::is_good_object (attr))
     return EINVAL;
-  if (!rwlock_initialization_lock.lock ())
-    return EINVAL;
+
+  rwlock_initialization_lock.lock ();
 
   if (!is_good_initializer_or_bad_object (rwlock))
     {
@@ -2844,8 +2817,8 @@ pthread_mutex::init (pthread_mutex_t *mutex,
 {
   if (attr && !pthread_mutexattr::is_good_object (attr) || check_valid_pointer (mutex))
     return EINVAL;
-  if (!mutex_initialization_lock.lock ())
-    return EINVAL;
+
+  mutex_initialization_lock.lock ();
 
   if (!is_good_initializer_or_bad_object (mutex))
     {
index a52c0b7..5753109 100644 (file)
@@ -44,6 +44,7 @@ extern "C"
 #include <signal.h>
 #include <pwd.h>
 #include <grp.h>
+#include <security.h>
 #define _NOMNTENT_FUNCS
 #include <mntent.h>
 
@@ -123,14 +124,46 @@ void AssertResourceOwner (int, int);
 #endif
 }
 
-class native_mutex
+class fast_mutex
 {
 public:
-  bool init ();
-  bool lock ();
-  void unlock ();
+  fast_mutex () :
+    lock_counter (0), win32_obj_id (0)
+  {
+  }
+
+  ~fast_mutex ()
+  {
+    if(win32_obj_id)
+      CloseHandle (win32_obj_id);
+  }
+
+  bool init ()
+  {
+    win32_obj_id = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL);
+    if (!win32_obj_id)
+      {
+        debug_printf ("CreateSemaphore failed. %E");
+        return false;
+      }
+    return true;
+  }
+
+  void lock ()
+  {
+    if (InterlockedIncrement ((long *)&lock_counter) != 1)
+      WaitForSingleObject (win32_obj_id, INFINITE);
+  }
+
+  void unlock ()
+  {
+    if (InterlockedDecrement ((long *)&lock_counter))
+      ::ReleaseSemaphore (win32_obj_id, 1, NULL);
+  }
+
 private:
-  HANDLE theHandle;
+  unsigned long lock_counter;
+  HANDLE win32_obj_id;
 };
 
 class per_process;
@@ -189,51 +222,85 @@ typedef enum
 verifyable_object_state verifyable_object_isvalid (void const *, long);
 verifyable_object_state verifyable_object_isvalid (void const *, long, void *);
 
-template <class list_node> class List {
-public:
+template <class list_node> inline void
+List_insert (fast_mutex &mx, list_node *&head, list_node *node)
+{
+  if (!node)
+    return;
+  mx.lock ();
+  node->next = head;
+  head = node;
+  mx.unlock ();
+}
+
+template <class list_node> inline void
+List_remove (fast_mutex &mx, list_node *&head, list_node *node)
+{
+  if (!node)
+    return;
+  mx.lock ();
+  if (node == head)
+    head = head->next;
+  else if (head)
+    {
+      list_node *cur = head;
+
+      while (cur->next && node != cur->next)
+        cur = cur->next;
+      if (node == cur->next)
+        cur->next = cur->next->next;
+    }
+  mx.unlock ();
+}
+
+template <class list_node> class List
+{
+ public:
   List() : head(NULL)
   {
+    mx_init ();
   }
 
-  void insert (list_node *node)
+  ~List()
   {
-    if (!node)
-      return;
-    node->next = (list_node *) InterlockedExchangePointer (&head, node);
   }
 
-  list_node *remove ( list_node *node)
+  void fixup_after_fork ()
   {
-    if (!node || !head)
-      return NULL;
-    if (node == head)
-      return pop ();
+    mx_init ();
+  }
 
-    list_node *result_prev = head;
-    while (result_prev && result_prev->next && !(node == result_prev->next))
-      result_prev = result_prev->next;
-    if (result_prev)
-      return (list_node *)InterlockedExchangePointer (&result_prev->next, result_prev->next->next);
-    return NULL;
+  void insert (list_node *node)
+  {
+    List_insert (mx, head, node);
   }
 
-  list_node *pop ()
+  void remove (list_node *node)
   {
-    return (list_node *) InterlockedExchangePointer (&head, head->next);
+    List_remove (mx, head, node);
   }
 
-  /* poor mans generic programming. */
   void for_each (void (list_node::*callback) ())
   {
-    list_node *node = head;
-    while (node)
+    mx.lock ();
+    list_node *cur = head;
+    while (cur)
       {
-        (node->*callback) ();
-        node = node->next;
+        (cur->*callback) ();
+        cur = cur->next;
       }
+    mx.unlock ();
   }
 
 protected:
+  void mx_init ()
+  {
+    if (!mx.init ())
+      api_fatal ("Could not create mutex for list synchronisation.");
+  }
+
+  fast_mutex mx;
   list_node *head;
 };
 
@@ -248,14 +315,15 @@ public:
 
   pthread_key (void (*)(void *));
   ~pthread_key ();
-  static void fixup_before_fork()
+  static void fixup_before_fork ()
   {
-    keys.for_each (&pthread_key::save_key_to_buffer);
+    keys.for_each (&pthread_key::_fixup_before_fork);
   }
 
-  static void fixup_after_fork()
+  static void fixup_after_fork ()
   {
-    keys.for_each (&pthread_key::recreate_key_from_buffer);
+    keys.fixup_after_fork ();
+    keys.for_each (&pthread_key::_fixup_after_fork);
   }
 
   static void run_all_destructors ()
@@ -267,8 +335,8 @@ public:
   class pthread_key *next;
 private:
   static List<pthread_key> keys;
-  void save_key_to_buffer ();
-  void recreate_key_from_buffer ();
+  void _fixup_before_fork ();
+  void _fixup_after_fork ();
   void (*destructor) (void *);
   void run_destructor ();
   void *fork_buf;
@@ -361,6 +429,7 @@ public:
   class pthread_mutex * next;
   static void fixup_after_fork ()
   {
+    mutexes.fixup_after_fork ();
     mutexes.for_each (&pthread_mutex::_fixup_after_fork);
   }
 
@@ -373,7 +442,7 @@ private:
   void _fixup_after_fork ();
 
   static List<pthread_mutex> mutexes;
-  static native_mutex mutex_initialization_lock;
+  static fast_mutex mutex_initialization_lock;
 };
 
 #define WAIT_CANCELED   (WAIT_OBJECT_0 + 1)
@@ -447,6 +516,7 @@ public:
   class pthread *next;
   static void fixup_after_fork ()
   {
+    threads.fixup_after_fork ();
     threads.for_each (&pthread::_fixup_after_fork);
   }
 
@@ -533,6 +603,7 @@ public:
   class pthread_cond * next;
   static void fixup_after_fork ()
   {
+    conds.fixup_after_fork ();
     conds.for_each (&pthread_cond::_fixup_after_fork);
   }
 
@@ -540,7 +611,7 @@ private:
   void _fixup_after_fork ();
 
   static List<pthread_cond> conds;
-  static native_mutex cond_initialization_lock;
+  static fast_mutex cond_initialization_lock;
 };
 
 class pthread_rwlockattr:public verifyable_object
@@ -573,6 +644,7 @@ public:
     struct RWLOCK_READER *next;
     pthread_t thread;
   } *readers;
+  fast_mutex readers_mx;
 
   int rdlock ();
   int tryrdlock ();
@@ -592,6 +664,7 @@ public:
   class pthread_rwlock * next;
   static void fixup_after_fork ()
   {
+    rwlocks.fixup_after_fork ();
     rwlocks.for_each (&pthread_rwlock::_fixup_after_fork);
   }
 
@@ -619,7 +692,7 @@ private:
 
   void _fixup_after_fork ();
 
-  static native_mutex rwlock_initialization_lock;
+  static fast_mutex rwlock_initialization_lock;
 };
 
 class pthread_once
@@ -651,6 +724,7 @@ public:
   class semaphore * next;
   static void fixup_after_fork ()
   {
+    semaphores.fixup_after_fork ();
     semaphores.for_each (&semaphore::_fixup_after_fork);
   }