git: 030f48f78f96 - main - pthread_setcancelstate(3): make it async-signal-safe
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 28 Dec 2024 17:20:25 UTC
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=030f48f78f96e0cdb30c960e1a11e5ae01d0eee8 commit 030f48f78f96e0cdb30c960e1a11e5ae01d0eee8 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2024-12-23 06:42:15 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2024-12-28 17:01:50 +0000 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 --- lib/libthr/thread/thr_cancel.c | 12 ++++++------ share/man/man3/pthread_testcancel.3 | 6 ++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/libthr/thread/thr_cancel.c b/lib/libthr/thread/thr_cancel.c index 7622e306f937..4189a2640d14 100644 --- a/lib/libthr/thread/thr_cancel.c +++ b/lib/libthr/thread/thr_cancel.c @@ -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; diff --git a/share/man/man3/pthread_testcancel.3 b/share/man/man3/pthread_testcancel.3 index 2d2bb06c48e2..c74cdcfe943b 100644 --- a/share/man/man3/pthread_testcancel.3 +++ b/share/man/man3/pthread_testcancel.3 @@ -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