[M3devel] 5.8.6 LINUXLIBC6 breakage, kernel 2.6.23, glibc-2.6-4

Tony Hosking hosking at cs.purdue.edu
Wed Apr 20 16:58:06 CEST 2011


Agreed.  But CVSup used it and we were trying to be supportive.

Antony Hosking | Associate Professor | Computer Science | Purdue University
305 N. University Street | West Lafayette | IN 47907 | USA
Office +1 765 494 6001 | Mobile +1 765 427 5484




On Apr 20, 2011, at 1:55 AM, Mika Nystrom wrote:

> 
> The rationale you directed us to says:
> 
> "It is suggested that programs that use fork() call an exec function very
> soon afterwards in the child process, thus resetting all states. In the
> meantime, only a short list of async-signal-safe library routines are
> promised to be available."
> 
> and later
> 
> "Application programs may not be aware that a multi-threaded library
> is in use, and they feel free to call any number of library routines
> between the fork() and exec calls, just as they always have. Indeed,
> they may be extant single-threaded programs and cannot, therefore,
> be expected to obey new restrictions imposed by the threads library."
> 
> In C maybe that is true.  In Modula-3, every application has *always*
> had to assume that there are other threads floating around.  There is
> no such thing as a "single-threaded" Modula-3 program---or at least,
> the distinction doesn't matter.
> 
> I really think fork-and-do-more-work is just a bug.  Maybe it is a special
> pattern used by some special program---maybe.  In any case support for it
> I do not think belongs in m3core.
> 
>     Mika
> 
> 
> 
> Jay K writes:
>> --_0203aac2-5c8e-49c7-9074-6bc448ecf342_
>> Content-Type: text/plain; charset="iso-8859-1"
>> Content-Transfer-Encoding: quoted-printable
>> 
>> 
>>> This change depends on pthread_atfork=2C for pthreads and user threads.
>> 
>> 
>> Clarification: There's no change described there for pthreads=2C and indeed=
>> =2C getting
>> this behavior with pthreads doesn't depend on using pthread_atfork. That is=
>> just
>> how pthreads are -- except optionally on Solaris (fork1() vs. forkall() vs.=
>> fork()).
>> The Solaris default used to be fork =3D> forkall().
>> The current Solaris default is fork =3D> fork1().
>> There really do exist on Solaris to functions you can call=2C fork1() and f=
>> orkall().
>> All other systems and the Posix specification have the "fork1" semantic for=
>> fork.
>> Therefore "fork1" is what we should provide unconditionally.
>> If you really want "forkall"=2C then you write:
>> #ifdef __sun
>> forkall()
>> #else
>> #error
>> #endif
>> 
>> 
>> 
>> and/or you go and hack up m3core/src/thread/POSIX=2C branch off m3core/src/=
>> thread/POSIX_FORKALL or such.
>> I don't expect anyone to ever do that.
>> 
>> 
>> 
>> The need for pthread_atfork is sort of different for user threads vs. pthre=
>> ads=2C but it is needed either way.
>> For pthreads=2C there is this problem -- at the time a thread calls fork()=
>> =2C what are other threads doing?
>> Answer: Anything.
>> Follow up question: What locks might they hold?
>> Answer: Any.
>> Follow up: So=2C if arbitrary locks are held=2C and you fork=2C and don't e=
>> xec=2C and the child process
>> attempts to use some of the locks that were held in the parent=2C and only =
>> the forking thread survived=2C
>> then the other threads will never leave their locks=2C and later attempts t=
>> o acquire them in the children
>> will deadlock. Therefore=2C what pthread_atfork provides for=2C what you ar=
>> e supposed to use it for=2C
>> is roughly speaking=2C right before fork()=2C in the parent=2C acquire all =
>> locks=2C and then fork()=2C and then in the
>> parent and children=2C release all locks. Therefore=2C you have to come up =
>> with a locking order.
>> 
>> 
>> 
>> Things are a little different for user threads.
>> In user threads=2C the existance of threads is established by virtue of a g=
>> lobal array or list of data describing the threads.
>> And a timer to occasionally preempt. When the timer interrupts=2C the sched=
>> uler picks another thread from the global
>> array/list. Previously=2C the data went unchanged when fork() was called. T=
>> herefore all threads survived.
>> What we do now is that in the child "handler" for pthread_atfork=2C is rein=
>> itialize the various data=2C so as to forget about
>> all but the current thread. Something like that.
>> 
>> 
>> 
>> I suspect if we had RTProcess.ForkBeforeExec and RTProcess.ForkBeforeMoreWo=
>> rk=2C then ForkBeforeExec
>> might get away with just fork() and ignore all this.
>> So far we have not drawn this line -- there is just the one fork and it is =
>> used prior to exec or do-more-work
>> and does the same thing w/o knowing what is to follow.
>> 
>> 
>> The Posix documentation I think describes this all fairly well.
>> Bing for "posix opengroup pthread_atfork".
>> Really. I think it is saying much of the same thing I am saying=2C but in l=
>> anguage that has received
>> much more thought. Be sure to read the "rationale" part.
>> 
>> 
>> - Jay
>> 
>> 
>> From: jay.krell at cornell.edu
>> To: mika at async.caltech.edu
>> CC: m3devel at elegosoft.com
>> Subject: RE: [M3devel] 5.8.6 LINUXLIBC6 breakage=2C kernel 2.6.23=2C glibc-=
>> 2.6-4
>> Date: Tue=2C 19 Apr 2011 15:06:38 +0000
>> 
>> 
>> 
>> 
>> 
>> 
>> 
>> 
>> Previously: user threads: all threads survived fork()
>> Previously: pthreads: only the thread calling fork() survived fork()
>> Now: user threads and pthreads: only the thread calling fork() survives for=
>> k()
>> This must be how pthreads behave=2C and this makes user threads and pthread=
>> s consistent.
>> 
>> This change depends on pthread_atfork=2C for pthreads and user threads.
>> It only really matters to the rare "fork + do more work" program=2C such as=
>> cvsupd.
>> Most programs either never fork=2C or exec almost immediately after fork.
>> 
>> 
>> pthread_atfork offers a good model.
>> A sort of "distributed" model.
>> You don't have to go and change all the calls to fork().
>> Each module with a need to do something before/after fork=2C calls the cent=
>> ral pthread_atfork=2C
>> and fork and pthread_atfork cooperate to do what is needed.
>> 
>> 
>> No function pointer is needed.
>> Instead move the code to m3core/thread.
>> 
>> 
>> If you really must not use -pthread=2C then you must implement pthread_atfo=
>> rk functionality
>> yourself and have all fork() calls go through your own fork() wrapper that =
>> cooperates
>> with your pthread_atfork replacement.
>> There is no free lunch -- there is a downside to this approach=2C as plain =
>> fork() calls
>> are ok and correct if pthread_atfork is used=2C but now become incorrect.
>> Pick your poison:
>> user thread/pthread inconsistency
>> cvsupd incompatibility with pthreads=20
>> user threads using pthread_atfork/-pthread=20
>> fork() calls having to go through a wrapper (ok -- you could miss this an=
>> d=20
>>  not likely notice -- only fork() calls in fork+do-more-work programs nee=
>> d the wrapper).=20
>> 
>> 
>> (Most of this has been explained multiple times=2C but people only pay atte=
>> ntion
>> when they think it affects them. I'm guilty of the same thing.)
>> 
>> 
>> - Jay
>> 
>> 
>>> To: jay.krell at cornell.edu
>>> Date: Mon=2C 18 Apr 2011 19:30:58 -0700
>>> From: mika at async.caltech.edu
>>> CC: m3devel at elegosoft.com
>>> Subject: Re: [M3devel] 5.8.6 LINUXLIBC6 breakage=2C kernel 2.6.23=2C glib=
>> c-2.6-4
>>> =20
>>> =20
>>> If you or Tony could describe roughly what you think needs to be done
>>> I'd be happy to look into it.
>>> =20
>>> The basic problem is that a decision that's made/described in
>>> m3core/thread/m3makefile needs to someone find its way to controlling
>>> what C code gets compiled elsewhere in the system.  Or maybe there should
>>> be an indirection into the thread library to pick up pthread_atfork (or n=
>> ot).
>>> =20
>>> But then again you still haven't explained why you made the user threads =
>> use
>>> pthread_atfork.  I just remove it from my installations=2C but then again=
>> I'm
>>> not trying to run CVSup so I don't know if it breaks that program to do s=
>> o.
>>> =20
>>>     Mika
>>> =20
>>> Jay K writes:
>>>> --_3dd397d4-ac1d-4148-a9ff-059d27dd794a_
>>>> Content-Type: text/plain=3B charset=3D"iso-8859-1"
>>>> Content-Transfer-Encoding: quoted-printable
>>>> 
>>>> 
>>>>> The following code from RTProcessC.c ensures that it is neeeded on eve=
>> ry =3D
>>>> Unix except
>>>>>> /* NOTE: Even userthreads now depends
>>>>>> * on availability of pthreads.
>>>>>> * This can be fixed if need be.
>>>>>> */
>>>> 
>>>> =3D20
>>>> Ok=3D2C "we" should probably go ahead and fix that.
>>>> I'll try to=3D2C but no promises=3D2C sorry.
>>>> =3D20
>>>> - Jay
>>>> =3D20
>>>>> From: hosking at cs.purdue.edu
>>>>> Date: Mon=3D2C 18 Apr 2011 18:11:26 -0400
>>>>> To: mika at async.caltech.edu
>>>>> CC: m3devel at elegosoft.com
>>>>> Subject: Re: [M3devel] 5.8.6 LINUXLIBC6 breakage=3D2C kernel 2.6.23=3D=
>> 2C glib=3D
>>>> c-2.6-4
>>>>> =3D20
>>>>> Probably unnecessary=3D2C given that I think there is another entry po=
>> int t=3D
>>>> o forking a process (I forget where) in the thread-specific portion of m=
>> 3co=3D
>>>> re. In which case the necessary work might be done there?
>>>>> =3D20
>>>>> On Apr 18=3D2C 2011=3D2C at 2:45 PM=3D2C Mika Nystrom wrote:
>>>>> =3D20
>>>>>> Tony Hosking writes:
>>>>>> ...
>>>>>>> pthread_atfork should not be needed under user threads.
>>>>>> ...
>>>>>> =3D20
>>>>>> The following code from RTProcessC.c ensures that it is neeeded on e=
>> ver=3D
>>>> y Unix except
>>>>>> FreeBSD before 6. The comment is from the checked-in source file.
>>>>>> =3D20
>>>>>> /* NOTE: Even userthreads now depends
>>>>>> * on availability of pthreads.
>>>>>> * This can be fixed if need be.
>>>>>> */
>>>>>> =3D20
>>>>>> INTEGER
>>>>>> __cdecl
>>>>>> RTProcess__RegisterForkHandlers(
>>>>>> ForkHandler prepare=3D2C
>>>>>> ForkHandler parent=3D2C
>>>>>> ForkHandler child)
>>>>>> {
>>>>>> /* FreeBSD < 6 lacks pthread_atfork. Would be good to use autoconf.
>>>>>> * VMS lacks pthread_atfork? Would be good to use autoconf.
>>>>>> * Win32 lacks pthread_atfork and fork. OK.
>>>>>> *
>>>>>> * As well=3D2C for all Posix systems=3D2C we could implement
>>>>>> * atfork ourselves=3D2C as long as we provide a fork()
>>>>>> * wrapper that code uses.
>>>>>> */
>>>>>> #if defined(_WIN32) \
>>>>>> || defined(__vms) \
>>>>>> || (defined(__FreeBSD__) /* && (__FreeBSD__ < 6)*/ )
>>>>>> return 0=3D3B
>>>>>> #else
>>>>>> while (1)
>>>>>> {
>>>>>> int i =3D3D pthread_atfork(prepare=3D2C parent=3D2C child)=3D3B
>>>>>> if (i !=3D3D EAGAIN)
>>>>>> return i=3D3B
>>>>>> sleep(0)=3D3B
>>>>>> }
>>>>>> #endif
>>>>>> }
>>>>> =3D20
>>>> 		 	   		  =3D
>>>> 
>>>> --_3dd397d4-ac1d-4148-a9ff-059d27dd794a_
>>>> Content-Type: text/html=3B charset=3D"iso-8859-1"
>>>> Content-Transfer-Encoding: quoted-printable
>>>> 
>>>> <html>
>>>> <head>
>>>> <style><!--
>>>> .hmmessage P
>>>> {
>>>> margin:0px=3D3B
>>>> padding:0px
>>>> }
>>>> body.hmmessage
>>>> {
>>>> font-size: 10pt=3D3B
>>>> font-family:Tahoma
>>>> }
>>>> --></style>
>>>> </head>
>>>> <body class=3D3D'hmmessage'>
>>>> &gt=3D3B The following code from RTProcessC.c ensures that it is neeeded=
>> on e=3D
>>>> very Unix except<BR>&gt=3D3B &gt=3D3B /* NOTE: Even userthreads now depe=
>> nds<BR>=3D
>>>> &gt=3D3B &gt=3D3B * on availability of pthreads.<BR>&gt=3D3B &gt=3D3B * =
>> This can be=3D
>>>> fixed if need be.<BR>&gt=3D3B &gt=3D3B */<BR><BR>
>>>> &nbsp=3D3B<BR>
>>>> Ok=3D2C "we" should probably go ahead and fix that.<BR>
>>>> I'll try to=3D2C but no&nbsp=3D3Bpromises=3D2C sorry.<BR>
>>>> &nbsp=3D3B<BR>
>>>> &nbsp=3D3B- Jay<BR>&nbsp=3D3B<BR>
>>>> &gt=3D3B From: hosking at cs.purdue.edu<BR>&gt=3D3B Date: Mon=3D2C 18 Apr 2=
>> 011 18:11=3D
>>>> :26 -0400<BR>&gt=3D3B To: mika at async.caltech.edu<BR>&gt=3D3B CC: m3devel=
>> @elegos=3D
>>>> oft.com<BR>&gt=3D3B Subject: Re: [M3devel] 5.8.6 LINUXLIBC6 breakage=3D2=
>> C kerne=3D
>>>> l 2.6.23=3D2C glibc-2.6-4<BR>&gt=3D3B <BR>&gt=3D3B Probably unnecessary=
>> =3D2C given =3D
>>>> that I think there is another entry point to forking a process (I forget=
>> wh=3D
>>>> ere) in the thread-specific portion of m3core. In which case the necessa=
>> ry =3D
>>>> work might be done there?<BR>&gt=3D3B <BR>&gt=3D3B On Apr 18=3D2C 2011=
>> =3D2C at 2:45=3D
>>>> PM=3D2C Mika Nystrom wrote:<BR>&gt=3D3B <BR>&gt=3D3B &gt=3D3B Tony Hosk=
>> ing writes:=3D
>>>> <BR>&gt=3D3B &gt=3D3B ...<BR>&gt=3D3B &gt=3D3B&gt=3D3B pthread_atfork sh=
>> ould not be n=3D
>>>> eeded under user threads.<BR>&gt=3D3B &gt=3D3B ...<BR>&gt=3D3B &gt=3D3B =
>> <BR>&gt=3D3B =3D
>>>> &gt=3D3B The following code from RTProcessC.c ensures that it is neeeded=
>> on e=3D
>>>> very Unix except<BR>&gt=3D3B &gt=3D3B FreeBSD before 6. The comment is f=
>> rom the=3D
>>>> checked-in source file.<BR>&gt=3D3B &gt=3D3B <BR>&gt=3D3B &gt=3D3B /* N=
>> OTE: Even u=3D
>>>> serthreads now depends<BR>&gt=3D3B &gt=3D3B * on availability of pthread=
>> s.<BR>&=3D
>>>> gt=3D3B &gt=3D3B * This can be fixed if need be.<BR>&gt=3D3B &gt=3D3B */=
>> <BR>&gt=3D3B =3D
>>>> &gt=3D3B <BR>&gt=3D3B &gt=3D3B INTEGER<BR>&gt=3D3B &gt=3D3B __cdecl<BR>&=
>> gt=3D3B &gt=3D3B =3D
>>>> RTProcess__RegisterForkHandlers(<BR>&gt=3D3B &gt=3D3B ForkHandler prepar=
>> e=3D2C<BR=3D
>>>>> &gt=3D3B &gt=3D3B ForkHandler parent=3D2C<BR>&gt=3D3B &gt=3D3B ForkHand=
>> ler child)<BR=3D
>>>>> &gt=3D3B &gt=3D3B {<BR>&gt=3D3B &gt=3D3B /* FreeBSD &lt=3D3B 6 lacks pt=
>> hread_atfork.=3D
>>>> Would be good to use autoconf.<BR>&gt=3D3B &gt=3D3B * VMS lacks pthread=
>> _atfork=3D
>>>> ? Would be good to use autoconf.<BR>&gt=3D3B &gt=3D3B * Win32 lacks pthr=
>> ead_atf=3D
>>>> ork and fork. OK.<BR>&gt=3D3B &gt=3D3B *<BR>&gt=3D3B &gt=3D3B * As well=
>> =3D2C for all =3D
>>>> Posix systems=3D2C we could implement<BR>&gt=3D3B &gt=3D3B * atfork ours=
>> elves=3D2C =3D
>>>> as long as we provide a fork()<BR>&gt=3D3B &gt=3D3B * wrapper that code =
>> uses.<B=3D
>>>> R>&gt=3D3B &gt=3D3B */<BR>&gt=3D3B &gt=3D3B #if defined(_WIN32) \<BR>&gt=
>> =3D3B &gt=3D3B =3D
>>>> || defined(__vms) \<BR>&gt=3D3B &gt=3D3B || (defined(__FreeBSD__) /* &am=
>> p=3D3B&am=3D
>>>> p=3D3B (__FreeBSD__ &lt=3D3B 6)*/ )<BR>&gt=3D3B &gt=3D3B return 0=3D3B<B=
>> R>&gt=3D3B &gt=3D
>>>> =3D3B #else<BR>&gt=3D3B &gt=3D3B while (1)<BR>&gt=3D3B &gt=3D3B {<BR>&gt=
>> =3D3B &gt=3D3B in=3D
>>>> t i =3D3D pthread_atfork(prepare=3D2C parent=3D2C child)=3D3B<BR>&gt=3D3=
>> B &gt=3D3B if (=3D
>>>> i !=3D3D EAGAIN)<BR>&gt=3D3B &gt=3D3B return i=3D3B<BR>&gt=3D3B &gt=3D3B=
>> sleep(0)=3D3B<BR=3D
>>>>> &gt=3D3B &gt=3D3B }<BR>&gt=3D3B &gt=3D3B #endif<BR>&gt=3D3B &gt=3D3B }<=
>> BR>&gt=3D3B <BR> =3D
>>>> 		 	   		  </body>
>>>> </html>=3D
>>>> 
>>>> --_3dd397d4-ac1d-4148-a9ff-059d27dd794a_--
>> 		 	   		  =
>> 
>> --_0203aac2-5c8e-49c7-9074-6bc448ecf342_
>> Content-Type: text/html; charset="iso-8859-1"
>> Content-Transfer-Encoding: quoted-printable
>> 
>> <html>
>> <head>
>> <style><!--
>> .hmmessage P
>> {
>> margin:0px=3B
>> padding:0px
>> }
>> body.hmmessage
>> {
>> font-size: 10pt=3B
>> font-family:Tahoma
>> }
>> --></style>
>> </head>
>> <body class=3D'hmmessage'>
>> &nbsp=3B&gt=3B This change depends on pthread_atfork=2C for pthreads and us=
>> er threads.<br><br><br>Clarification: There's no change described there for=
>> pthreads=2C and indeed=2C getting<br>this behavior with pthreads doesn't d=
>> epend on using pthread_atfork. That is just<br>how pthreads are -- except o=
>> ptionally on Solaris (fork1() vs. forkall() vs. fork()).<br>The Solaris def=
>> ault used to be fork =3D&gt=3B forkall().<br>The current Solaris default is=
>> fork =3D&gt=3B fork1().<br>There really do exist on Solaris to functions y=
>> ou can call=2C fork1() and forkall().<br>All other systems and the Posix sp=
>> ecification have the "fork1" semantic for fork.<br>Therefore "fork1" is wha=
>> t we should provide unconditionally.<br>If you really want "forkall"=2C the=
>> n you write:<br>#ifdef __sun<br>&nbsp=3B forkall()<br>#else<br>&nbsp=3B #er=
>> ror<br>#endif<br><br><br><br>and/or you go and hack up m3core/src/thread/PO=
>> SIX=2C branch off m3core/src/thread/POSIX_FORKALL or such.<br>I don't expec=
>> t anyone to ever do that.<br><br><br><br>The need for pthread_atfork is sor=
>> t of different for user threads vs. pthreads=2C but it is needed either way=
>> .<br>For pthreads=2C there is this problem -- at the time a thread calls fo=
>> rk()=2C what are other threads doing?<br>Answer: Anything.<br>Follow up que=
>> stion: What locks might they hold?<br>Answer: Any.<br>Follow up: So=2C if a=
>> rbitrary locks are held=2C and you fork=2C and don't exec=2C and the child =
>> process<br>attempts to use some of the locks that were held in the parent=
>> =2C and only the forking thread survived=2C<br>then the other threads will =
>> never leave their locks=2C and later attempts to acquire them in the childr=
>> en<br>will deadlock. Therefore=2C what pthread_atfork provides for=2C what =
>> you are supposed to use it for=2C<br>is roughly speaking=2C right before fo=
>> rk()=2C in the parent=2C acquire all locks=2C and then fork()=2C and then i=
>> n the<br>parent and children=2C release all locks. Therefore=2C you have to=
>> come up with a locking order.<br><br><br><br>Things are a little different=
>> for user threads.<br>In user threads=2C the existance of threads is establ=
>> ished by virtue of a global array or list of data describing the threads.<b=
>> r>And a timer to occasionally preempt. When the timer interrupts=2C the sch=
>> eduler picks another thread from the global<br>array/list. Previously=2C th=
>> e data went unchanged when fork() was called. Therefore all threads survive=
>> d.<br>What we do now is that in the child "handler" for pthread_atfork=2C i=
>> s reinitialize the various data=2C so as to forget about<br>all but the cur=
>> rent thread. Something like that.<br><br><br><br>I suspect if we had RTProc=
>> ess.ForkBeforeExec and RTProcess.ForkBeforeMoreWork=2C then ForkBeforeExec<=
>> br>might get away with just fork() and ignore all this.<br>So far we have n=
>> ot drawn this line -- there is just the one fork and it is used prior to ex=
>> ec or do-more-work<br>and does the same thing w/o knowing what is to follow=
>> .<br><br><br>The Posix documentation I think describes this all fairly well=
>> .<br>Bing for "posix opengroup pthread_atfork".<br>Really. I think it is sa=
>> ying much of the same thing I am saying=2C but in language that has receive=
>> d<br>much more thought. Be sure to read the "rationale" part.<br><br><br>&n=
>> bsp=3B- Jay<br><br><br><hr id=3D"stopSpelling">From: jay.krell at cornell.edu<=
>> br>To: mika at async.caltech.edu<br>CC: m3devel at elegosoft.com<br>Subject: RE: =
>> [M3devel] 5.8.6 LINUXLIBC6 breakage=2C kernel 2.6.23=2C glibc-2.6-4<br>Date=
>> : Tue=2C 19 Apr 2011 15:06:38 +0000<br><br>
>> 
>> <meta http-equiv=3D"Content-Type" content=3D"text/html=3B charset=3Dunicode=
>> ">
>> <meta name=3D"Generator" content=3D"Microsoft SafeHTML">
>> <style>
>> .ExternalClass .ecxhmmessage P
>> {padding:0px=3B}
>> .ExternalClass body.ecxhmmessage
>> {font-size:10pt=3Bfont-family:Tahoma=3B}
>> 
>> </style>
>> 
>> 
>> Previously: user threads: all threads survived fork()<br>Previously: pthrea=
>> ds: only the thread calling fork() survived fork()<br>Now: user threads and=
>> pthreads: only the thread calling fork() survives fork()<br>This must be h=
>> ow pthreads behave=2C and this makes user threads and pthreads consistent.<=
>> br>
>> This change depends on pthread_atfork=2C for pthreads and user threads.<br>=
>> It only really matters to the rare "fork + do more work" program=2C such as=
>> cvsupd.<br>Most programs either never fork=2C or exec almost immediately a=
>> fter fork.<br><br><br>pthread_atfork offers a good model.<br>A sort of "dis=
>> tributed" model.<br>You don't have to go and change all the calls to fork()=
>> .<br>Each module with a need to do something before/after fork=2C calls the=
>> central pthread_atfork=2C<br>and fork and pthread_atfork cooperate to do w=
>> hat is needed.<br><br><br>No function pointer is needed.<br>Instead move th=
>> e code to m3core/thread.<br><br><br>If you really must not use -pthread=2C =
>> then you must implement pthread_atfork functionality<br>yourself and have a=
>> ll fork() calls go through your own fork() wrapper that cooperates<br>with =
>> your pthread_atfork replacement.<br>There is no free lunch -- there is a do=
>> wnside to this approach=2C as plain fork() calls<br>are ok and correct if p=
>> thread_atfork is used=2C but now become incorrect.<br>Pick your poison:<br>=
>> &nbsp=3B user thread/pthread inconsistency<br>&nbsp=3B cvsupd incompatibili=
>> ty with pthreads <br>&nbsp=3B user threads using pthread_atfork/-pthread <b=
>> r>&nbsp=3B fork() calls having to go through a wrapper (ok -- you could mis=
>> s this and <br>&nbsp=3B&nbsp=3B not likely notice -- only fork() calls in f=
>> ork+do-more-work programs need the wrapper). <br><br><br>(Most of this has =
>> been explained multiple times=2C but people only pay attention<br>when they=
>> think it affects them. I'm guilty of the same thing.)<br><br><br>&nbsp=3B-=
>> Jay<br><br><br>&gt=3B To: jay.krell at cornell.edu<br>&gt=3B Date: Mon=2C 18 =
>> Apr 2011 19:30:58 -0700<br>&gt=3B From: mika at async.caltech.edu<br>&gt=3B CC=
>> : m3devel at elegosoft.com<br>&gt=3B Subject: Re: [M3devel] 5.8.6 LINUXLIBC6 b=
>> reakage=2C kernel 2.6.23=2C glibc-2.6-4<br>&gt=3B <br>&gt=3B <br>&gt=3B If =
>> you or Tony could describe roughly what you think needs to be done<br>&gt=
>> =3B I'd be happy to look into it.<br>&gt=3B <br>&gt=3B The basic problem is=
>> that a decision that's made/described in<br>&gt=3B m3core/thread/m3makefil=
>> e needs to someone find its way to controlling<br>&gt=3B what C code gets c=
>> ompiled elsewhere in the system.  Or maybe there should<br>&gt=3B be an ind=
>> irection into the thread library to pick up pthread_atfork (or not).<br>&gt=
>> =3B <br>&gt=3B But then again you still haven't explained why you made the =
>> user threads use<br>&gt=3B pthread_atfork.  I just remove it from my instal=
>> lations=2C but then again I'm<br>&gt=3B not trying to run CVSup so I don't =
>> know if it breaks that program to do so.<br>&gt=3B <br>&gt=3B      Mika<br>=
>> &gt=3B <br>&gt=3B Jay K writes:<br>&gt=3B &gt=3B--_3dd397d4-ac1d-4148-a9ff-=
>> 059d27dd794a_<br>&gt=3B &gt=3BContent-Type: text/plain=3B charset=3D"iso-88=
>> 59-1"<br>&gt=3B &gt=3BContent-Transfer-Encoding: quoted-printable<br>&gt=3B=
>> &gt=3B<br>&gt=3B &gt=3B<br>&gt=3B &gt=3B&gt=3B The following code from RTP=
>> rocessC.c ensures that it is neeeded on every =3D<br>&gt=3B &gt=3BUnix exce=
>> pt<br>&gt=3B &gt=3B&gt=3B &gt=3B /* NOTE: Even userthreads now depends<br>&=
>> gt=3B &gt=3B&gt=3B &gt=3B * on availability of pthreads.<br>&gt=3B &gt=3B&g=
>> t=3B &gt=3B * This can be fixed if need be.<br>&gt=3B &gt=3B&gt=3B &gt=3B *=
>> /<br>&gt=3B &gt=3B<br>&gt=3B &gt=3B=3D20<br>&gt=3B &gt=3BOk=3D2C "we" shoul=
>> d probably go ahead and fix that.<br>&gt=3B &gt=3BI'll try to=3D2C but no p=
>> romises=3D2C sorry.<br>&gt=3B &gt=3B=3D20<br>&gt=3B &gt=3B - Jay<br>&gt=3B =
>> &gt=3B=3D20<br>&gt=3B &gt=3B&gt=3B From: hosking at cs.purdue.edu<br>&gt=3B &g=
>> t=3B&gt=3B Date: Mon=3D2C 18 Apr 2011 18:11:26 -0400<br>&gt=3B &gt=3B&gt=3B=
>> To: mika at async.caltech.edu<br>&gt=3B &gt=3B&gt=3B CC: m3devel at elegosoft.co=
>> m<br>&gt=3B &gt=3B&gt=3B Subject: Re: [M3devel] 5.8.6 LINUXLIBC6 breakage=
>> =3D2C kernel 2.6.23=3D2C glib=3D<br>&gt=3B &gt=3Bc-2.6-4<br>&gt=3B &gt=3B&g=
>> t=3B=3D20<br>&gt=3B &gt=3B&gt=3B Probably unnecessary=3D2C given that I thi=
>> nk there is another entry point t=3D<br>&gt=3B &gt=3Bo forking a process (I=
>> forget where) in the thread-specific portion of m3co=3D<br>&gt=3B &gt=3Bre=
>> . In which case the necessary work might be done there?<br>&gt=3B &gt=3B&gt=
>> =3B=3D20<br>&gt=3B &gt=3B&gt=3B On Apr 18=3D2C 2011=3D2C at 2:45 PM=3D2C Mi=
>> ka Nystrom wrote:<br>&gt=3B &gt=3B&gt=3B=3D20<br>&gt=3B &gt=3B&gt=3B &gt=3B=
>> Tony Hosking writes:<br>&gt=3B &gt=3B&gt=3B &gt=3B ...<br>&gt=3B &gt=3B&gt=
>> =3B &gt=3B&gt=3B pthread_atfork should not be needed under user threads.<br=
>>> &gt=3B &gt=3B&gt=3B &gt=3B ...<br>&gt=3B &gt=3B&gt=3B &gt=3B=3D20<br>&gt=
>> =3B &gt=3B&gt=3B &gt=3B The following code from RTProcessC.c ensures that i=
>> t is neeeded on ever=3D<br>&gt=3B &gt=3By Unix except<br>&gt=3B &gt=3B&gt=
>> =3B &gt=3B FreeBSD before 6. The comment is from the checked-in source file=
>> .<br>&gt=3B &gt=3B&gt=3B &gt=3B=3D20<br>&gt=3B &gt=3B&gt=3B &gt=3B /* NOTE:=
>> Even userthreads now depends<br>&gt=3B &gt=3B&gt=3B &gt=3B * on availabili=
>> ty of pthreads.<br>&gt=3B &gt=3B&gt=3B &gt=3B * This can be fixed if need b=
>> e.<br>&gt=3B &gt=3B&gt=3B &gt=3B */<br>&gt=3B &gt=3B&gt=3B &gt=3B=3D20<br>&=
>> gt=3B &gt=3B&gt=3B &gt=3B INTEGER<br>&gt=3B &gt=3B&gt=3B &gt=3B __cdecl<br>=
>> &gt=3B &gt=3B&gt=3B &gt=3B RTProcess__RegisterForkHandlers(<br>&gt=3B &gt=
>> =3B&gt=3B &gt=3B ForkHandler prepare=3D2C<br>&gt=3B &gt=3B&gt=3B &gt=3B For=
>> kHandler parent=3D2C<br>&gt=3B &gt=3B&gt=3B &gt=3B ForkHandler child)<br>&g=
>> t=3B &gt=3B&gt=3B &gt=3B {<br>&gt=3B &gt=3B&gt=3B &gt=3B /* FreeBSD &lt=3B =
>> 6 lacks pthread_atfork. Would be good to use autoconf.<br>&gt=3B &gt=3B&gt=
>> =3B &gt=3B * VMS lacks pthread_atfork? Would be good to use autoconf.<br>&g=
>> t=3B &gt=3B&gt=3B &gt=3B * Win32 lacks pthread_atfork and fork. OK.<br>&gt=
>> =3B &gt=3B&gt=3B &gt=3B *<br>&gt=3B &gt=3B&gt=3B &gt=3B * As well=3D2C for =
>> all Posix systems=3D2C we could implement<br>&gt=3B &gt=3B&gt=3B &gt=3B * a=
>> tfork ourselves=3D2C as long as we provide a fork()<br>&gt=3B &gt=3B&gt=3B =
>> &gt=3B * wrapper that code uses.<br>&gt=3B &gt=3B&gt=3B &gt=3B */<br>&gt=3B=
>> &gt=3B&gt=3B &gt=3B #if defined(_WIN32) \<br>&gt=3B &gt=3B&gt=3B &gt=3B ||=
>> defined(__vms) \<br>&gt=3B &gt=3B&gt=3B &gt=3B || (defined(__FreeBSD__) /*=
>> &amp=3B&amp=3B (__FreeBSD__ &lt=3B 6)*/ )<br>&gt=3B &gt=3B&gt=3B &gt=3B re=
>> turn 0=3D3B<br>&gt=3B &gt=3B&gt=3B &gt=3B #else<br>&gt=3B &gt=3B&gt=3B &gt=
>> =3B while (1)<br>&gt=3B &gt=3B&gt=3B &gt=3B {<br>&gt=3B &gt=3B&gt=3B &gt=3B=
>> int i =3D3D pthread_atfork(prepare=3D2C parent=3D2C child)=3D3B<br>&gt=3B =
>> &gt=3B&gt=3B &gt=3B if (i !=3D3D EAGAIN)<br>&gt=3B &gt=3B&gt=3B &gt=3B retu=
>> rn i=3D3B<br>&gt=3B &gt=3B&gt=3B &gt=3B sleep(0)=3D3B<br>&gt=3B &gt=3B&gt=
>> =3B &gt=3B }<br>&gt=3B &gt=3B&gt=3B &gt=3B #endif<br>&gt=3B &gt=3B&gt=3B &g=
>> t=3B }<br>&gt=3B &gt=3B&gt=3B=3D20<br>&gt=3B &gt=3B 		 	   		  =3D<br>&gt=
>> =3B &gt=3B<br>&gt=3B &gt=3B--_3dd397d4-ac1d-4148-a9ff-059d27dd794a_<br>&gt=
>> =3B &gt=3BContent-Type: text/html=3B charset=3D"iso-8859-1"<br>&gt=3B &gt=
>> =3BContent-Transfer-Encoding: quoted-printable<br>&gt=3B &gt=3B<br>&gt=3B &=
>> gt=3B&lt=3Bhtml&gt=3B<br>&gt=3B &gt=3B&lt=3Bhead&gt=3B<br>&gt=3B &gt=3B&lt=
>> =3Bstyle&gt=3B&lt=3B!--<br>&gt=3B &gt=3B.hmmessage P<br>&gt=3B &gt=3B{<br>&=
>> gt=3B &gt=3Bmargin:0px=3D3B<br>&gt=3B &gt=3Bpadding:0px<br>&gt=3B &gt=3B}<b=
>> r>&gt=3B &gt=3Bbody.hmmessage<br>&gt=3B &gt=3B{<br>&gt=3B &gt=3Bfont-size: =
>> 10pt=3D3B<br>&gt=3B &gt=3Bfont-family:Tahoma<br>&gt=3B &gt=3B}<br>&gt=3B &g=
>> t=3B--&gt=3B&lt=3B/style&gt=3B<br>&gt=3B &gt=3B&lt=3B/head&gt=3B<br>&gt=3B =
>> &gt=3B&lt=3Bbody class=3D3D'hmmessage'&gt=3B<br>&gt=3B &gt=3B&amp=3Bgt=3D3B=
>> The following code from RTProcessC.c ensures that it is neeeded on e=3D<br=
>>> &gt=3B &gt=3Bvery Unix except&lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B /=
>> * NOTE: Even userthreads now depends&lt=3BBR&gt=3B=3D<br>&gt=3B &gt=3B&amp=
>> =3Bgt=3D3B &amp=3Bgt=3D3B * on availability of pthreads.&lt=3BBR&gt=3B&amp=
>> =3Bgt=3D3B &amp=3Bgt=3D3B * This can be=3D<br>&gt=3B &gt=3B fixed if need b=
>> e.&lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B */&lt=3BBR&gt=3B&lt=3BBR&gt=
>> =3B<br>&gt=3B &gt=3B&amp=3Bnbsp=3D3B&lt=3BBR&gt=3B<br>&gt=3B &gt=3BOk=3D2C =
>> "we" should probably go ahead and fix that.&lt=3BBR&gt=3B<br>&gt=3B &gt=3BI=
>> 'll try to=3D2C but no&amp=3Bnbsp=3D3Bpromises=3D2C sorry.&lt=3BBR&gt=3B<br=
>>> &gt=3B &gt=3B&amp=3Bnbsp=3D3B&lt=3BBR&gt=3B<br>&gt=3B &gt=3B&amp=3Bnbsp=3D=
>> 3B- Jay&lt=3BBR&gt=3B&amp=3Bnbsp=3D3B&lt=3BBR&gt=3B<br>&gt=3B &gt=3B&amp=3B=
>> gt=3D3B From: hosking at cs.purdue.edu&lt=3BBR&gt=3B&amp=3Bgt=3D3B Date: Mon=
>> =3D2C 18 Apr 2011 18:11=3D<br>&gt=3B &gt=3B:26 -0400&lt=3BBR&gt=3B&amp=3Bgt=
>> =3D3B To: mika at async.caltech.edu&lt=3BBR&gt=3B&amp=3Bgt=3D3B CC: m3devel at el=
>> egos=3D<br>&gt=3B &gt=3Boft.com&lt=3BBR&gt=3B&amp=3Bgt=3D3B Subject: Re: [M=
>> 3devel] 5.8.6 LINUXLIBC6 breakage=3D2C kerne=3D<br>&gt=3B &gt=3Bl 2.6.23=3D=
>> 2C glibc-2.6-4&lt=3BBR&gt=3B&amp=3Bgt=3D3B &lt=3BBR&gt=3B&amp=3Bgt=3D3B Pro=
>> bably unnecessary=3D2C given =3D<br>&gt=3B &gt=3Bthat I think there is anot=
>> her entry point to forking a process (I forget wh=3D<br>&gt=3B &gt=3Bere) i=
>> n the thread-specific portion of m3core. In which case the necessary =3D<br=
>>> &gt=3B &gt=3Bwork might be done there?&lt=3BBR&gt=3B&amp=3Bgt=3D3B &lt=3BB=
>> R&gt=3B&amp=3Bgt=3D3B On Apr 18=3D2C 2011=3D2C at 2:45=3D<br>&gt=3B &gt=3B =
>> PM=3D2C Mika Nystrom wrote:&lt=3BBR&gt=3B&amp=3Bgt=3D3B &lt=3BBR&gt=3B&amp=
>> =3Bgt=3D3B &amp=3Bgt=3D3B Tony Hosking writes:=3D<br>&gt=3B &gt=3B&lt=3BBR&=
>> gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B ...&lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bg=
>> t=3D3B&amp=3Bgt=3D3B pthread_atfork should not be n=3D<br>&gt=3B &gt=3Beede=
>> d under user threads.&lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B ...&lt=3BB=
>> R&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B &lt=3BBR&gt=3B&amp=3Bgt=3D3B =3D<br>&g=
>> t=3B &gt=3B&amp=3Bgt=3D3B The following code from RTProcessC.c ensures that=
>> it is neeeded on e=3D<br>&gt=3B &gt=3Bvery Unix except&lt=3BBR&gt=3B&amp=
>> =3Bgt=3D3B &amp=3Bgt=3D3B FreeBSD before 6. The comment is from the=3D<br>&=
>> gt=3B &gt=3B checked-in source file.&lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=
>> =3D3B &lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B /* NOTE: Even u=3D<br>&gt=
>> =3B &gt=3Bserthreads now depends&lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B=
>> * on availability of pthreads.&lt=3BBR&gt=3B&amp=3B=3D<br>&gt=3B &gt=3Bgt=
>> =3D3B &amp=3Bgt=3D3B * This can be fixed if need be.&lt=3BBR&gt=3B&amp=3Bgt=
>> =3D3B &amp=3Bgt=3D3B */&lt=3BBR&gt=3B&amp=3Bgt=3D3B =3D<br>&gt=3B &gt=3B&am=
>> p=3Bgt=3D3B &lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B INTEGER&lt=3BBR&gt=
>> =3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B __cdecl&lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=
>> =3Bgt=3D3B =3D<br>&gt=3B &gt=3BRTProcess__RegisterForkHandlers(&lt=3BBR&gt=
>> =3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B ForkHandler prepare=3D2C&lt=3BBR=3D<br>&gt=
>> =3B &gt=3B&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B ForkHandler parent=3D2C&lt=3B=
>> BR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B ForkHandler child)&lt=3BBR=3D<br>&gt=
>> =3B &gt=3B&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B {&lt=3BBR&gt=3B&amp=3Bgt=3D3B=
>> &amp=3Bgt=3D3B /* FreeBSD &amp=3Blt=3D3B 6 lacks pthread_atfork.=3D<br>&gt=
>> =3B &gt=3B Would be good to use autoconf.&lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=
>> =3Bgt=3D3B * VMS lacks pthread_atfork=3D<br>&gt=3B &gt=3B? Would be good to=
>> use autoconf.&lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B * Win32 lacks pth=
>> read_atf=3D<br>&gt=3B &gt=3Bork and fork. OK.&lt=3BBR&gt=3B&amp=3Bgt=3D3B &=
>> amp=3Bgt=3D3B *&lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B * As well=3D2C f=
>> or all =3D<br>&gt=3B &gt=3BPosix systems=3D2C we could implement&lt=3BBR&gt=
>> =3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B * atfork ourselves=3D2C =3D<br>&gt=3B &gt=
>> =3Bas long as we provide a fork()&lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3=
>> B * wrapper that code uses.&lt=3BB=3D<br>&gt=3B &gt=3BR&gt=3B&amp=3Bgt=3D3B=
>> &amp=3Bgt=3D3B */&lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B #if defined(_=
>> WIN32) \&lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B =3D<br>&gt=3B &gt=3B|| =
>> defined(__vms) \&lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B || (defined(__F=
>> reeBSD__) /* &amp=3Bamp=3D3B&amp=3Bam=3D<br>&gt=3B &gt=3Bp=3D3B (__FreeBSD_=
>> _ &amp=3Blt=3D3B 6)*/ )&lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B return 0=
>> =3D3B&lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D<br>&gt=3B &gt=3B=3D3B #else&=
>> lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B while (1)&lt=3BBR&gt=3B&amp=3Bgt=
>> =3D3B &amp=3Bgt=3D3B {&lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B in=3D<br>=
>> &gt=3B &gt=3Bt i =3D3D pthread_atfork(prepare=3D2C parent=3D2C child)=3D3B&=
>> lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B if (=3D<br>&gt=3B &gt=3Bi !=3D3D=
>> EAGAIN)&lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B return i=3D3B&lt=3BBR&g=
>> t=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B sleep(0)=3D3B&lt=3BBR=3D<br>&gt=3B &gt=3B=
>> &gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B }&lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=
>> =3D3B #endif&lt=3BBR&gt=3B&amp=3Bgt=3D3B &amp=3Bgt=3D3B }&lt=3BBR&gt=3B&amp=
>> =3Bgt=3D3B &lt=3BBR&gt=3B =3D<br>&gt=3B &gt=3B		 	   		  &lt=3B/body&gt=3B<=
>> br>&gt=3B &gt=3B&lt=3B/html&gt=3B=3D<br>&gt=3B &gt=3B<br>&gt=3B &gt=3B--_3d=
>> d397d4-ac1d-4148-a9ff-059d27dd794a_--<br> 		 	   		  </body>
>> </html>=
>> 
>> --_0203aac2-5c8e-49c7-9074-6bc448ecf342_--




More information about the M3devel mailing list