* 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.
This commit is contained in:
Thomas Pfaff 2003-06-24 20:14:01 +00:00
parent b8f7ea5ccb
commit e1e196a225
3 changed files with 72 additions and 10 deletions

View File

@ -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> 2003-06-20 Christopher Faylor <cgf@redhat.com>
* pinfo.cc (_pinfo::commune_send): Don't attempt to communicate with a * pinfo.cc (_pinfo::commune_send): Don't attempt to communicate with a

View File

@ -238,6 +238,7 @@ MTinterface::fixup_after_fork (void)
threadcount = 1; threadcount = 1;
pthread::init_mainthread (); pthread::init_mainthread ();
pthread::fixup_after_fork ();
pthread_mutex::fixup_after_fork (); pthread_mutex::fixup_after_fork ();
pthread_cond::fixup_after_fork (); pthread_cond::fixup_after_fork ();
pthread_rwlock::fixup_after_fork (); pthread_rwlock::fixup_after_fork ();
@ -284,11 +285,16 @@ pthread::get_tls_self_pointer ()
List<pthread> pthread::threads;
/* member methods */ /* member methods */
pthread::pthread ():verifyable_object (PTHREAD_MAGIC), win32_obj_id (0), pthread::pthread ():verifyable_object (PTHREAD_MAGIC), win32_obj_id (0),
running (false), suspended (false),
cancelstate (0), canceltype (0), cancel_event (0), 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 () pthread::~pthread ()
@ -297,6 +303,9 @@ pthread::~pthread ()
CloseHandle (win32_obj_id); CloseHandle (win32_obj_id);
if (cancel_event) if (cancel_event)
CloseHandle (cancel_event); CloseHandle (cancel_event);
if (this != pthread_null::get_null_pthread ())
threads.remove (this);
} }
void void
@ -370,13 +379,15 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr,
void void
pthread::postcreate () pthread::postcreate ()
{ {
InterlockedIncrement (&MT_INTERFACE->threadcount); running = true;
/* FIXME: set the priority appropriately for system contention scope */
if (attr.inheritsched == PTHREAD_EXPLICIT_SCHED) InterlockedIncrement (&MT_INTERFACE->threadcount);
{ /* FIXME: set the priority appropriately for system contention scope */
/* FIXME: set the scheduling settings for the new thread */ if (attr.inheritsched == PTHREAD_EXPLICIT_SCHED)
/* sched_thread_setparam (win32_obj_id, attr.schedparam); */ {
} /* FIXME: set the scheduling settings for the new thread */
/* sched_thread_setparam (win32_obj_id, attr.schedparam); */
}
} }
void void
@ -395,6 +406,7 @@ pthread::exit (void *value_ptr)
delete this; delete this;
else else
{ {
running = false;
return_ptr = value_ptr; return_ptr = value_ptr;
mutex.unlock (); mutex.unlock ();
} }
@ -413,6 +425,12 @@ pthread::cancel (void)
mutex.lock (); mutex.lock ();
if (!running)
{
mutex.unlock ();
return 0;
}
if (canceltype == PTHREAD_CANCEL_DEFERRED || if (canceltype == PTHREAD_CANCEL_DEFERRED ||
cancelstate == PTHREAD_CANCEL_DISABLE) cancelstate == PTHREAD_CANCEL_DISABLE)
{ {
@ -762,6 +780,19 @@ pthread::init_current_thread ()
set_tls_self_pointer (this); 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 */ /* static members */
bool bool
pthread_attr::is_good_object (pthread_attr_t const *attr) 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 // 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 // force cleanup on exit
(*thread)->joiner = *thread; (*thread)->joiner = *thread;

View File

@ -385,11 +385,11 @@ public:
void *(*function) (void *); void *(*function) (void *);
void *arg; void *arg;
void *return_ptr; void *return_ptr;
bool running;
bool suspended; bool suspended;
int cancelstate, canceltype; int cancelstate, canceltype;
HANDLE cancel_event; HANDLE cancel_event;
pthread_t joiner; pthread_t joiner;
// int joinable;
/* signal handling */ /* signal handling */
struct sigaction *sigs; struct sigaction *sigs;
@ -442,11 +442,21 @@ public:
return t1 == t2; return t1 == t2;
} }
/* List support calls */
class pthread *next;
static void fixup_after_fork ()
{
threads.for_each (&pthread::_fixup_after_fork);
}
private: private:
static List<pthread> threads;
DWORD thread_id; DWORD thread_id;
__pthread_cleanup_handler *cleanup_stack; __pthread_cleanup_handler *cleanup_stack;
pthread_mutex mutex; pthread_mutex mutex;
void _fixup_after_fork ();
void pop_all_cleanup_handlers (void); void pop_all_cleanup_handlers (void);
void precreate (pthread_attr *); void precreate (pthread_attr *);
void postcreate (); void postcreate ();