thr_join.c revision 35509
1893SN/A/*
214105Sbpb * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
3893SN/A * All rights reserved.
4893SN/A *
5893SN/A * Redistribution and use in source and binary forms, with or without
6893SN/A * modification, are permitted provided that the following conditions
72362SN/A * are met:
8893SN/A * 1. Redistributions of source code must retain the above copyright
92362SN/A *    notice, this list of conditions and the following disclaimer.
10893SN/A * 2. Redistributions in binary form must reproduce the above copyright
11893SN/A *    notice, this list of conditions and the following disclaimer in the
12893SN/A *    documentation and/or other materials provided with the distribution.
13893SN/A * 3. All advertising materials mentioning features or use of this software
14893SN/A *    must display the following acknowledgement:
15893SN/A *	This product includes software developed by John Birrell.
16893SN/A * 4. Neither the name of the author nor the names of any co-contributors
17893SN/A *    may be used to endorse or promote products derived from this software
18893SN/A *    without specific prior written permission.
19893SN/A *
20893SN/A * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
212362SN/A * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
222362SN/A * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
232362SN/A * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24893SN/A * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25893SN/A * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26893SN/A * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27893SN/A * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28893SN/A * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29893SN/A * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30893SN/A * SUCH DAMAGE.
31893SN/A *
32893SN/A */
33893SN/A#include <errno.h>
34893SN/A#ifdef _THREAD_SAFE
35893SN/A#include <pthread.h>
36893SN/A#include "pthread_private.h"
37893SN/A
38893SN/Aint
39893SN/Apthread_join(pthread_t pthread, void **thread_return)
40893SN/A{
41893SN/A	int ret = 0;
42893SN/A	pthread_t pthread1 = NULL;
43893SN/A
44893SN/A	/* Check if the caller has specified an invalid thread: */
45893SN/A	if (pthread == NULL || pthread->magic != PTHREAD_MAGIC)
46893SN/A		/* Invalid thread: */
47893SN/A		return(EINVAL);
48893SN/A
49893SN/A	/* Check if the caller has specified itself: */
50893SN/A	if (pthread == _thread_run)
51893SN/A		/* Avoid a deadlock condition: */
52893SN/A		return(EDEADLK);
53893SN/A
54893SN/A	/*
55893SN/A	 * Find the thread in the list of active threads or in the
56893SN/A	 * list of dead threads:
57893SN/A	 */
58893SN/A	if (_find_thread(pthread) == 0 ||
59893SN/A	    _find_dead_thread(pthread) == 0)
60893SN/A		pthread1  = pthread;
61893SN/A
62893SN/A	if (pthread1 == NULL)
63893SN/A		/* Return an error: */
64893SN/A		ret = ESRCH;
65893SN/A
66893SN/A	/* Check if this thread has been detached: */
67893SN/A	else if ((pthread->attr.flags & PTHREAD_DETACHED) != 0)
68893SN/A		/* Return an error: */
69893SN/A		ret = ESRCH;
70893SN/A
71893SN/A	/* Check if the thread is not dead: */
7214105Sbpb	else if (pthread->state != PS_DEAD) {
7314105Sbpb		/* Add the running thread to the join queue: */
7414105Sbpb		_thread_queue_enq(&(pthread->join_queue), _thread_run);
7514105Sbpb
7614105Sbpb		/* Schedule the next thread: */
7714105Sbpb		_thread_kern_sched_state(PS_JOIN, __FILE__, __LINE__);
78893SN/A
79893SN/A		/* Check if the thread is not detached: */
80893SN/A		if ((pthread->attr.flags & PTHREAD_DETACHED) == 0)
81893SN/A			/* Check if the return value is required: */
82893SN/A			if (thread_return)
83893SN/A				/* Return the thread's return value: */
84893SN/A				*thread_return = pthread->ret;
85893SN/A		else
86893SN/A			/* Return an error: */
87893SN/A			ret = ESRCH;
88893SN/A
89893SN/A	/* Check if the return value is required: */
90893SN/A	} else if (thread_return != NULL)
91893SN/A		/* Return the thread's return value: */
92893SN/A		*thread_return = pthread->ret;
93893SN/A
94893SN/A	/* Return the completion status: */
95893SN/A	return (ret);
96893SN/A}
97893SN/A#endif
98893SN/A