summaryrefslogtreecommitdiff
path: root/libpthread/linuxthreads/cancel.c
diff options
context:
space:
mode:
Diffstat (limited to 'libpthread/linuxthreads/cancel.c')
-rw-r--r--libpthread/linuxthreads/cancel.c90
1 files changed, 54 insertions, 36 deletions
diff --git a/libpthread/linuxthreads/cancel.c b/libpthread/linuxthreads/cancel.c
index 392d1d586..21b8d900c 100644
--- a/libpthread/linuxthreads/cancel.c
+++ b/libpthread/linuxthreads/cancel.c
@@ -19,13 +19,6 @@
#include "internals.h"
#include "spinlock.h"
#include "restart.h"
-#ifdef __UCLIBC_HAS_RPC__
-#include <rpc/rpc.h>
-extern void __rpc_thread_destroy(void);
-#endif
-#include <bits/stackinfo.h>
-
-#include <stdio.h>
#ifdef _STACK_GROWS_DOWN
# define FRAME_LEFT(frame, other) ((char *) frame >= (char *) other)
@@ -35,10 +28,8 @@ extern void __rpc_thread_destroy(void);
# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP"
#endif
-libpthread_hidden_proto(pthread_setcancelstate)
-libpthread_hidden_proto(pthread_setcanceltype)
-int pthread_setcancelstate(int state, int * oldstate)
+int __pthread_setcancelstate(int state, int * oldstate)
{
pthread_descr self = thread_self();
if (state < PTHREAD_CANCEL_ENABLE || state > PTHREAD_CANCEL_DISABLE)
@@ -51,9 +42,9 @@ int pthread_setcancelstate(int state, int * oldstate)
__pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
return 0;
}
-libpthread_hidden_def(pthread_setcancelstate)
+strong_alias (__pthread_setcancelstate, pthread_setcancelstate)
-int pthread_setcanceltype(int type, int * oldtype)
+int __pthread_setcanceltype(int type, int * oldtype)
{
pthread_descr self = thread_self();
if (type < PTHREAD_CANCEL_DEFERRED || type > PTHREAD_CANCEL_ASYNCHRONOUS)
@@ -66,7 +57,33 @@ int pthread_setcanceltype(int type, int * oldtype)
__pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
return 0;
}
-libpthread_hidden_def(pthread_setcanceltype)
+strong_alias (__pthread_setcanceltype, pthread_setcanceltype)
+
+
+/* The next two functions are similar to pthread_setcanceltype() but
+ more specialized for the use in the cancelable functions like write().
+ They do not need to check parameters etc. */
+int
+attribute_hidden
+__pthread_enable_asynccancel (void)
+{
+ pthread_descr self = thread_self();
+ int oldtype = THREAD_GETMEM(self, p_canceltype);
+ THREAD_SETMEM(self, p_canceltype, PTHREAD_CANCEL_ASYNCHRONOUS);
+ if (__builtin_expect (THREAD_GETMEM(self, p_canceled), 0) &&
+ THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE)
+ __pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
+ return oldtype;
+}
+
+void
+internal_function attribute_hidden
+__pthread_disable_asynccancel (int oldtype)
+{
+ pthread_descr self = thread_self();
+ THREAD_SETMEM(self, p_canceltype, oldtype);
+}
+
int pthread_cancel(pthread_t thread)
{
@@ -167,7 +184,6 @@ void _pthread_cleanup_push_defer(struct _pthread_cleanup_buffer * buffer,
THREAD_SETMEM(self, p_canceltype, PTHREAD_CANCEL_DEFERRED);
THREAD_SETMEM(self, p_cleanup, buffer);
}
-strong_alias(_pthread_cleanup_push_defer,__pthread_cleanup_push_defer)
void _pthread_cleanup_pop_restore(struct _pthread_cleanup_buffer * buffer,
int execute)
@@ -181,26 +197,36 @@ void _pthread_cleanup_pop_restore(struct _pthread_cleanup_buffer * buffer,
THREAD_GETMEM(self, p_canceltype) == PTHREAD_CANCEL_ASYNCHRONOUS)
__pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
}
-strong_alias(_pthread_cleanup_pop_restore,__pthread_cleanup_pop_restore)
-
+extern void __rpc_thread_destroy(void);
void __pthread_perform_cleanup(char *currentframe)
{
pthread_descr self = thread_self();
- struct _pthread_cleanup_buffer * c;
-
- for (c = THREAD_GETMEM(self, p_cleanup); c != NULL; c = c->__prev)
+ struct _pthread_cleanup_buffer *c = THREAD_GETMEM(self, p_cleanup);
+ struct _pthread_cleanup_buffer *last;
+
+ if (c != NULL)
+ while (FRAME_LEFT (currentframe, c))
+ {
+ last = c;
+ c = c->__prev;
+
+ if (c == NULL || FRAME_LEFT (last, c))
+ {
+ c = NULL;
+ break;
+ }
+ }
+
+ while (c != NULL)
{
-#ifdef _STACK_GROWS_DOWN
- if ((char *) c <= currentframe)
- break;
-#elif defined _STACK_GROWS_UP
- if ((char *) c >= currentframe)
- break;
-#else
-# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP"
-#endif
c->__routine(c->__arg);
+
+ last = c;
+ c = c->__prev;
+
+ if (FRAME_LEFT (last, c))
+ break;
}
#ifdef __UCLIBC_HAS_RPC__
@@ -209,11 +235,3 @@ void __pthread_perform_cleanup(char *currentframe)
__rpc_thread_destroy ();
#endif
}
-
-#ifndef __PIC__
-/* We need a hook to force the cancellation wrappers to be linked in when
- static libpthread is used. */
-extern const char __pthread_provide_wrappers;
-static const char *const __pthread_require_wrappers =
- &__pthread_provide_wrappers;
-#endif