aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--htl/pt-setcancelstate.c8
-rw-r--r--htl/pt-setcanceltype.c5
-rw-r--r--sysdeps/htl/pthreadP.h8
3 files changed, 21 insertions, 0 deletions
diff --git a/htl/pt-setcancelstate.c b/htl/pt-setcancelstate.c
index 6e09c26..0d5692e 100644
--- a/htl/pt-setcancelstate.c
+++ b/htl/pt-setcancelstate.c
@@ -24,6 +24,7 @@ int
__pthread_setcancelstate (int state, int *oldstate)
{
struct __pthread *p = _pthread_self ();
+ int cancelled;
switch (state)
{
@@ -38,8 +39,15 @@ __pthread_setcancelstate (int state, int *oldstate)
if (oldstate != NULL)
*oldstate = p->cancel_state;
p->cancel_state = state;
+ cancelled = (p->cancel_state == PTHREAD_CANCEL_ENABLE) && p->cancel_pending == 1 && (p->cancel_type == PTHREAD_CANCEL_ASYNCHRONOUS);
+ if (cancelled)
+ /* Do not achieve cancel when called again, notably from __pthread_exit itself. */
+ p->cancel_pending = 2;
__pthread_mutex_unlock (&p->cancel_lock);
+ if (cancelled && __pthread_exit)
+ __pthread_exit (PTHREAD_CANCELED);
+
return 0;
}
libc_hidden_def (__pthread_setcancelstate)
diff --git a/htl/pt-setcanceltype.c b/htl/pt-setcanceltype.c
index 0b76fbf..b33931c 100644
--- a/htl/pt-setcanceltype.c
+++ b/htl/pt-setcanceltype.c
@@ -24,6 +24,7 @@ int
__pthread_setcanceltype (int type, int *oldtype)
{
struct __pthread *p = _pthread_self ();
+ int cancelled;
switch (type)
{
@@ -38,8 +39,12 @@ __pthread_setcanceltype (int type, int *oldtype)
if (oldtype != NULL)
*oldtype = p->cancel_type;
p->cancel_type = type;
+ cancelled = (p->cancel_state == PTHREAD_CANCEL_ENABLE) && p->cancel_pending && (p->cancel_type == PTHREAD_CANCEL_ASYNCHRONOUS);
__pthread_mutex_unlock (&p->cancel_lock);
+ if (cancelled && __pthread_exit)
+ __pthread_exit (PTHREAD_CANCELED);
+
return 0;
}
libc_hidden_def (__pthread_setcanceltype)
diff --git a/sysdeps/htl/pthreadP.h b/sysdeps/htl/pthreadP.h
index 9479b9e..78ef4e7 100644
--- a/sysdeps/htl/pthreadP.h
+++ b/sysdeps/htl/pthreadP.h
@@ -221,6 +221,14 @@ hidden_proto (__pthread_setspecific)
hidden_proto (__pthread_get_cleanup_stack)
#endif
+#if !defined(__NO_WEAK_PTHREAD_ALIASES) && !IS_IN (libpthread)
+# ifdef weak_extern
+weak_extern (__pthread_exit)
+# else
+# pragma weak __pthread_exit
+# endif
+#endif
+
#define ASSERT_TYPE_SIZE(type, size) \
_Static_assert (sizeof (type) == size, \
"sizeof (" #type ") != " #size)