Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 9 Jan 2009 11:34:26 -0500
From:      Brian Fundakowski Feldman <green@freebsd.org>
To:        Julian Elischer <julian@elischer.org>
Cc:        hackers@freebsd.org, jasone@freebsd.org
Subject:   Re: threaded, forked, rethreaded processes will deadlock
Message-ID:  <20090109163426.GC2825@green.homeunix.org>
In-Reply-To: <4966F81C.3070406@elischer.org>
References:  <20090109031942.GA2825@green.homeunix.org> <Pine.GSO.4.64.0901082237001.28531@sea.ntplx.net> <20090109053117.GB2825@green.homeunix.org> <4966F81C.3070406@elischer.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, Jan 08, 2009 at 11:09:16PM -0800, Julian Elischer wrote:
> Brian Fundakowski Feldman wrote:
>> On Thu, Jan 08, 2009 at 10:44:20PM -0500, Daniel Eischen wrote:
>>> On Thu, 8 Jan 2009, Brian Fundakowski Feldman wrote:
>>> 
>>>> It appears that the post-fork hooks for malloc(3) are somewhat broken such that
>>>> when a threaded program forks, and then its child attempts to go threaded, it
>>>> deadlocks because it already appears to have locks held.  I am not familiar
>>>> enough with the current libthr/libc/rtld-elf interaction that I've been able
>>>> to fix it myself, unfortunately.
>>> There's really nothing to fix - according to POSIX you are only
>>> allowed to call async-signal-safe functions in the child forked
>>> from a threaded process.  If you are trying to do anything other
>>> than that, it may or may not work on FreeBSD, but it is not
>>> guaranteed and is not portable.
>>> 
>>> The rationale is that what is the point of forking and creating
>>> more threads, when you can just as easily create more threads in
>>> the parent without forking?  The only reason to fork from a threaded
>>> process is to call one of the exec() functions.
>> 
>> Well, it worked until the last major set of changes to malloc.  For me, the point
>> was that I was able to have transparent background worker threads in any program
>> regardless of its architecture, using the standard pthread fork hooks.  Could you
>> point me to the POSIX section covering fork and threads?  If it's really not
>> supposed to work then that's fine, but there's an awful lot of code there dedicated
>> to support going threaded again after a fork.
>> 
> 
> Practically, you can't go threaded again after a fork
> (by which I mean creating new threads or use things
> like mutexes etc.) in any posix system I know of.
> 
> It would require that:
>  The forking thread stop until:
>   Every other thread has released every resource it owns
>   and reports itself to be in a "safe quiescent state",
>   or at least report every resource it owns, especially
>   locks,
>  and
>  After the fork:
>   The child, post fork, to take ownership of all
>   of them, and free them.
> 
> You might be able to do that in a simple
> threaded program, but consider then that the libraries may have
> threads running in them of which you are unaware, and that
> some of the resources may interract with resources owned by the
> forking thread.
> 
> Add to this that there may be a signal thrown into this mix as well
> 
> (signals are the bane of thread developement)

Well, I wouldn't mind showing all of you what I can of what I had been doing
with the background threads -- it works pretty well modulo this particular
malloc lock bug.  Due to it being inappropriate to share library resources
between a child and parent for an open socket connection, I always considered
the only "safe" behavior to be going single-threaded for the duration of the fork
processes in both the parent and child, and the pthread_atfork(3) hooks have been
sufficient to do so.

-- 
Brian Fundakowski Feldman                           \'[ FreeBSD ]''''''''''\
  <> green@FreeBSD.org                               \  The Power to Serve! \
 Opinions expressed are my own.                       \,,,,,,,,,,,,,,,,,,,,,,\



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20090109163426.GC2825>