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