summaryrefslogtreecommitdiffstats
path: root/libpthread/linuxthreads.old/join.c
diff options
context:
space:
mode:
author"Steven J. Hill" <sjhill@realitydiluted.com>2006-12-16 04:54:52 +0000
committer"Steven J. Hill" <sjhill@realitydiluted.com>2006-12-16 04:54:52 +0000
commit7dfaf230d2191da71f3078943ea09d014298e7b0 (patch)
tree11b16e846adf904f804b8ce15937db12d08259d8 /libpthread/linuxthreads.old/join.c
parent1bcf527f5f8c94aac1b2e80b585898a7266293af (diff)
downloaduClibc-alpine-7dfaf230d2191da71f3078943ea09d014298e7b0.tar.bz2
uClibc-alpine-7dfaf230d2191da71f3078943ea09d014298e7b0.tar.xz
Merge from trunk.
Diffstat (limited to 'libpthread/linuxthreads.old/join.c')
-rw-r--r--libpthread/linuxthreads.old/join.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/libpthread/linuxthreads.old/join.c b/libpthread/linuxthreads.old/join.c
index 6a8a9d982..4bdc77a25 100644
--- a/libpthread/linuxthreads.old/join.c
+++ b/libpthread/linuxthreads.old/join.c
@@ -27,16 +27,25 @@
void pthread_exit(void * retval)
{
+ __pthread_do_exit (retval, CURRENT_STACK_FRAME);
+}
+
+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);
- /* Reset the cancellation flag to avoid looping if the cleanup handlers
- contain cancellation points */
- THREAD_SETMEM(self, p_canceled, 0);
+ /* 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);
+
/* Call cleanup functions and destroy the thread-specific data */
- __pthread_perform_cleanup();
+ __pthread_perform_cleanup(currentframe);
__pthread_destroy_specifics();
/* Store return value */
__pthread_lock(THREAD_GETMEM(self, p_lock), self);
@@ -150,7 +159,7 @@ int pthread_join(pthread_t thread_id, void ** thread_return)
if (already_canceled) {
__pthread_set_own_extricate_if(self, 0);
- pthread_exit(PTHREAD_CANCELED);
+ __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
}
PDEBUG("before suspend\n");
@@ -163,7 +172,7 @@ int pthread_join(pthread_t thread_id, void ** thread_return)
if (THREAD_GETMEM(self, p_woken_by_cancel)
&& THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE) {
THREAD_SETMEM(self, p_woken_by_cancel, 0);
- pthread_exit(PTHREAD_CANCELED);
+ __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
}
__pthread_lock(&handle->h_lock, self);
}