<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Verdana
}
--></style>
</head>
<body class='hmmessage'>
<A href="http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man2/fork.2.html">http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man2/fork.2.html</A><BR>
<BR>
<FONT face=""></FONT> <BR>
<FONT face="">There are limits to what you can do in the child process. To be totally safe you should restrict your-<FONT class=whiteout color=#ffffff size=1>self yourself</FONT><BR> self to only executing async-signal safe operations until such time as one of the exec functions is<BR> called. All APIs, including global data symbols, in any framework or library should be assumed to be<BR> unsafe after a <B>fork</B>() unless explicitly documented to be safe or async-signal safe. If you need to use<BR> these frameworks in the child process, you must exec. In this situation it is reasonable to exec your-<FONT class=whiteout color=#ffffff size=1>self. yourself.</FONT><BR> self.<BR><BR></FONT>
<FONT face=""></FONT> <BR>
<FONT face=""><A href="http://www.opengroup.org/onlinepubs/000095399/functions/fork.html">http://www.opengroup.org/onlinepubs/000095399/functions/fork.html</A></FONT><BR>
<FONT face=""></FONT> <BR><FONT face="">
Consequently, to avoid errors, the child process may only execute async-signal-safe operations until such time as one of the <I><A href="http://www.opengroup.org/onlinepubs/000095399/functions/exec.html">exec</A></I> functions is called. <SUP>[<A href="javascript:open_code('THR')">THR</A>]</SUP> <IMG border=0 alt="[Option Start]" src="http://www.opengroup.org/onlinepubs/000095399/images/opt-start.gif"> Fork handlers may be established by means of the <A href="http://www.opengroup.org/onlinepubs/000095399/functions/pthread_atfork.html"><I>pthread_atfork</I>()</A> function in order to maintain application invariants across <I>fork</I>() calls. <IMG border=0 alt="[Option End]" src="http://www.opengroup.org/onlinepubs/000095399/images/opt-end.gif"><BR>
<BR>
<BR>
I've run through a few theories so far.<BR>
Current thinking is related to what Tony said:<BR>
use pthread_atfork: <BR>
in prepare, stopworld <BR>
in parent, resumeworld <BR>
You don't want the child to be mid-gc for example, on another thread. Or mid-anything.<BR>
in child, reinitialize -- current thread is the only thread<BR>
<BR>
<BR>
Also in the cvsup code, ShutDown should just call DoShutDown immediately.<BR>
I did that, without m3core changes, and it hits an error in the pthread code, signaling a nonexistant thread.<BR>
pthread_atfork/child should address that -- child shouldn't retain a record of all the threads in the parent.<BR>
<BR>
<BR>
I don't have a theory as to why user threads work.<BR>
<BR>
<BR>
I experimented with malloc vs. static alloc vs. sbrk vs. mmap(private) vs. mmap(shared).<BR>
I was expecting more cases to act like mmap(shared), but none did, only it.<BR>
<BR>
<BR>
I experimented with having mutexes and condition variables be initialize up front instead of on-demand.<BR>
Via changing cvsup to lock/unlock or broadcast immediately upon creating them.<BR>
On the theory that might let them work across process.<BR>
That didn't make a difference.<BR>
<BR>
<BR>
- Jay<BR></FONT> </body>
</html>