summaryrefslogtreecommitdiff
path: root/libpthread/linuxthreads/join.c
diff options
context:
space:
mode:
Diffstat (limited to 'libpthread/linuxthreads/join.c')
-rw-r--r--libpthread/linuxthreads/join.c57
1 files changed, 23 insertions, 34 deletions
diff --git a/libpthread/linuxthreads/join.c b/libpthread/linuxthreads/join.c
index 4a7c0d8ac..57ea54e34 100644
--- a/libpthread/linuxthreads/join.c
+++ b/libpthread/linuxthreads/join.c
@@ -14,38 +14,31 @@
/* Thread termination and joining */
-#include <features.h>
#include <errno.h>
#include <sched.h>
-#include <unistd.h>
#include <stdlib.h>
+#include <unistd.h>
#include "pthread.h"
#include "internals.h"
#include "spinlock.h"
#include "restart.h"
-#include "debug.h" /* PDEBUG, added by StS */
+#include <not-cancel.h>
-libpthread_hidden_proto(pthread_exit)
-void pthread_exit(void * retval)
+void __pthread_exit(void * retval)
{
__pthread_do_exit (retval, CURRENT_STACK_FRAME);
}
-libpthread_hidden_def (pthread_exit)
+strong_alias (__pthread_exit, pthread_exit)
void __pthread_do_exit(void *retval, char *currentframe)
{
pthread_descr self = thread_self();
pthread_descr joining;
struct pthread_request request;
- PDEBUG("self=%p, pid=%d\n", self, self->p_pid);
-
- /* obey POSIX behavior and prevent cancellation functions from
- * being called more than once.
- * http://sourceware.org/ml/libc-ports/2006-10/msg00043.html
- */
- THREAD_SETMEM(self, p_cancelstate, PTHREAD_CANCEL_DISABLE);
- THREAD_SETMEM(self, p_canceltype, PTHREAD_CANCEL_DEFERRED);
+ /* Reset the cancellation flag to avoid looping if the cleanup handlers
+ contain cancellation points */
+ THREAD_SETMEM(self, p_canceled, 0);
/* Call cleanup functions and destroy the thread-specific data */
__pthread_perform_cleanup(currentframe);
__pthread_destroy_specifics();
@@ -61,7 +54,7 @@ void __pthread_do_exit(void *retval, char *currentframe)
if ((mask & (__pthread_threads_events.event_bits[idx]
| THREAD_GETMEM_NC(self,
- p_eventbuf.eventmask).event_bits[idx]))
+ p_eventbuf.eventmask.event_bits[idx])))
!= 0)
{
/* Yep, we have to signal the death. */
@@ -77,7 +70,6 @@ void __pthread_do_exit(void *retval, char *currentframe)
THREAD_SETMEM(self, p_terminated, 1);
/* See if someone is joining on us */
joining = THREAD_GETMEM(self, p_joining);
- PDEBUG("joining = %p, pid=%d\n", joining, joining ? joining->p_pid : 0);
__pthread_unlock(THREAD_GETMEM(self, p_lock));
/* Restart joining thread if any */
if (joining != NULL) restart(joining);
@@ -87,25 +79,25 @@ void __pthread_do_exit(void *retval, char *currentframe)
if (self == __pthread_main_thread && __pthread_manager_request >= 0) {
request.req_thread = self;
request.req_kind = REQ_MAIN_THREAD_EXIT;
- TEMP_FAILURE_RETRY(write(__pthread_manager_request,
- (char *)&request, sizeof(request)));
+ TEMP_FAILURE_RETRY(write_not_cancel(__pthread_manager_request,
+ (char *)&request, sizeof(request)));
suspend(self);
/* Main thread flushes stdio streams and runs atexit functions.
- * It also calls a handler within LinuxThreads which sends a process exit
- * request to the thread manager. */
+ It also calls a handler within LinuxThreads which sends a process exit
+ request to the thread manager. */
exit(0);
}
- /* Exit the process (but don't flush stdio streams, and don't run
- atexit functions). */
+ /* Threads other than the main one terminate without flushing stdio streams
+ or running atexit functions. */
_exit(0);
}
/* Function called by pthread_cancel to remove the thread from
waiting on a condition variable queue. */
-static int join_extricate_func(void *obj, pthread_descr th attribute_unused)
+static int join_extricate_func(void *obj, pthread_descr th)
{
- volatile pthread_descr self = thread_self();
+ __volatile__ pthread_descr self = thread_self();
pthread_handle handle = obj;
pthread_descr jo;
int did_remove = 0;
@@ -121,20 +113,19 @@ static int join_extricate_func(void *obj, pthread_descr th attribute_unused)
int pthread_join(pthread_t thread_id, void ** thread_return)
{
- volatile pthread_descr self = thread_self();
+ __volatile__ pthread_descr self = thread_self();
struct pthread_request request;
pthread_handle handle = thread_handle(thread_id);
pthread_descr th;
pthread_extricate_if extr;
int already_canceled = 0;
- PDEBUG("\n");
/* Set up extrication interface */
extr.pu_object = handle;
extr.pu_extricate_func = join_extricate_func;
__pthread_lock(&handle->h_lock, self);
- if (invalid_handle(handle, thread_id)) {
+ if (nonexisting_handle(handle, thread_id)) {
__pthread_unlock(&handle->h_lock);
return ESRCH;
}
@@ -164,9 +155,7 @@ int pthread_join(pthread_t thread_id, void ** thread_return)
__pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
}
- PDEBUG("before suspend\n");
suspend(self);
- PDEBUG("after suspend\n");
/* Deregister extrication interface */
__pthread_set_own_extricate_if(self, 0);
@@ -186,8 +175,8 @@ int pthread_join(pthread_t thread_id, void ** thread_return)
request.req_thread = self;
request.req_kind = REQ_FREE;
request.req_args.free.thread_id = thread_id;
- TEMP_FAILURE_RETRY(write(__pthread_manager_request,
- (char *) &request, sizeof(request)));
+ TEMP_FAILURE_RETRY(write_not_cancel(__pthread_manager_request,
+ (char *) &request, sizeof(request)));
}
return 0;
}
@@ -200,7 +189,7 @@ int pthread_detach(pthread_t thread_id)
pthread_descr th;
__pthread_lock(&handle->h_lock, NULL);
- if (invalid_handle(handle, thread_id)) {
+ if (nonexisting_handle(handle, thread_id)) {
__pthread_unlock(&handle->h_lock);
return ESRCH;
}
@@ -224,8 +213,8 @@ int pthread_detach(pthread_t thread_id)
request.req_thread = thread_self();
request.req_kind = REQ_FREE;
request.req_args.free.thread_id = thread_id;
- TEMP_FAILURE_RETRY(write(__pthread_manager_request,
- (char *) &request, sizeof(request)));
+ TEMP_FAILURE_RETRY(write_not_cancel(__pthread_manager_request,
+ (char *) &request, sizeof(request)));
}
return 0;
}