pthread_setcancelstate(3): make it async-signal-safe

by setting new cancel state and reading old cancel state from the
curthread structure atomic.

Note that this does not play well with async cancellation, since if
cancellation is enabled from a signal handler and cancellation request
is pending, the thread is cancelled immediately, calling user-defined
destructors, which all must be async-signal-safe (but this is a general
requirement for async cancellation anyway).

Reviewed by:	markj
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D48200
This commit is contained in:
Konstantin Belousov 2024-12-23 08:42:15 +02:00
parent a944e6d5c0
commit 030f48f78f
2 changed files with 12 additions and 6 deletions

View file

@ -83,22 +83,22 @@ int
_thr_setcancelstate(int state, int *oldstate)
{
struct pthread *curthread = _get_curthread();
int oldval;
int oldval, val;
oldval = curthread->cancel_enable;
switch (state) {
case PTHREAD_CANCEL_DISABLE:
curthread->cancel_enable = 0;
val = 0;
break;
case PTHREAD_CANCEL_ENABLE:
curthread->cancel_enable = 1;
if (curthread->cancel_async)
testcancel(curthread);
val = 1;
break;
default:
return (EINVAL);
}
oldval = atomic_swap_int(&curthread->cancel_enable, val);
if (state == PTHREAD_CANCEL_ENABLE && curthread->cancel_async)
testcancel(curthread);
if (oldstate != NULL) {
*oldstate = oldval ? PTHREAD_CANCEL_ENABLE :
PTHREAD_CANCEL_DISABLE;

View file

@ -34,6 +34,7 @@ are
.Dv PTHREAD_CANCEL_ENABLE
and
.Dv PTHREAD_CANCEL_DISABLE .
The function is async-signal-safe.
.Pp
The
.Fn pthread_setcanceltype
@ -248,6 +249,11 @@ function conforms to
.St -p1003.1-96 .
The standard allows implementations to make many more functions
cancellation points.
.Pp
The
.Fn pthread_setcancelstate
function is async-signal-safe as required by
.St -p1003.1-2024 .
.Sh AUTHORS
This manual page was written by
.An David Leonard Aq Mt d@openbsd.org