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

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Thu Dec 11 14:12:38 GMT 2025



On 08/12/25 17:03, Florian Weimer wrote:
> * 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.

The issue in fact the xread, since the function is actually checking
pthread_testcancel.  I will fix it.

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

Ack.

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

Ack, I will change the comment.

> 
>> 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)

Ack.

> 
> Thanks,
> Florian
> 



More information about the Libc-alpha mailing list