thr_join.c revision 50476
1254885Sdumbbell/* 2254885Sdumbbell * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. 3254885Sdumbbell * All rights reserved. 4254885Sdumbbell * 5254885Sdumbbell * Redistribution and use in source and binary forms, with or without 6254885Sdumbbell * modification, are permitted provided that the following conditions 7254885Sdumbbell * are met: 8254885Sdumbbell * 1. Redistributions of source code must retain the above copyright 9254885Sdumbbell * notice, this list of conditions and the following disclaimer. 10254885Sdumbbell * 2. Redistributions in binary form must reproduce the above copyright 11254885Sdumbbell * notice, this list of conditions and the following disclaimer in the 12254885Sdumbbell * documentation and/or other materials provided with the distribution. 13254885Sdumbbell * 3. All advertising materials mentioning features or use of this software 14254885Sdumbbell * must display the following acknowledgement: 15254885Sdumbbell * This product includes software developed by John Birrell. 16254885Sdumbbell * 4. Neither the name of the author nor the names of any co-contributors 17254885Sdumbbell * may be used to endorse or promote products derived from this software 18254885Sdumbbell * without specific prior written permission. 19254885Sdumbbell * 20254885Sdumbbell * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND 21254885Sdumbbell * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22254885Sdumbbell * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23254885Sdumbbell * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24254885Sdumbbell * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25254885Sdumbbell * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26254885Sdumbbell * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27254885Sdumbbell * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28254885Sdumbbell * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29254885Sdumbbell * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30254885Sdumbbell * SUCH DAMAGE. 31254885Sdumbbell * 32254885Sdumbbell * $FreeBSD: head/lib/libkse/thread/thr_join.c 50476 1999-08-28 00:22:10Z peter $ 33254885Sdumbbell */ 34254885Sdumbbell#include <errno.h> 35254885Sdumbbell#ifdef _THREAD_SAFE 36254885Sdumbbell#include <pthread.h> 37254885Sdumbbell#include "pthread_private.h" 38254885Sdumbbell 39254885Sdumbbellint 40254885Sdumbbellpthread_join(pthread_t pthread, void **thread_return) 41254885Sdumbbell{ 42254885Sdumbbell int ret = 0; 43254885Sdumbbell pthread_t pthread1 = NULL; 44254885Sdumbbell 45254885Sdumbbell /* Check if the caller has specified an invalid thread: */ 46254885Sdumbbell if (pthread == NULL || pthread->magic != PTHREAD_MAGIC) 47254885Sdumbbell /* Invalid thread: */ 48282199Sdumbbell return(EINVAL); 49254885Sdumbbell 50254885Sdumbbell /* Check if the caller has specified itself: */ 51254885Sdumbbell if (pthread == _thread_run) 52254885Sdumbbell /* Avoid a deadlock condition: */ 53254885Sdumbbell return(EDEADLK); 54254885Sdumbbell 55254885Sdumbbell /* 56254885Sdumbbell * Find the thread in the list of active threads or in the 57254885Sdumbbell * list of dead threads: 58254885Sdumbbell */ 59254885Sdumbbell if (_find_thread(pthread) == 0 || 60254885Sdumbbell _find_dead_thread(pthread) == 0) 61254885Sdumbbell pthread1 = pthread; 62254885Sdumbbell 63254885Sdumbbell if (pthread1 == NULL) 64254885Sdumbbell /* Return an error: */ 65254885Sdumbbell ret = ESRCH; 66254885Sdumbbell 67254885Sdumbbell /* Check if this thread has been detached: */ 68254885Sdumbbell else if ((pthread->attr.flags & PTHREAD_DETACHED) != 0) 69254885Sdumbbell /* Return an error: */ 70254885Sdumbbell ret = ESRCH; 71254885Sdumbbell 72254885Sdumbbell /* Check if the thread is not dead: */ 73254885Sdumbbell else if (pthread->state != PS_DEAD) { 74254885Sdumbbell /* Add the running thread to the join queue: */ 75254885Sdumbbell TAILQ_INSERT_TAIL(&(pthread->join_queue), _thread_run, qe); 76254885Sdumbbell 77254885Sdumbbell /* Schedule the next thread: */ 78254885Sdumbbell _thread_kern_sched_state(PS_JOIN, __FILE__, __LINE__); 79254885Sdumbbell 80254885Sdumbbell /* Check if the thread is not detached: */ 81254885Sdumbbell if ((pthread->attr.flags & PTHREAD_DETACHED) == 0) { 82254885Sdumbbell /* Check if the return value is required: */ 83254885Sdumbbell if (thread_return) 84254885Sdumbbell /* Return the thread's return value: */ 85254885Sdumbbell *thread_return = pthread->ret; 86254885Sdumbbell } 87254885Sdumbbell else 88254885Sdumbbell /* Return an error: */ 89254885Sdumbbell ret = ESRCH; 90254885Sdumbbell 91254885Sdumbbell /* Check if the return value is required: */ 92254885Sdumbbell } else if (thread_return != NULL) 93254885Sdumbbell /* Return the thread's return value: */ 94254885Sdumbbell *thread_return = pthread->ret; 95254885Sdumbbell 96254885Sdumbbell /* Return the completion status: */ 97254885Sdumbbell return (ret); 98254885Sdumbbell} 99254885Sdumbbell#endif 100254885Sdumbbell