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