Add pthread_peekjoin_np(3).
The function allows to peek at the thread exit status and even see return value, without joining (and thus finally destroying) the target thread. Reviewed by: markj Sponsored by: The FreeBSD Foundation (kib) MFC after: 2 weeks Differential revision: https://reviews.freebsd.org/D23676
This commit is contained in:
parent
a7b61c0af1
commit
132fb3dc99
@ -63,6 +63,7 @@ int pthread_mutex_setyieldloops_np(pthread_mutex_t *mutex, int count);
|
||||
int pthread_mutex_isowned_np(pthread_mutex_t *mutex);
|
||||
void pthread_resume_all_np(void);
|
||||
int pthread_resume_np(pthread_t);
|
||||
int pthread_peekjoin_np(pthread_t, void **);
|
||||
void pthread_set_name_np(pthread_t, const char *);
|
||||
int pthread_setaffinity_np(pthread_t, size_t, const cpuset_t *);
|
||||
int pthread_single_np(void);
|
||||
|
@ -326,3 +326,7 @@ FBSD_1.4 {
|
||||
FBSD_1.5 {
|
||||
pthread_get_name_np;
|
||||
};
|
||||
|
||||
FBSD_1.6 {
|
||||
pthread_peekjoin_np;
|
||||
};
|
||||
|
@ -36,13 +36,15 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "thr_private.h"
|
||||
|
||||
int _pthread_peekjoin_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 *);
|
||||
const struct timespec *abstime);
|
||||
static int join_common(pthread_t, void **, const struct timespec *, bool peek);
|
||||
|
||||
__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);
|
||||
|
||||
static void backout_join(void *arg)
|
||||
{
|
||||
@ -57,7 +59,7 @@ static void backout_join(void *arg)
|
||||
int
|
||||
_thr_join(pthread_t pthread, void **thread_return)
|
||||
{
|
||||
return (join_common(pthread, thread_return, NULL));
|
||||
return (join_common(pthread, thread_return, NULL, false));
|
||||
}
|
||||
|
||||
int
|
||||
@ -68,7 +70,13 @@ _pthread_timedjoin_np(pthread_t pthread, void **thread_return,
|
||||
abstime->tv_nsec >= 1000000000)
|
||||
return (EINVAL);
|
||||
|
||||
return (join_common(pthread, thread_return, abstime));
|
||||
return (join_common(pthread, thread_return, abstime, false));
|
||||
}
|
||||
|
||||
int
|
||||
_pthread_peekjoin_np(pthread_t pthread, void **thread_return)
|
||||
{
|
||||
return (join_common(pthread, thread_return, NULL, true));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -77,13 +85,13 @@ _pthread_timedjoin_np(pthread_t pthread, void **thread_return,
|
||||
*/
|
||||
static int
|
||||
join_common(pthread_t pthread, void **thread_return,
|
||||
const struct timespec *abstime)
|
||||
const struct timespec *abstime, bool peek)
|
||||
{
|
||||
struct pthread *curthread = _get_curthread();
|
||||
struct timespec ts, ts2, *tsp;
|
||||
void *tmp;
|
||||
long tid;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
if (pthread == NULL)
|
||||
return (EINVAL);
|
||||
@ -100,10 +108,21 @@ join_common(pthread_t pthread, void **thread_return,
|
||||
/* Multiple joiners are not supported. */
|
||||
ret = ENOTSUP;
|
||||
}
|
||||
if (ret) {
|
||||
if (ret != 0) {
|
||||
THR_THREAD_UNLOCK(curthread, pthread);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* Only peek into status, do not gc the thread. */
|
||||
if (peek) {
|
||||
if (pthread->tid != TID_TERMINATED)
|
||||
ret = EBUSY;
|
||||
else if (thread_return != NULL)
|
||||
*thread_return = pthread->ret;
|
||||
THR_THREAD_UNLOCK(curthread, pthread);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* Set the running thread to be the joiner: */
|
||||
pthread->joiner = curthread;
|
||||
|
||||
|
@ -500,7 +500,8 @@ PTHREAD_MLINKS+=pthread_spin_init.3 pthread_spin_destroy.3 \
|
||||
PTHREAD_MLINKS+=pthread_switch_add_np.3 pthread_switch_delete_np.3
|
||||
PTHREAD_MLINKS+=pthread_testcancel.3 pthread_setcancelstate.3 \
|
||||
pthread_testcancel.3 pthread_setcanceltype.3
|
||||
PTHREAD_MLINKS+=pthread_join.3 pthread_timedjoin_np.3
|
||||
PTHREAD_MLINKS+=pthread_join.3 pthread_peekjoin_np.3 \
|
||||
pthread_join.3 pthread_timedjoin_np.3
|
||||
.endif
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -30,13 +30,14 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 3, 2018
|
||||
.Dd February 13, 2019
|
||||
.Dt PTHREAD_JOIN 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm pthread_join ,
|
||||
.Nm pthread_peekjoin_np ,
|
||||
.Nm pthread_timedjoin_np
|
||||
.Nd wait for thread termination
|
||||
.Nd inspect thread termination state
|
||||
.Sh LIBRARY
|
||||
.Lb libpthread
|
||||
.Sh SYNOPSIS
|
||||
@ -45,7 +46,16 @@
|
||||
.Fn pthread_join "pthread_t thread" "void **value_ptr"
|
||||
.In pthread_np.h
|
||||
.Ft int
|
||||
.Fn pthread_timedjoin_np "pthread_t thread" "void **value_ptr" "const struct timespec *abstime"
|
||||
.Fo pthread_peekjoin_np
|
||||
.Fa "pthread_t thread"
|
||||
.Fa "void **value_ptr"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo pthread_timedjoin_np
|
||||
.Fa "pthread_t thread"
|
||||
.Fa "void **value_ptr"
|
||||
.Fa "const struct timespec *abstime"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn pthread_join
|
||||
@ -82,19 +92,30 @@ function except it will return
|
||||
.Er ETIMEDOUT
|
||||
if target thread does not exit before specified absolute time passes.
|
||||
.Pp
|
||||
The
|
||||
.Fn pthread_peekjoin_np
|
||||
only peeks into the exit status of the specified thread.
|
||||
If the thread has not exited, the
|
||||
.Er EBUSY
|
||||
error is returned.
|
||||
Otherwise, zero is returned and the thread exit value is optionally stored
|
||||
into the location of
|
||||
.Fa *value_ptr .
|
||||
The target thread is left unjoined and can be used as an argument for
|
||||
the
|
||||
.Fn pthread_join
|
||||
family of functions again.
|
||||
.Pp
|
||||
A thread that has exited but remains unjoined counts against
|
||||
[_POSIX_THREAD_THREADS_MAX].
|
||||
.Sh RETURN VALUES
|
||||
If successful, the
|
||||
.Fn pthread_join
|
||||
and
|
||||
.Fn pthread_timedjoin_np
|
||||
functions will return zero.
|
||||
Otherwise an error number will be returned to
|
||||
indicate the error.
|
||||
If successful, the described functions return zero.
|
||||
Otherwise an error number is returned to indicate the error or
|
||||
special condition.
|
||||
.Sh ERRORS
|
||||
The
|
||||
.Fn pthread_join
|
||||
.Fn pthread_join ,
|
||||
.Fn pthread_peekjoin_np ,
|
||||
and
|
||||
.Fn pthread_timedjoin_np
|
||||
functions will fail if:
|
||||
@ -125,6 +146,14 @@ The specified absolute time passed while
|
||||
.Fn pthread_timedjoin_np
|
||||
waited for thread exit.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn pthread_peekjoin_np
|
||||
function will also fail if:
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EBUSY
|
||||
The specified thread has not yet exited.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr wait 2 ,
|
||||
.Xr pthread_create 3
|
||||
@ -139,3 +168,7 @@ function is a
|
||||
.Fx
|
||||
extension which first appeared in
|
||||
.Fx 6.1 .
|
||||
Another extension, the
|
||||
.Fn pthread_peekjoin_np
|
||||
function, first appearead in
|
||||
.Fx 13.0 .
|
||||
|
Loading…
Reference in New Issue
Block a user