PERFORCE change 65509 for review

David Xu davidxu at FreeBSD.org
Fri Nov 19 20:21:40 PST 2004


http://perforce.freebsd.org/chv.cgi?CH=65509

Change 65509 by davidxu at davidxu_alona on 2004/11/20 04:21:13

	1. Fix buggy libpthread code, always call fork handler even if
	   there is only one thred.
	2. Reinit all mutexs thread holding in child process.

Affected files ...

.. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_fork.c#2 edit

Differences ...

==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_fork.c#2 (text+ko) ====

@@ -57,25 +57,20 @@
 	sigset_t sigset, oldset;
 	struct pthread *curthread;
 	struct pthread_atfork *af;
+	struct pthread_mutex *m;
 	pid_t ret;
 	int errsave;
 
-	if (!_kse_isthreaded())
+	if (!_thr_is_inited())
 		return (__sys_fork());
 
 	curthread = _get_curthread();
 
 	/*
-	 * Masks all signals until we reach a safe point in
-	 * _kse_single_thread, and the signal masks will be
-	 * restored in that function, for M:N thread, all 
-	 * signals were already masked in kernel atomically,
-	 * we only need to do this for bound thread.
+	 * Masks all signals until we reach a safe point.
 	 */
-	if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) {
-		SIGFILLSET(sigset);
-		__sys_sigprocmask(SIG_SETMASK, &sigset, &oldset);
-	}
+	SIGFILLSET(sigset);
+	__sys_sigprocmask(SIG_SETMASK, &sigset, &oldset);
 
 	_pthread_mutex_lock(&_thr_atfork_mutex);
 
@@ -86,30 +81,50 @@
 	}
 
 	/* Fork a new process: */
-	if ((_kse_isthreaded() != 0) && (__malloc_lock != NULL)) {
+	if ((_thr_isthreaded() != 0) && (__malloc_lock != NULL))
 		_spinlock(__malloc_lock);
-	}
+
 	if ((ret = __sys_fork()) == 0) {
 		/* Child process */
-		errsave = errno; 
+		errsave = errno;
+
+		/* clear aother thread locked us. */
+		_lock_reinit(&curthread->lock);
+		thr_self(&curthread->tid);
+
+		/* reinitialize libc spinlocks, this includes __malloc_lock. */
+		_thr_spinlock_init();
+
+		/*
+		 * reinitialize all mutexes the curthread owns, these include
+		 * _thr_fork_mutex.
+		 */
+		TAILQ_FOREACH(m, &curthread->mutexq, m_qe) {
+			_thr_mutex_reinit(curthread, &m);
+		}
+		/* Reinitialize lib kernel. */
+		_thr_single_thread(curthread);
+
+		/* Restore signal mask. */ 
+		__sys_sigprocmask(SIG_SETMASK, &oldset, NULL);
 
-		/* Kernel signal mask is restored in _kse_single_thread */
-		_kse_single_thread(curthread);
+		_pthread_mutex_unlock(&_thr_atfork_mutex);
 
 		/* Run down atfork child handlers. */
 		TAILQ_FOREACH(af, &_thr_atfork_list, qe) {
 			if (af->child != NULL)
 				af->child();
 		}
-		_thr_mutex_reinit(&_thr_atfork_mutex);
 	} else {
-		if ((_kse_isthreaded() != 0) && (__malloc_lock != NULL)) {
+		/* Parent process */
+		errsave = errno;
+
+		if ((_thr_isthreaded() != 0) && (__malloc_lock != NULL))
 			_spinunlock(__malloc_lock);
-		}
-		errsave = errno; 
-		if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) {
-			__sys_sigprocmask(SIG_SETMASK, &oldset, NULL);
-		}
+
+		/* Restore signal mask. */ 
+		__sys_sigprocmask(SIG_SETMASK, &oldset, NULL);
+
 		/* Run down atfork parent handlers. */
 		TAILQ_FOREACH(af, &_thr_atfork_list, qe) {
 			if (af->parent != NULL)


More information about the p4-projects mailing list