Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Pfaff <tpfaff@gmx.net>2003-06-25 00:14:01 +0400
committerThomas Pfaff <tpfaff@gmx.net>2003-06-25 00:14:01 +0400
commite1e196a225a1fee14447b5ef409c5b3890f98334 (patch)
tree58657e1abe9c0a82f29fce455a0213425a1988d7 /winsup/cygwin
parentb8f7ea5ccba184f7a3718312a186b8ea45a153ed (diff)
* 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.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/ChangeLog21
-rw-r--r--winsup/cygwin/thread.cc49
-rw-r--r--winsup/cygwin/thread.h12
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 <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 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> 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<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 ();