Skip site navigation (1)Skip section navigation (2)
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>