diff options
Diffstat (limited to 'pthread/pt-join.c')
-rw-r--r-- | pthread/pt-join.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/pthread/pt-join.c b/pthread/pt-join.c index 698b6c9..153058b 100644 --- a/pthread/pt-join.c +++ b/pthread/pt-join.c @@ -37,7 +37,8 @@ pthread_join (pthread_t thread, void **status) return ESRCH; __pthread_mutex_lock (&pthread->state_lock); - pthread_cleanup_push (__pthread_mutex_unlock, &pthread->state_lock); + pthread_cleanup_push ((void (*)(void *)) __pthread_mutex_unlock, + &pthread->state_lock); while (pthread->state == PTHREAD_JOINABLE) pthread_cond_wait (&pthread->state_cond, &pthread->state_lock); @@ -53,12 +54,20 @@ pthread_join (pthread_t thread, void **status) if (status) *status = pthread->status; - /* Make sure nobody can reference it anymore, and mark it as - terminated. */ + /* Make sure the thread is not running before we remove its + stack. (The only possibility is that it is in a call to + __pthread_thread_halt itself, but that is enough to cause a + sigsegv.) */ + __pthread_thread_halt (pthread); + + /* Destroy the stack, the kernel resources and the control + block. */ assert (pthread->stack); __pthread_stack_dealloc (pthread->stackaddr, pthread->stacksize); pthread->stack = 0; + __pthread_thread_dealloc (pthread); + __pthread_dealloc (pthread); break; |