[PATCH v6 1/4] nptl: Set cancellation type and state on pthread_exit (BZ #28267)

Florian Weimer fweimer@redhat.com
Mon Dec 8 20:03:54 GMT 2025


* Adhemerval Zanella:

> diff --git a/nptl/tst-cleanup5.c b/nptl/tst-cleanup5.c
> new file mode 100644
> index 0000000000..582ce68063
> --- /dev/null
> +++ b/nptl/tst-cleanup5.c

> +/* Check if a thread with PTHREAD_CANCEL_DEFERRED cancellation on
> +   pthread_cleanup_pop sets the correct state and type as pthread_exit.  */
> +static void *
> +tf_cancel (void *arg)
> +{
> +  int *cancel_type = (int *) (arg);
> +
> +  TEST_VERIFY (pthread_setcanceltype (*cancel_type, NULL) == 0);
> +
> +  xpthread_barrier_wait (&b);
> +
> +  pthread_cleanup_push (clh, NULL);
> +
> +  xread (pipefds[0], &(char){0}, 1);
> +
> +  pthread_cleanup_pop (1);
> +
> +  return NULL;
> +}
> +
> +/* Check if a thread with PTHREAD_CANCEL_DEFERRED cancellation on
> +   blocked read() sets the correct state and type as pthread_exit.  */
> +static void *
> +tf_testcancel (void *arg)
> +{
> +  int *cancel_type = (int *) (arg);
> +
> +  TEST_VERIFY (pthread_setcanceltype (*cancel_type, NULL) == 0);
> +
> +  xpthread_barrier_wait (&b);
> +
> +  pthread_cleanup_push (clh, NULL);
> +
> +  xread (pipefds[0], &(char){0}, 1);
> +
> +  pthread_testcancel ();
> +
> +  pthread_cleanup_pop (1);
> +
> +  return NULL;
> +}

Gemini claims that the pthread_cancel is dead code.

I think there should probably be a test failure marker after each xread.

I think the references to PTHREAD_CANCEL_DEFERRED in the comments are no
longer correct?

> diff --git a/sysdeps/nptl/pthreadP.h b/sysdeps/nptl/pthreadP.h
> index 4f649267b3..881a37cedd 100644
> --- a/sysdeps/nptl/pthreadP.h
> +++ b/sysdeps/nptl/pthreadP.h
> @@ -252,7 +252,20 @@ __do_cancel (void *result)
>    self->result = result;
>  
>    /* Make sure we get no more cancellations.  */
> -  atomic_fetch_or_relaxed (&self->cancelhandling, EXITING_BITMASK);
> +  int oldval = atomic_load_relaxed (&self->cancelhandling);
> +  int newval;
> +  do
> +    {
> +      /* It is required by POSIX XSH 2.9.5 Thread Cancellation under the
> +	 heading Thread Cancellation Cleanup Handlers and also avoid further
> +	 cancellation wrapper to act on cancellation.  */
> +      newval = oldval | CANCELSTATE_BITMASK | EXITING_BITMASK;
> +      newval = newval & ~CANCELTYPE_BITMASK;
> +      if (oldval == newval)

“and also prevents further cancellation points from acting on
cancellation”

(I think)

Thanks,
Florian



More information about the Libc-alpha mailing list