Changeset View
Changeset View
Standalone View
Standalone View
lib/libthr/thread/thr_join.c
Context not available. | |||||
#include "thr_private.h" | #include "thr_private.h" | ||||
int _pthread_peekjoin_np(pthread_t pthread, void **thread_return); | |||||
int _pthread_timedjoin_np(pthread_t pthread, void **thread_return, | int _pthread_timedjoin_np(pthread_t pthread, void **thread_return, | ||||
const struct timespec *abstime); | const struct timespec *abstime); | ||||
static int join_common(pthread_t, void **, const struct timespec *); | 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(_thr_join, _pthread_join); | __weak_reference(_thr_join, _pthread_join); | ||||
__weak_reference(_pthread_timedjoin_np, pthread_timedjoin_np); | __weak_reference(_pthread_timedjoin_np, pthread_timedjoin_np); | ||||
__weak_reference(_pthread_peekjoin_np, pthread_peekjoin_np); | |||||
static void backout_join(void *arg) | static void backout_join(void *arg) | ||||
{ | { | ||||
Context not available. | |||||
int | int | ||||
_thr_join(pthread_t pthread, void **thread_return) | _thr_join(pthread_t pthread, void **thread_return) | ||||
{ | { | ||||
return (join_common(pthread, thread_return, NULL)); | return (join_common(pthread, thread_return, NULL, false)); | ||||
} | } | ||||
int | int | ||||
Context not available. | |||||
abstime->tv_nsec >= 1000000000) | abstime->tv_nsec >= 1000000000) | ||||
return (EINVAL); | 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)); | |||||
} | } | ||||
/* | /* | ||||
Context not available. | |||||
*/ | */ | ||||
static int | static int | ||||
join_common(pthread_t pthread, void **thread_return, | join_common(pthread_t pthread, void **thread_return, | ||||
const struct timespec *abstime) | const struct timespec *abstime, bool peek) | ||||
{ | { | ||||
struct pthread *curthread = _get_curthread(); | struct pthread *curthread = _get_curthread(); | ||||
struct timespec ts, ts2, *tsp; | struct timespec ts, ts2, *tsp; | ||||
void *tmp; | void *tmp; | ||||
long tid; | long tid; | ||||
int ret = 0; | int ret; | ||||
if (pthread == NULL) | if (pthread == NULL) | ||||
return (EINVAL); | return (EINVAL); | ||||
Context not available. | |||||
/* Multiple joiners are not supported. */ | /* Multiple joiners are not supported. */ | ||||
ret = ENOTSUP; | ret = ENOTSUP; | ||||
} | } | ||||
if (ret) { | if (ret != 0) { | ||||
THR_THREAD_UNLOCK(curthread, pthread); | THR_THREAD_UNLOCK(curthread, pthread); | ||||
return (ret); | 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: */ | /* Set the running thread to be the joiner: */ | ||||
pthread->joiner = curthread; | pthread->joiner = curthread; | ||||
Context not available. |