From 1503a262e1a2675a0f439287ca02a952b67cc098 Mon Sep 17 00:00:00 2001 From: GNU Libc Maintainers Date: Sat, 17 May 2025 17:15:43 +0200 Subject: [PATCH] git-pthread_setcancel commit bfb2f2f481147da54237ade3266f2586a51d43c9 Author: Samuel Thibault Date: Sat Mar 15 15:23:42 2025 +0000 htl: Make pthread_setcanceltype / state a cancellation point as expected by tst-cancel32. Gbp-Pq: Topic hurd-i386 Gbp-Pq: Name git-pthread_setcancel.diff --- htl/pt-setcancelstate.c | 8 ++++++++ htl/pt-setcanceltype.c | 5 +++++ sysdeps/htl/pthreadP.h | 8 ++++++++ 3 files changed, 21 insertions(+) diff --git a/htl/pt-setcancelstate.c b/htl/pt-setcancelstate.c index 57894de71..7241122c0 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; } diff --git a/htl/pt-setcanceltype.c b/htl/pt-setcanceltype.c index f9474f9c3..a4fdeb691 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; } diff --git a/sysdeps/htl/pthreadP.h b/sysdeps/htl/pthreadP.h index 20dd5a1cc..893198f45 100644 --- a/sysdeps/htl/pthreadP.h +++ b/sysdeps/htl/pthreadP.h @@ -172,6 +172,14 @@ hidden_proto (__pthread_mutex_timedlock) 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) -- 2.30.2