diff options
-rw-r--r-- | htl/pt-setcancelstate.c | 8 | ||||
-rw-r--r-- | htl/pt-setcanceltype.c | 5 | ||||
-rw-r--r-- | sysdeps/htl/pthreadP.h | 8 |
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) |