summaryrefslogtreecommitdiff
path: root/pthread/pt-join.c
diff options
context:
space:
mode:
Diffstat (limited to 'pthread/pt-join.c')
-rw-r--r--pthread/pt-join.c15
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;