1/* 2 * pthread_join.c 3 * 4 * Description: 5 * This translation unit implements functions related to thread 6 * synchronisation. 7 * 8 * -------------------------------------------------------------------------- 9 * 10 * Pthreads-win32 - POSIX Threads Library for Win32 11 * Copyright(C) 1998 John E. Bossom 12 * Copyright(C) 1999,2005 Pthreads-win32 contributors 13 * 14 * Contact Email: rpj@callisto.canberra.edu.au 15 * 16 * The current list of contributors is contained 17 * in the file CONTRIBUTORS included with the source 18 * code distribution. The list can also be seen at the 19 * following World Wide Web location: 20 * http://sources.redhat.com/pthreads-win32/contributors.html 21 * 22 * This library is free software; you can redistribute it and/or 23 * modify it under the terms of the GNU Lesser General Public 24 * License as published by the Free Software Foundation; either 25 * version 2 of the License, or (at your option) any later version. 26 * 27 * This library is distributed in the hope that it will be useful, 28 * but WITHOUT ANY WARRANTY; without even the implied warranty of 29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 30 * Lesser General Public License for more details. 31 * 32 * You should have received a copy of the GNU Lesser General Public 33 * License along with this library in the file COPYING.LIB; 34 * if not, write to the Free Software Foundation, Inc., 35 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 36 */ 37 38#include "pthread.h" 39#include "implement.h" 40 41/* 42 * Not needed yet, but defining it should indicate clashes with build target 43 * environment that should be fixed. 44 */ 45#if !defined(WINCE) 46# include <signal.h> 47#endif 48 49 50int 51pthread_join (pthread_t thread, void **value_ptr) 52 /* 53 * ------------------------------------------------------ 54 * DOCPUBLIC 55 * This function waits for 'thread' to terminate and 56 * returns the thread's exit value if 'value_ptr' is not 57 * NULL. This also detaches the thread on successful 58 * completion. 59 * 60 * PARAMETERS 61 * thread 62 * an instance of pthread_t 63 * 64 * value_ptr 65 * pointer to an instance of pointer to void 66 * 67 * 68 * DESCRIPTION 69 * This function waits for 'thread' to terminate and 70 * returns the thread's exit value if 'value_ptr' is not 71 * NULL. This also detaches the thread on successful 72 * completion. 73 * NOTE: detached threads cannot be joined or canceled 74 * 75 * RESULTS 76 * 0 'thread' has completed 77 * EINVAL thread is not a joinable thread, 78 * ESRCH no thread could be found with ID 'thread', 79 * ENOENT thread couldn't find it's own valid handle, 80 * EDEADLK attempt to join thread with self 81 * 82 * ------------------------------------------------------ 83 */ 84{ 85 int result; 86 pthread_t self; 87 ptw32_thread_t * tp = (ptw32_thread_t *) thread.p; 88 ptw32_mcs_local_node_t node; 89 90 ptw32_mcs_lock_acquire(&ptw32_thread_reuse_lock, &node); 91 92 if (NULL == tp 93 || thread.x != tp->ptHandle.x) 94 { 95 result = ESRCH; 96 } 97 else if (PTHREAD_CREATE_DETACHED == tp->detachState) 98 { 99 result = EINVAL; 100 } 101 else 102 { 103 result = 0; 104 } 105 106 ptw32_mcs_lock_release(&node); 107 108 if (result == 0) 109 { 110 /* 111 * The target thread is joinable and can't be reused before we join it. 112 */ 113 self = pthread_self(); 114 115 if (NULL == self.p) 116 { 117 result = ENOENT; 118 } 119 else if (pthread_equal (self, thread)) 120 { 121 result = EDEADLK; 122 } 123 else 124 { 125 /* 126 * Pthread_join is a cancelation point. 127 * If we are canceled then our target thread must not be 128 * detached (destroyed). This is guarranteed because 129 * pthreadCancelableWait will not return if we 130 * are canceled. 131 */ 132 result = pthreadCancelableWait (tp->threadH); 133 134 if (0 == result) 135 { 136 if (value_ptr != NULL) 137 { 138 *value_ptr = tp->exitStatus; 139 } 140 141 /* 142 * The result of making multiple simultaneous calls to 143 * pthread_join() or pthread_detach() specifying the same 144 * target is undefined. 145 */ 146 result = pthread_detach (thread); 147 } 148 else 149 { 150 result = ESRCH; 151 } 152 } 153 } 154 155 return (result); 156 157} /* pthread_join */ 158