From 28194e813eecd55cbc126f0ffd2a3d28d7b526cb Mon Sep 17 00:00:00 2001 From: Thomas Pfaff Date: Fri, 24 Oct 2003 19:34:47 +0000 Subject: 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. --- winsup/cygwin/thread.h | 150 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 112 insertions(+), 38 deletions(-) (limited to 'winsup/cygwin/thread.h') diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h index a52c0b771..575310958 100644 --- a/winsup/cygwin/thread.h +++ b/winsup/cygwin/thread.h @@ -44,6 +44,7 @@ extern "C" #include #include #include +#include #define _NOMNTENT_FUNCS #include @@ -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 { -public: +template 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 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 +{ + 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 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 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 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); } -- cgit v1.2.3