Date: Thu, 03 Aug 2006 18:11:28 +0000 From: "Poul-Henning Kamp" <phk@phk.freebsd.dk> To: Daniel Eischen <deischen@freebsd.org> Cc: FreeBSD-gnats-submit@freebsd.org, freebsd-threads@freebsd.org Subject: Re: threads/101323: fork(2) in threaded programs broken. Message-ID: <49426.1154628688@critter.freebsd.dk> In-Reply-To: Your message of "Thu, 03 Aug 2006 13:51:45 -0400." <Pine.GSO.4.64.0608031348490.13543@sea.ntplx.net>
next in thread | previous in thread | raw e-mail | index | archive | help
In message <Pine.GSO.4.64.0608031348490.13543@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@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.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?49426.1154628688>