Bug 19366 - returning from a thread should disable cancellation
Summary: returning from a thread should disable cancellation
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: nptl (show other bugs)
Version: 2.22
: P2 normal
Target Milestone: 2.34
Assignee: Adhemerval Zanella
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-12-15 20:11 UTC by Luis Javier Merino
Modified: 2021-06-09 18:22 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
demo of thread acting on cancellation request while terminating (224 bytes, text/x-csrc)
2015-12-15 20:11 UTC, Luis Javier Merino
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Luis Javier Merino 2015-12-15 20:11:39 UTC
Created attachment 8848 [details]
demo of thread acting on cancellation request while terminating

Returning from a thread should behave as calling pthread_exit(), and XSH 2.95, under the epigraph "Thread Cancellation Cleanup Handlers" requires pthread_exit() to set the cancellation state and type to disabled and deferred, respectively.

The attached program is supposed to endlessly loop creating an asynchronously cancellable thread, and then cancelling and joining it. Instead of that, after a while, the program exits. This does not happen if the created thread calls pthread_exit() instead of returning.

Setting the cancellation state and type to disabled and deferred in nptl/pthread_create.c:START_THREAD_DEFN after returning from/long jumping out of start_routine fixes this test case. This fix is similar to one in musl (http://git.musl-libc.org/cgit/musl/commit/?id=36d8e972231c397194e513691d09f7d489de0a62), the test program deadlocks in musl prior to that commit.
Comment 1 Adhemerval Zanella 2021-06-09 18:22:19 UTC
The issue is fixed on 2.34 (8fe503f74e0a2ab41eec9bbae1e0ea8f5203716b), although it does fully follow the POSIX XSH 2.9.5 Thread Cancellation under the heading Thread Cancellation Cleanup Handlers that states that when a cancellation request is acted upon, or when a thread calls pthread_exit(), the thread first disables cancellation by setting its  cancelability state to PTHREAD_CANCEL_DISABLE and its cancelability type to PTHREAD_CANCEL_DEFERRED.  

The issue is _pthread_enable_asynccancel' explicit enabled asynchronous cancellation, so an interrupted syscall within the cancellation cleanup handlers might see an invalid cancelling type.  To fully fix it we will need to rewrite how cancellation is done (as my proposed solution to BZ#12683).

I will send a second part for this bug where a cancellation callback should see the expected cancellation state and type (although changing the cancellation state/type on cancellation callback is undefined).