git: 2f645d539c60 - stable/14 - pthread_setcancelstate(3): make it async-signal-safe

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Sat, 04 Jan 2025 03:57:48 UTC
The branch stable/14 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=2f645d539c6003601c5a09c156869a6c6334ec4c

commit 2f645d539c6003601c5a09c156869a6c6334ec4c
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-12-23 06:42:15 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-01-04 03:57:24 +0000

    pthread_setcancelstate(3): make it async-signal-safe
    
    (cherry picked from commit 030f48f78f96e0cdb30c960e1a11e5ae01d0eee8)
---
 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