2002-06-12 Thomas Pfaff <tpfaff@gmx.net>

* thread.h (pthread::cleanup_stack): Renamed cleanup_handlers to
	cleanup_stack.
	* thread.cc (pthread::pthread): Ditto.
	(pthread::create): Fixed mutex verification.
	(pthread::push_cleanup_handler): Renamed cleanup_handlers to
	cleanup_stack.
	Mutex calls removed, used InterlockedExchangePointer instead.
	(pthread::pop_cleanup_handler): Renamed cleanup_handlers to
	cleanup_stack.
	(pthread::pop_all_cleanup_handlers): Ditto.
	(__pthread_once): Check state first and return if already done.
	(__pthread_join): DEADLOCK test reverted to __pthread_equal
	call.
	(__pthread_detach): Unlock mutex before deletion.
This commit is contained in:
Robert Collins 2002-06-23 07:36:21 +00:00
parent 0278e3a33f
commit f6709c07db
3 changed files with 45 additions and 24 deletions

View File

@ -1,3 +1,20 @@
2002-06-12 Thomas Pfaff <tpfaff@gmx.net>
* thread.h (pthread::cleanup_stack): Renamed cleanup_handlers to
cleanup_stack.
* thread.cc (pthread::pthread): Ditto.
(pthread::create): Fixed mutex verification.
(pthread::push_cleanup_handler): Renamed cleanup_handlers to
cleanup_stack.
Mutex calls removed, used InterlockedExchangePointer instead.
(pthread::pop_cleanup_handler): Renamed cleanup_handlers to
cleanup_stack.
(pthread::pop_all_cleanup_handlers): Ditto.
(__pthread_once): Check state first and return if already done.
(__pthread_join): DEADLOCK test reverted to __pthread_equal
call.
(__pthread_detach): Unlock mutex before deletion.
2002-06-21 Christopher Faylor <cgf@redhat.com> 2002-06-21 Christopher Faylor <cgf@redhat.com>
* Makefile.in (cygrun.exe): Move -lgcc where it will do some good. * Makefile.in (cygrun.exe): Move -lgcc where it will do some good.

View File

@ -355,7 +355,7 @@ pthread::self ()
/* member methods */ /* member methods */
pthread::pthread ():verifyable_object (PTHREAD_MAGIC), win32_obj_id (0), pthread::pthread ():verifyable_object (PTHREAD_MAGIC), win32_obj_id (0),
cancelstate (0), canceltype (0), joiner (NULL), cleanup_handlers(NULL) cancelstate (0), canceltype (0), joiner (NULL), cleanup_stack(NULL)
{ {
} }
@ -370,6 +370,8 @@ void
pthread::create (void *(*func) (void *), pthread_attr *newattr, pthread::create (void *(*func) (void *), pthread_attr *newattr,
void *threadarg) void *threadarg)
{ {
pthread_mutex *verifyable_mutex_obj = &mutex;
/*already running ? */ /*already running ? */
if (win32_obj_id) if (win32_obj_id)
return; return;
@ -384,7 +386,7 @@ pthread::create (void *(*func) (void *), pthread_attr *newattr,
function = func; function = func;
arg = threadarg; arg = threadarg;
if (verifyable_object_isvalid (&mutex, PTHREAD_MUTEX_MAGIC) != VALID_OBJECT) if (verifyable_object_isvalid (&verifyable_mutex_obj, PTHREAD_MUTEX_MAGIC) != VALID_OBJECT)
{ {
thread_printf ("New thread object access mutex is not valid. this %p", thread_printf ("New thread object access mutex is not valid. this %p",
this); this);
@ -417,10 +419,8 @@ pthread::push_cleanup_handler (__pthread_cleanup_handler *handler)
if (this != self ()) if (this != self ())
// TODO: do it? // TODO: do it?
api_fatal ("Attempt to push a cleanup handler across threads"); api_fatal ("Attempt to push a cleanup handler across threads");
mutex.Lock(); handler->next = cleanup_stack;
handler->next = cleanup_handlers; InterlockedExchangePointer( &cleanup_stack, handler );
cleanup_handlers = handler;
mutex.UnLock();
} }
void void
@ -430,21 +430,20 @@ pthread::pop_cleanup_handler (int const execute)
// TODO: send a signal or something to the thread ? // TODO: send a signal or something to the thread ?
api_fatal ("Attempt to execute a cleanup handler across threads"); api_fatal ("Attempt to execute a cleanup handler across threads");
if (cleanup_handlers != NULL ) if (cleanup_stack != NULL)
{ {
__pthread_cleanup_handler *handler = cleanup_handlers; __pthread_cleanup_handler *handler = cleanup_stack;
if (execute) if (execute)
(*handler->function) (handler->arg); (*handler->function) (handler->arg);
cleanup_stack = handler->next;
cleanup_handlers = handler->next;
} }
} }
void void
pthread::pop_all_cleanup_handlers () pthread::pop_all_cleanup_handlers ()
{ {
while (cleanup_handlers != NULL) while (cleanup_stack != NULL)
pop_cleanup_handler (1); pop_cleanup_handler (1);
} }
@ -1015,6 +1014,10 @@ __pthread_create (pthread_t *thread, const pthread_attr_t *attr,
int int
__pthread_once (pthread_once_t *once_control, void (*init_routine) (void)) __pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
{ {
// already done ?
if (once_control->state)
return 0;
pthread_mutex_lock (&once_control->mutex); pthread_mutex_lock (&once_control->mutex);
/*Here we must set a cancellation handler to unlock the mutex if needed */ /*Here we must set a cancellation handler to unlock the mutex if needed */
/*but a cancellation handler is not the right thing. We need this in the thread /*but a cancellation handler is not the right thing. We need this in the thread
@ -1022,7 +1025,7 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
*at a time. Stote a mutex_t *in the pthread_structure. if that's non null unlock *at a time. Stote a mutex_t *in the pthread_structure. if that's non null unlock
*on pthread_exit (); *on pthread_exit ();
*/ */
if (once_control->state == 0) if (!once_control->state)
{ {
init_routine (); init_routine ();
once_control->state = 1; once_control->state = 1;
@ -1556,7 +1559,7 @@ __pthread_exit (void *value_ptr)
pthread * thread = pthread::self (); pthread * thread = pthread::self ();
// run cleanup handlers // run cleanup handlers
thread->pop_all_cleanup_handlers(); thread->pop_all_cleanup_handlers ();
MT_INTERFACE->destructors.IterateNull (); MT_INTERFACE->destructors.IterateNull ();
@ -1581,23 +1584,21 @@ __pthread_join (pthread_t *thread, void **return_val)
{ {
pthread_t joiner = pthread::self (); pthread_t joiner = pthread::self ();
// Initialize return val with NULL
if (return_val)
*return_val = NULL;
/*FIXME: wait on the thread cancellation event as well - we are a cancellation point*/ /*FIXME: wait on the thread cancellation event as well - we are a cancellation point*/
if (verifyable_object_isvalid (thread, PTHREAD_MAGIC) != VALID_OBJECT) if (verifyable_object_isvalid (thread, PTHREAD_MAGIC) != VALID_OBJECT)
return ESRCH; return ESRCH;
if ( joiner == *thread) if (__pthread_equal(thread,&joiner))
{ return EDEADLK;
if (return_val)
*return_val = NULL;
return EDEADLK;
}
(*thread)->mutex.Lock (); (*thread)->mutex.Lock ();
if((*thread)->attr.joinable == PTHREAD_CREATE_DETACHED) if((*thread)->attr.joinable == PTHREAD_CREATE_DETACHED)
{ {
if (return_val)
*return_val = NULL;
(*thread)->mutex.UnLock (); (*thread)->mutex.UnLock ();
return EINVAL; return EINVAL;
} }
@ -1640,8 +1641,11 @@ __pthread_detach (pthread_t *thread)
(*thread)->mutex.UnLock (); (*thread)->mutex.UnLock ();
} }
else else
// thread has already terminated. {
// thread has already terminated.
(*thread)->mutex.UnLock ();
delete (*thread); delete (*thread);
}
return 0; return 0;
} }

View File

@ -295,7 +295,7 @@ public:
private: private:
DWORD thread_id; DWORD thread_id;
__pthread_cleanup_handler *cleanup_handlers; __pthread_cleanup_handler *cleanup_stack;
pthread_mutex mutex; pthread_mutex mutex;
friend void __pthread_exit (void *value_ptr); friend void __pthread_exit (void *value_ptr);