diff mbox series

[hurd,commited] htl: Make pthread_setcanceltype / state a cancellation point

Message ID 20250315214009.3905005-1-samuel.thibault@ens-lyon.org
State New
Headers show
Series [hurd,commited] htl: Make pthread_setcanceltype / state a cancellation point | expand

Commit Message

Samuel Thibault March 15, 2025, 9:40 p.m. UTC
as expected by tst-cancel32.
---
 htl/pt-setcancelstate.c | 8 ++++++++
 htl/pt-setcanceltype.c  | 5 +++++
 sysdeps/htl/pthreadP.h  | 8 ++++++++
 3 files changed, 21 insertions(+)
diff mbox series

Patch

diff --git a/htl/pt-setcancelstate.c b/htl/pt-setcancelstate.c
index 6e09c260ea..0d5692e661 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 0b76fbfbd6..b33931c468 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 9479b9ef24..78ef4e7674 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)