git: afa70a8496e9 - main - libthr: add pthread_tryjoin_np()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 19 Jan 2026 16:57:16 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=afa70a8496e90fa751418be8d1b55e3d559a281a
commit afa70a8496e90fa751418be8d1b55e3d559a281a
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-01-18 12:26:46 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-01-19 16:49:57 +0000
libthr: add pthread_tryjoin_np()
Similar to the same glibc function.
Reviewed by: markj
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D54766
---
include/pthread_np.h | 1 +
lib/libthr/pthread.map | 4 ++++
lib/libthr/thread/thr_join.c | 55 +++++++++++++++++++++++++++++++++-----------
3 files changed, 46 insertions(+), 14 deletions(-)
diff --git a/include/pthread_np.h b/include/pthread_np.h
index a9e738540db4..04c64a748b72 100644
--- a/include/pthread_np.h
+++ b/include/pthread_np.h
@@ -65,6 +65,7 @@ int pthread_single_np(void);
void pthread_suspend_all_np(void);
int pthread_suspend_np(pthread_t);
int pthread_timedjoin_np(pthread_t, void **, const struct timespec *);
+int pthread_tryjoin_np(pthread_t, void **);
__END_DECLS
#endif
diff --git a/lib/libthr/pthread.map b/lib/libthr/pthread.map
index 3a5353a32dc3..ad0c28de98c1 100644
--- a/lib/libthr/pthread.map
+++ b/lib/libthr/pthread.map
@@ -342,3 +342,7 @@ FBSD_1.8 {
pthread_signals_unblock_np;
pthread_sigqueue;
};
+
+FBSD_1.9 {
+ pthread_tryjoin_np;
+};
diff --git a/lib/libthr/thread/thr_join.c b/lib/libthr/thread/thr_join.c
index 56b316ec0f51..33eb18638169 100644
--- a/lib/libthr/thread/thr_join.c
+++ b/lib/libthr/thread/thr_join.c
@@ -34,14 +34,17 @@
#include "thr_private.h"
int _pthread_peekjoin_np(pthread_t pthread, void **thread_return);
+int _pthread_tryjoin_np(pthread_t pthread, void **thread_return);
int _pthread_timedjoin_np(pthread_t pthread, void **thread_return,
const struct timespec *abstime);
-static int join_common(pthread_t, void **, const struct timespec *, bool peek);
+static int join_common(pthread_t, void **, const struct timespec *, bool peek,
+ bool try);
__weak_reference(_thr_join, pthread_join);
__weak_reference(_thr_join, _pthread_join);
__weak_reference(_pthread_timedjoin_np, pthread_timedjoin_np);
__weak_reference(_pthread_peekjoin_np, pthread_peekjoin_np);
+__weak_reference(_pthread_tryjoin_np, pthread_tryjoin_np);
static void
backout_join(struct pthread *pthread, struct pthread *curthread)
@@ -63,7 +66,7 @@ backout_join_pop(void *arg)
int
_thr_join(pthread_t pthread, void **thread_return)
{
- return (join_common(pthread, thread_return, NULL, false));
+ return (join_common(pthread, thread_return, NULL, false, false));
}
int
@@ -74,13 +77,34 @@ _pthread_timedjoin_np(pthread_t pthread, void **thread_return,
abstime->tv_nsec >= 1000000000)
return (EINVAL);
- return (join_common(pthread, thread_return, abstime, false));
+ return (join_common(pthread, thread_return, abstime, false, false));
}
int
_pthread_peekjoin_np(pthread_t pthread, void **thread_return)
{
- return (join_common(pthread, thread_return, NULL, true));
+ return (join_common(pthread, thread_return, NULL, true, false));
+}
+
+int
+_pthread_tryjoin_np(pthread_t pthread, void **thread_return)
+{
+ return (join_common(pthread, thread_return, NULL, false, true));
+}
+
+static void
+join_common_joined(struct pthread *pthread, struct pthread *curthread,
+ void **thread_return)
+{
+ void *tmp;
+
+ tmp = pthread->ret;
+ pthread->flags |= THR_FLAGS_DETACHED;
+ pthread->joiner = NULL;
+ _thr_try_gc(curthread, pthread); /* thread lock released */
+
+ if (thread_return != NULL)
+ *thread_return = tmp;
}
/*
@@ -89,11 +113,10 @@ _pthread_peekjoin_np(pthread_t pthread, void **thread_return)
*/
static int
join_common(pthread_t pthread, void **thread_return,
- const struct timespec *abstime, bool peek)
+ const struct timespec *abstime, bool peek, bool try)
{
struct pthread *curthread = _get_curthread();
struct timespec ts, ts2, *tsp;
- void *tmp;
long tid;
int ret;
@@ -127,12 +150,22 @@ join_common(pthread_t pthread, void **thread_return,
return (ret);
}
+ /* Only try to join. */
+ if (try) {
+ if (pthread->tid != TID_TERMINATED) {
+ THR_THREAD_UNLOCK(curthread, pthread);
+ return (EBUSY);
+ }
+ join_common_joined(pthread, curthread, thread_return);
+ return (0);
+ }
+
/* Set the running thread to be the joiner: */
pthread->joiner = curthread;
THR_THREAD_UNLOCK(curthread, pthread);
- THR_CLEANUP_PUSH(curthread, backout_join, pthread);
+ THR_CLEANUP_PUSH(curthread, backout_join_pop, pthread);
_thr_cancel_enter(curthread);
tid = pthread->tid;
@@ -160,14 +193,8 @@ join_common(pthread_t pthread, void **thread_return,
backout_join(pthread, curthread);
} else {
ret = 0;
- tmp = pthread->ret;
THR_THREAD_LOCK(curthread, pthread);
- pthread->flags |= THR_FLAGS_DETACHED;
- pthread->joiner = NULL;
- _thr_try_gc(curthread, pthread); /* thread lock released */
-
- if (thread_return != NULL)
- *thread_return = tmp;
+ join_common_joined(pthread, curthread, thread_return);
}
return (ret);
}