Page MenuHomeFreeBSD

D48200.id148394.diff
No OneTemporary

D48200.id148394.diff

diff --git a/lib/libthr/thread/thr_cancel.c b/lib/libthr/thread/thr_cancel.c
--- a/lib/libthr/thread/thr_cancel.c
+++ b/lib/libthr/thread/thr_cancel.c
@@ -83,25 +83,25 @@
_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);
}
- if (oldstate) {
+ 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;
+ PTHREAD_CANCEL_DISABLE;
}
return (0);
}
@@ -125,9 +125,9 @@
return (EINVAL);
}
- if (oldtype) {
+ if (oldtype != NULL) {
*oldtype = oldval ? PTHREAD_CANCEL_ASYNCHRONOUS :
- PTHREAD_CANCEL_DEFERRED;
+ PTHREAD_CANCEL_DEFERRED;
}
return (0);
}
@@ -166,9 +166,8 @@
_thr_cancel_leave(struct pthread *curthread, int maycancel)
{
curthread->cancel_point = 0;
- if (__predict_false(SHOULD_CANCEL(curthread) &&
- !THR_IN_CRITICAL(curthread) && maycancel))
- _pthread_exit(PTHREAD_CANCELED);
+ if (maycancel)
+ testcancel(curthread);
}
void
diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h
--- a/lib/libthr/thread/thr_private.h
+++ b/lib/libthr/thread/thr_private.h
@@ -562,8 +562,12 @@
/* Deferred threads from pthread_cond_signal. */
unsigned int *defer_waiters[MAX_DEFER_WAITERS];
-#define _pthread_endzero wake_addr
+ /* rtld thread-local dlerror message and seen control */
+ char dlerror_msg[512];
+ int dlerror_seen;
+
+#define _pthread_endzero wake_addr
struct wake_addr *wake_addr;
#define WAKE_ADDR(td) ((td)->wake_addr)
@@ -572,10 +576,6 @@
/* pthread_set/get_name_np */
char *name;
-
- /* rtld thread-local dlerror message and seen control */
- char dlerror_msg[512];
- int dlerror_seen;
};
#define THR_SHOULD_GC(thrd) \
diff --git a/lib/libthr/thread/thr_sig.c b/lib/libthr/thread/thr_sig.c
--- a/lib/libthr/thread/thr_sig.c
+++ b/lib/libthr/thread/thr_sig.c
@@ -185,8 +185,7 @@
}
static void
-sigcancel_handler(int sig __unused,
- siginfo_t *info __unused, ucontext_t *ucp)
+sigcancel_handler(int sig __unused, siginfo_t *info __unused, ucontext_t *ucp)
{
struct pthread *curthread = _get_curthread();
int err;
@@ -354,9 +353,11 @@
* on getting a signal before it agrees to return.
*/
if (curthread->cancel_point) {
- if (curthread->in_sigsuspend && ucp) {
- SIGADDSET(ucp->uc_sigmask, SIGCANCEL);
- curthread->unblock_sigcancel = 1;
+ if (curthread->in_sigsuspend) {
+ if (ucp != NULL) {
+ SIGADDSET(ucp->uc_sigmask, SIGCANCEL);
+ curthread->unblock_sigcancel = 1;
+ }
_thr_send_sig(curthread, SIGCANCEL);
} else
thr_wake(curthread->tid);
@@ -365,8 +366,8 @@
* asynchronous cancellation mode, act upon
* immediately.
*/
- _pthread_exit_mask(PTHREAD_CANCELED,
- ucp? &ucp->uc_sigmask : NULL);
+ _pthread_exit_mask(PTHREAD_CANCELED, ucp != NULL ?
+ &ucp->uc_sigmask : NULL);
}
}
@@ -405,9 +406,8 @@
{
uint32_t cycle;
- if (__predict_true((curthread->flags &
- (THR_FLAGS_NEED_SUSPEND | THR_FLAGS_SUSPENDED))
- != THR_FLAGS_NEED_SUSPEND))
+ if (__predict_true((curthread->flags & (THR_FLAGS_NEED_SUSPEND |
+ THR_FLAGS_SUSPENDED)) != THR_FLAGS_NEED_SUSPEND))
return;
if (curthread == _single_thread)
return;
@@ -664,7 +664,7 @@
}
int
-_sigsuspend(const sigset_t * set)
+_sigsuspend(const sigset_t *set)
{
sigset_t newset;
@@ -672,7 +672,7 @@
}
int
-__thr_sigsuspend(const sigset_t * set)
+__thr_sigsuspend(const sigset_t *set)
{
struct pthread *curthread;
sigset_t newset;
@@ -698,7 +698,7 @@
int
_sigtimedwait(const sigset_t *set, siginfo_t *info,
- const struct timespec * timeout)
+ const struct timespec *timeout)
{
sigset_t newset;
@@ -713,7 +713,7 @@
*/
int
__thr_sigtimedwait(const sigset_t *set, siginfo_t *info,
- const struct timespec * timeout)
+ const struct timespec *timeout)
{
struct pthread *curthread = _get_curthread();
sigset_t newset;
diff --git a/share/man/man3/pthread_testcancel.3 b/share/man/man3/pthread_testcancel.3
--- a/share/man/man3/pthread_testcancel.3
+++ b/share/man/man3/pthread_testcancel.3
@@ -34,6 +34,7 @@
.Dv PTHREAD_CANCEL_ENABLE
and
.Dv PTHREAD_CANCEL_DISABLE .
+The function is async-signal-safe.
.Pp
The
.Fn pthread_setcanceltype
@@ -248,6 +249,11 @@
.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

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 11, 4:40 PM (13 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29544162
Default Alt Text
D48200.id148394.diff (4 KB)

Event Timeline