diff options
author | Thomas Pfaff <tpfaff@gmx.net> | 2003-06-24 20:14:01 +0000 |
---|---|---|
committer | Thomas Pfaff <tpfaff@gmx.net> | 2003-06-24 20:14:01 +0000 |
commit | e1e196a225a1fee14447b5ef409c5b3890f98334 (patch) | |
tree | 58657e1abe9c0a82f29fce455a0213425a1988d7 | |
parent | b8f7ea5ccba184f7a3718312a186b8ea45a153ed (diff) | |
download | newlib-e1e196a225a1fee14447b5ef409c5b3890f98334.zip newlib-e1e196a225a1fee14447b5ef409c5b3890f98334.tar.gz newlib-e1e196a225a1fee14447b5ef409c5b3890f98334.tar.bz2 |
* 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.
-rw-r--r-- | winsup/cygwin/ChangeLog | 21 | ||||
-rw-r--r-- | winsup/cygwin/thread.cc | 49 | ||||
-rw-r--r-- | winsup/cygwin/thread.h | 12 |
3 files changed, 72 insertions, 10 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index e854b6f..aa0e3ae 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,24 @@ +2003-06-24 Thomas Pfaff <tpfaff@gmx.net> + + * 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 <cgf@redhat.com> * 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 60e94e7..937a9fb 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> 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 e89640e..ea1f13f 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<pthread> 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 (); |