Date: Fri, 31 Dec 2004 14:58:08 GMT From: David Xu <davidxu@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 67981 for review Message-ID: <200412311458.iBVEw8l8009297@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=67981 Change 67981 by davidxu@davidxu_tiger on 2004/12/31 14:57:36 rework join related code. Affected files ... .. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_exit.c#3 edit Differences ... ==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_exit.c#3 (text+ko) ==== @@ -86,9 +86,10 @@ _pthread_exit(void *status) { struct pthread *curthread = _get_curthread(); + struct pthread *joiner; /* Check if this thread is already in the process of exiting: */ - if ((curthread->flags & THR_FLAGS_EXITING) != 0) { + if ((curthread->flags & THR_CANCEL_EXITING) != 0) { char msg[128]; snprintf(msg, sizeof(msg), "Thread %p has called " "pthread_exit() from a destructor. POSIX 1003.1 " @@ -101,9 +102,11 @@ * from joining to this thread. */ THR_LOCK(curthread); - curthread->flags |= THR_FLAGS_EXITING; + curthread->cancelflags |= THR_CANCEL_EXITING; THR_UNLOCK(curthread); + _thr_exit_cleanup(); + /* Save the return value: */ curthread->ret = status; while (curthread->cleanup != NULL) { @@ -117,23 +120,34 @@ /* Run the thread-specific data destructors: */ _thread_cleanupspecific(); } + if (!_thr_isthreaded()) exit(0); - THR_LOCK_ACQUIRE(curthread, &_thread_list_lock); - /* Use thread_list_lock */ + + THREAD_LIST_LOCK(curthread); + if ((joiner = curthread->joiner) != NULL) { + THR_THREAD_LOCK(curthread, joiner); + if (joiner->join_status.thread == curthread) { + joiner->join_status.thread = NULL; + joiner->join_status.ret = curthread->ret; + joiner->cycle++; + umtx_wake((struct umtx *)&joiner->cycle, 1); + } + THR_THREAD_UNLOCK(curthread, joiner); + } _thread_active_threads--; if (_thread_active_threads == 0) { - THR_LOCK_RELEASE(curthread, &_thread_list_lock); + THREAD_LIST_UNLOCK(curthread); exit(0); /* Never reach! */ } - THR_LOCK_RELEASE(curthread, &_thread_list_lock); - - THR_LOCK_SWITCH(curthread); - THR_SET_STATE(curthread, PS_DEAD); - _thr_sched_switch_unlocked(curthread); + curthread->tlflags |= TLFLAGS_GC_SAFE; + THR_GCLIST_ADD(curthread); + THR_LOCK(curthread); + curthread->state = PS_DEAD; + THR_UNLOCK(curthread); + THREAD_LIST_UNLOCK(curthread); + thr_exit(&curthread->isdead); + PANIC("thr_exit() returned"); /* Never reach! */ - - /* This point should not be reached. */ - PANIC("Dead thread has resumed"); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200412311458.iBVEw8l8009297>