From e1e196a225a1fee14447b5ef409c5b3890f98334 Mon Sep 17 00:00:00 2001 From: Thomas Pfaff Date: Tue, 24 Jun 2003 20:14:01 +0000 Subject: [PATCH] * thread.cc (MTinterface::fixup_after_fork): Fix thread list after fork. (pthread::threads): Instantiate. (pthread::pthread): Initialize running and suspendend. Initialize next with NULL. Add thread to thread list if it is not the null_pthread. (pthread::~pthread): Remove thread from thread list if it is not the null_pthread. (pthread::postcreate): Set running flag. (pthread::exit): Reset running flag. (pthread::cancel): Try to cancel thread only if still running. (pthread::_fixup_after_fork): Implement. (pthread::detach): Check if thread is still running before detach. * thread.h (pthread::running): New member. (pthread::next): Ditto. (pthread::fixup_after_fork): New static method. (pthread::threads): New static method. (pthread::_fixup_after_fork): New method. --- winsup/cygwin/ChangeLog | 21 ++++++++++++++++++ winsup/cygwin/thread.cc | 49 +++++++++++++++++++++++++++++++++-------- winsup/cygwin/thread.h | 12 +++++++++- 3 files changed, 72 insertions(+), 10 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index e854b6fd3..aa0e3ae55 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,24 @@ +2003-06-24 Thomas Pfaff + + * thread.cc (MTinterface::fixup_after_fork): Fix thread list after + fork. + (pthread::threads): Instantiate. + (pthread::pthread): Initialize running and suspendend. + Initialize next with NULL. + Add thread to thread list if it is not the null_pthread. + (pthread::~pthread): Remove thread from thread list if it is + not the null_pthread. + (pthread::postcreate): Set running flag. + (pthread::exit): Reset running flag. + (pthread::cancel): Try to cancel thread only if still running. + (pthread::_fixup_after_fork): Implement. + (pthread::detach): Check if thread is still running before detach. + * thread.h (pthread::running): New member. + (pthread::next): Ditto. + (pthread::fixup_after_fork): New static method. + (pthread::threads): New static method. + (pthread::_fixup_after_fork): New method. + 2003-06-20 Christopher Faylor * pinfo.cc (_pinfo::commune_send): Don't attempt to communicate with a diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc index 60e94e794..937a9fbbc 100644 --- a/winsup/cygwin/thread.cc +++ b/winsup/cygwin/thread.cc @@ -238,6 +238,7 @@ MTinterface::fixup_after_fork (void) threadcount = 1; pthread::init_mainthread (); + pthread::fixup_after_fork (); pthread_mutex::fixup_after_fork (); pthread_cond::fixup_after_fork (); pthread_rwlock::fixup_after_fork (); @@ -284,11 +285,16 @@ pthread::get_tls_self_pointer () +List pthread::threads; + /* member methods */ pthread::pthread ():verifyable_object (PTHREAD_MAGIC), win32_obj_id (0), + running (false), suspended (false), cancelstate (0), canceltype (0), cancel_event (0), - joiner (NULL), cleanup_stack (NULL) + joiner (NULL), next (NULL), cleanup_stack (NULL) { + if (this != pthread_null::get_null_pthread ()) + threads.insert (this); } pthread::~pthread () @@ -297,6 +303,9 @@ pthread::~pthread () CloseHandle (win32_obj_id); if (cancel_event) CloseHandle (cancel_event); + + if (this != pthread_null::get_null_pthread ()) + threads.remove (this); } void @@ -370,13 +379,15 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr, void pthread::postcreate () { - InterlockedIncrement (&MT_INTERFACE->threadcount); - /* FIXME: set the priority appropriately for system contention scope */ - if (attr.inheritsched == PTHREAD_EXPLICIT_SCHED) - { - /* FIXME: set the scheduling settings for the new thread */ - /* sched_thread_setparam (win32_obj_id, attr.schedparam); */ - } + running = true; + + InterlockedIncrement (&MT_INTERFACE->threadcount); + /* FIXME: set the priority appropriately for system contention scope */ + if (attr.inheritsched == PTHREAD_EXPLICIT_SCHED) + { + /* FIXME: set the scheduling settings for the new thread */ + /* sched_thread_setparam (win32_obj_id, attr.schedparam); */ + } } void @@ -395,6 +406,7 @@ pthread::exit (void *value_ptr) delete this; else { + running = false; return_ptr = value_ptr; mutex.unlock (); } @@ -413,6 +425,12 @@ pthread::cancel (void) mutex.lock (); + if (!running) + { + mutex.unlock (); + return 0; + } + if (canceltype == PTHREAD_CANCEL_DEFERRED || cancelstate == PTHREAD_CANCEL_DISABLE) { @@ -762,6 +780,19 @@ pthread::init_current_thread () set_tls_self_pointer (this); } +void +pthread::_fixup_after_fork () +{ + /* set thread to not running if it is not the forking thread */ + if (this != pthread::self ()) + { + magic = 0; + running = false; + win32_obj_id = NULL; + cancel_event = NULL; + } +} + /* static members */ bool pthread_attr::is_good_object (pthread_attr_t const *attr) @@ -2211,7 +2242,7 @@ pthread::detach (pthread_t *thread) } // check if thread is still alive - if (WaitForSingleObject ((*thread)->win32_obj_id, 0) == WAIT_TIMEOUT) + if ((*thread)->running && WaitForSingleObject ((*thread)->win32_obj_id, 0) == WAIT_TIMEOUT) { // force cleanup on exit (*thread)->joiner = *thread; diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h index e89640e6b..ea1f13f44 100644 --- a/winsup/cygwin/thread.h +++ b/winsup/cygwin/thread.h @@ -385,11 +385,11 @@ public: void *(*function) (void *); void *arg; void *return_ptr; + bool running; bool suspended; int cancelstate, canceltype; HANDLE cancel_event; pthread_t joiner; - // int joinable; /* signal handling */ struct sigaction *sigs; @@ -442,11 +442,21 @@ public: return t1 == t2; } + /* List support calls */ + class pthread *next; + static void fixup_after_fork () + { + threads.for_each (&pthread::_fixup_after_fork); + } + private: + static List threads; DWORD thread_id; __pthread_cleanup_handler *cleanup_stack; pthread_mutex mutex; + void _fixup_after_fork (); + void pop_all_cleanup_handlers (void); void precreate (pthread_attr *); void postcreate ();