threads/101323: fork(2) in threaded programs broken.

Poul-Henning Kamp phk at phk.freebsd.dk
Thu Aug 3 18:22:23 UTC 2006


The following reply was made to PR threads/101323; it has been noted by GNATS.

From: "Poul-Henning Kamp" <phk at phk.freebsd.dk>
To: Daniel Eischen <deischen at freebsd.org>
Cc: FreeBSD-gnats-submit at freebsd.org, freebsd-threads at freebsd.org
Subject: Re: threads/101323: fork(2) in threaded programs broken. 
Date: Thu, 03 Aug 2006 18:11:28 +0000

 In message <Pine.GSO.4.64.0608031348490.13543 at sea.ntplx.net>, Daniel Eischen writes:
 >On Thu, 3 Aug 2006, Poul-Henning Kamp wrote:
 >
 >> 	Forking a threaded process and starting a thread in the
 >> 	child process does not work.
 >>
 >> 	Tested on -current and releng_6 and both fails with more or
 >> 	less the same error message:
 >>
 >> 	Fatal error 'mutex is on list' at line 540 in file
 >> 	    /usr/src/lib/libpthread/thread/thr_mutex.c (errno = 0)
 >
 >fork()ing from a threaded process and making calls to functions
 >other than those defined as async-signal-safe is not allowed 
 >by POSIX.  libpthread intentionally doesn't support this.
 
 As you may probably be aware, I don't hold great respect for
 POSIX when it comes to writing useful APIs :-)
 
 First of all, there is a difference between POSIX explicitly
 disallowing something and POSIX not guaranteeing that something
 works.
 
 I belive we are in the second range here.
 
 Both Solaris and Linux support the usage which FreeBSD fails and
 as far as I can tell from our source-code, we also go a long way
 to make it work, just not long enough.
 
 As far as I can tell, all that's need to make it work correctly is
 the attached patch (which I've sent to Jason Evans since it's malloc related.)
 
 Poul-Henning
 
 
 Index: thr_fork.c
 ===================================================================
 RCS file: /home/ncvs/src/lib/libpthread/thread/thr_fork.c,v
 retrieving revision 1.37
 diff -u -r1.37 thr_fork.c
 --- thr_fork.c	13 Mar 2006 00:59:51 -0000	1.37
 +++ thr_fork.c	3 Aug 2006 18:09:44 -0000
 @@ -93,10 +93,10 @@
  	}
  
  	/* Fork a new process: */
 -	if (_kse_isthreaded() != 0) {
 -		_malloc_prefork();
 -	}
 -	if ((ret = __sys_fork()) == 0) {
 +	_malloc_prefork();
 +	ret = __sys_fork();
 +	_malloc_postfork();
 +	if (ret == 0) {
  		/* Child process */
  		errsave = errno; 
  
 @@ -110,9 +110,6 @@
  		}
  		_thr_mutex_reinit(&_thr_atfork_mutex);
  	} else {
 -		if (_kse_isthreaded() != 0) {
 -			_malloc_postfork();
 -		}
  		errsave = errno; 
  		if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) {
  			__sys_sigprocmask(SIG_SETMASK, &oldset, NULL);
 
 -- 
 Poul-Henning Kamp       | UNIX since Zilog Zeus 3.20
 phk at FreeBSD.ORG         | TCP/IP since RFC 956
 FreeBSD committer       | BSD since 4.3-tahoe    
 Never attribute to malice what can adequately be explained by incompetence.


More information about the freebsd-threads mailing list