[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'>
>>>> >=3D3B The following code from RTProcessC.c ensures that it is neeeded=
>> on e=3D
>>>> very Unix except<BR>>=3D3B >=3D3B /* NOTE: Even userthreads now depe=
>> nds<BR>=3D
>>>> >=3D3B >=3D3B * on availability of pthreads.<BR>>=3D3B >=3D3B * =
>> This can be=3D
>>>> fixed if need be.<BR>>=3D3B >=3D3B */<BR><BR>
>>>>  =3D3B<BR>
>>>> Ok=3D2C "we" should probably go ahead and fix that.<BR>
>>>> I'll try to=3D2C but no =3D3Bpromises=3D2C sorry.<BR>
>>>>  =3D3B<BR>
>>>>  =3D3B- Jay<BR> =3D3B<BR>
>>>> >=3D3B From: hosking at cs.purdue.edu<BR>>=3D3B Date: Mon=3D2C 18 Apr 2=
>> 011 18:11=3D
>>>> :26 -0400<BR>>=3D3B To: mika at async.caltech.edu<BR>>=3D3B CC: m3devel=
>> @elegos=3D
>>>> oft.com<BR>>=3D3B Subject: Re: [M3devel] 5.8.6 LINUXLIBC6 breakage=3D2=
>> C kerne=3D
>>>> l 2.6.23=3D2C glibc-2.6-4<BR>>=3D3B <BR>>=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>>=3D3B <BR>>=3D3B On Apr 18=3D2C 2011=
>> =3D2C at 2:45=3D
>>>> PM=3D2C Mika Nystrom wrote:<BR>>=3D3B <BR>>=3D3B >=3D3B Tony Hosk=
>> ing writes:=3D
>>>> <BR>>=3D3B >=3D3B ...<BR>>=3D3B >=3D3B>=3D3B pthread_atfork sh=
>> ould not be n=3D
>>>> eeded under user threads.<BR>>=3D3B >=3D3B ...<BR>>=3D3B >=3D3B =
>> <BR>>=3D3B =3D
>>>> >=3D3B The following code from RTProcessC.c ensures that it is neeeded=
>> on e=3D
>>>> very Unix except<BR>>=3D3B >=3D3B FreeBSD before 6. The comment is f=
>> rom the=3D
>>>> checked-in source file.<BR>>=3D3B >=3D3B <BR>>=3D3B >=3D3B /* N=
>> OTE: Even u=3D
>>>> serthreads now depends<BR>>=3D3B >=3D3B * on availability of pthread=
>> s.<BR>&=3D
>>>> gt=3D3B >=3D3B * This can be fixed if need be.<BR>>=3D3B >=3D3B */=
>> <BR>>=3D3B =3D
>>>> >=3D3B <BR>>=3D3B >=3D3B INTEGER<BR>>=3D3B >=3D3B __cdecl<BR>&=
>> gt=3D3B >=3D3B =3D
>>>> RTProcess__RegisterForkHandlers(<BR>>=3D3B >=3D3B ForkHandler prepar=
>> e=3D2C<BR=3D
>>>>> >=3D3B >=3D3B ForkHandler parent=3D2C<BR>>=3D3B >=3D3B ForkHand=
>> ler child)<BR=3D
>>>>> >=3D3B >=3D3B {<BR>>=3D3B >=3D3B /* FreeBSD <=3D3B 6 lacks pt=
>> hread_atfork.=3D
>>>> Would be good to use autoconf.<BR>>=3D3B >=3D3B * VMS lacks pthread=
>> _atfork=3D
>>>> ? Would be good to use autoconf.<BR>>=3D3B >=3D3B * Win32 lacks pthr=
>> ead_atf=3D
>>>> ork and fork. OK.<BR>>=3D3B >=3D3B *<BR>>=3D3B >=3D3B * As well=
>> =3D2C for all =3D
>>>> Posix systems=3D2C we could implement<BR>>=3D3B >=3D3B * atfork ours=
>> elves=3D2C =3D
>>>> as long as we provide a fork()<BR>>=3D3B >=3D3B * wrapper that code =
>> uses.<B=3D
>>>> R>>=3D3B >=3D3B */<BR>>=3D3B >=3D3B #if defined(_WIN32) \<BR>>=
>> =3D3B >=3D3B =3D
>>>> || defined(__vms) \<BR>>=3D3B >=3D3B || (defined(__FreeBSD__) /* &am=
>> p=3D3B&am=3D
>>>> p=3D3B (__FreeBSD__ <=3D3B 6)*/ )<BR>>=3D3B >=3D3B return 0=3D3B<B=
>> R>>=3D3B >=3D
>>>> =3D3B #else<BR>>=3D3B >=3D3B while (1)<BR>>=3D3B >=3D3B {<BR>>=
>> =3D3B >=3D3B in=3D
>>>> t i =3D3D pthread_atfork(prepare=3D2C parent=3D2C child)=3D3B<BR>>=3D3=
>> B >=3D3B if (=3D
>>>> i !=3D3D EAGAIN)<BR>>=3D3B >=3D3B return i=3D3B<BR>>=3D3B >=3D3B=
>> sleep(0)=3D3B<BR=3D
>>>>> >=3D3B >=3D3B }<BR>>=3D3B >=3D3B #endif<BR>>=3D3B >=3D3B }<=
>> BR>>=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'>
>>  =3B>=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>=3B forkall().<br>The current Solaris default is=
>> fork =3D>=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> =3B forkall()<br>#else<br> =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>=
>>  =3B user thread/pthread inconsistency<br> =3B cvsupd incompatibili=
>> ty with pthreads <br> =3B user threads using pthread_atfork/-pthread <b=
>> r> =3B fork() calls having to go through a wrapper (ok -- you could mis=
>> s this and <br> =3B =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> =3B-=
>> Jay<br><br><br>>=3B To: jay.krell at cornell.edu<br>>=3B Date: Mon=2C 18 =
>> Apr 2011 19:30:58 -0700<br>>=3B From: mika at async.caltech.edu<br>>=3B CC=
>> : m3devel at elegosoft.com<br>>=3B Subject: Re: [M3devel] 5.8.6 LINUXLIBC6 b=
>> reakage=2C kernel 2.6.23=2C glibc-2.6-4<br>>=3B <br>>=3B <br>>=3B If =
>> you or Tony could describe roughly what you think needs to be done<br>>=
>> =3B I'd be happy to look into it.<br>>=3B <br>>=3B The basic problem is=
>> that a decision that's made/described in<br>>=3B m3core/thread/m3makefil=
>> e needs to someone find its way to controlling<br>>=3B what C code gets c=
>> ompiled elsewhere in the system. Or maybe there should<br>>=3B be an ind=
>> irection into the thread library to pick up pthread_atfork (or not).<br>>=
>> =3B <br>>=3B But then again you still haven't explained why you made the =
>> user threads use<br>>=3B pthread_atfork. I just remove it from my instal=
>> lations=2C but then again I'm<br>>=3B not trying to run CVSup so I don't =
>> know if it breaks that program to do so.<br>>=3B <br>>=3B Mika<br>=
>> >=3B <br>>=3B Jay K writes:<br>>=3B >=3B--_3dd397d4-ac1d-4148-a9ff-=
>> 059d27dd794a_<br>>=3B >=3BContent-Type: text/plain=3B charset=3D"iso-88=
>> 59-1"<br>>=3B >=3BContent-Transfer-Encoding: quoted-printable<br>>=3B=
>> >=3B<br>>=3B >=3B<br>>=3B >=3B>=3B The following code from RTP=
>> rocessC.c ensures that it is neeeded on every =3D<br>>=3B >=3BUnix exce=
>> pt<br>>=3B >=3B>=3B >=3B /* NOTE: Even userthreads now depends<br>&=
>> gt=3B >=3B>=3B >=3B * on availability of pthreads.<br>>=3B >=3B&g=
>> t=3B >=3B * This can be fixed if need be.<br>>=3B >=3B>=3B >=3B *=
>> /<br>>=3B >=3B<br>>=3B >=3B=3D20<br>>=3B >=3BOk=3D2C "we" shoul=
>> d probably go ahead and fix that.<br>>=3B >=3BI'll try to=3D2C but no p=
>> romises=3D2C sorry.<br>>=3B >=3B=3D20<br>>=3B >=3B - Jay<br>>=3B =
>> >=3B=3D20<br>>=3B >=3B>=3B From: hosking at cs.purdue.edu<br>>=3B &g=
>> t=3B>=3B Date: Mon=3D2C 18 Apr 2011 18:11:26 -0400<br>>=3B >=3B>=3B=
>> To: mika at async.caltech.edu<br>>=3B >=3B>=3B CC: m3devel at elegosoft.co=
>> m<br>>=3B >=3B>=3B Subject: Re: [M3devel] 5.8.6 LINUXLIBC6 breakage=
>> =3D2C kernel 2.6.23=3D2C glib=3D<br>>=3B >=3Bc-2.6-4<br>>=3B >=3B&g=
>> t=3B=3D20<br>>=3B >=3B>=3B Probably unnecessary=3D2C given that I thi=
>> nk there is another entry point t=3D<br>>=3B >=3Bo forking a process (I=
>> forget where) in the thread-specific portion of m3co=3D<br>>=3B >=3Bre=
>> . In which case the necessary work might be done there?<br>>=3B >=3B>=
>> =3B=3D20<br>>=3B >=3B>=3B On Apr 18=3D2C 2011=3D2C at 2:45 PM=3D2C Mi=
>> ka Nystrom wrote:<br>>=3B >=3B>=3B=3D20<br>>=3B >=3B>=3B >=3B=
>> Tony Hosking writes:<br>>=3B >=3B>=3B >=3B ...<br>>=3B >=3B>=
>> =3B >=3B>=3B pthread_atfork should not be needed under user threads.<br=
>>> >=3B >=3B>=3B >=3B ...<br>>=3B >=3B>=3B >=3B=3D20<br>>=
>> =3B >=3B>=3B >=3B The following code from RTProcessC.c ensures that i=
>> t is neeeded on ever=3D<br>>=3B >=3By Unix except<br>>=3B >=3B>=
>> =3B >=3B FreeBSD before 6. The comment is from the checked-in source file=
>> .<br>>=3B >=3B>=3B >=3B=3D20<br>>=3B >=3B>=3B >=3B /* NOTE:=
>> Even userthreads now depends<br>>=3B >=3B>=3B >=3B * on availabili=
>> ty of pthreads.<br>>=3B >=3B>=3B >=3B * This can be fixed if need b=
>> e.<br>>=3B >=3B>=3B >=3B */<br>>=3B >=3B>=3B >=3B=3D20<br>&=
>> gt=3B >=3B>=3B >=3B INTEGER<br>>=3B >=3B>=3B >=3B __cdecl<br>=
>> >=3B >=3B>=3B >=3B RTProcess__RegisterForkHandlers(<br>>=3B >=
>> =3B>=3B >=3B ForkHandler prepare=3D2C<br>>=3B >=3B>=3B >=3B For=
>> kHandler parent=3D2C<br>>=3B >=3B>=3B >=3B ForkHandler child)<br>&g=
>> t=3B >=3B>=3B >=3B {<br>>=3B >=3B>=3B >=3B /* FreeBSD <=3B =
>> 6 lacks pthread_atfork. Would be good to use autoconf.<br>>=3B >=3B>=
>> =3B >=3B * VMS lacks pthread_atfork? Would be good to use autoconf.<br>&g=
>> t=3B >=3B>=3B >=3B * Win32 lacks pthread_atfork and fork. OK.<br>>=
>> =3B >=3B>=3B >=3B *<br>>=3B >=3B>=3B >=3B * As well=3D2C for =
>> all Posix systems=3D2C we could implement<br>>=3B >=3B>=3B >=3B * a=
>> tfork ourselves=3D2C as long as we provide a fork()<br>>=3B >=3B>=3B =
>> >=3B * wrapper that code uses.<br>>=3B >=3B>=3B >=3B */<br>>=3B=
>> >=3B>=3B >=3B #if defined(_WIN32) \<br>>=3B >=3B>=3B >=3B ||=
>> defined(__vms) \<br>>=3B >=3B>=3B >=3B || (defined(__FreeBSD__) /*=
>> &=3B&=3B (__FreeBSD__ <=3B 6)*/ )<br>>=3B >=3B>=3B >=3B re=
>> turn 0=3D3B<br>>=3B >=3B>=3B >=3B #else<br>>=3B >=3B>=3B >=
>> =3B while (1)<br>>=3B >=3B>=3B >=3B {<br>>=3B >=3B>=3B >=3B=
>> int i =3D3D pthread_atfork(prepare=3D2C parent=3D2C child)=3D3B<br>>=3B =
>> >=3B>=3B >=3B if (i !=3D3D EAGAIN)<br>>=3B >=3B>=3B >=3B retu=
>> rn i=3D3B<br>>=3B >=3B>=3B >=3B sleep(0)=3D3B<br>>=3B >=3B>=
>> =3B >=3B }<br>>=3B >=3B>=3B >=3B #endif<br>>=3B >=3B>=3B &g=
>> t=3B }<br>>=3B >=3B>=3B=3D20<br>>=3B >=3B =3D<br>>=
>> =3B >=3B<br>>=3B >=3B--_3dd397d4-ac1d-4148-a9ff-059d27dd794a_<br>>=
>> =3B >=3BContent-Type: text/html=3B charset=3D"iso-8859-1"<br>>=3B >=
>> =3BContent-Transfer-Encoding: quoted-printable<br>>=3B >=3B<br>>=3B &=
>> gt=3B<=3Bhtml>=3B<br>>=3B >=3B<=3Bhead>=3B<br>>=3B >=3B<=
>> =3Bstyle>=3B<=3B!--<br>>=3B >=3B.hmmessage P<br>>=3B >=3B{<br>&=
>> gt=3B >=3Bmargin:0px=3D3B<br>>=3B >=3Bpadding:0px<br>>=3B >=3B}<b=
>> r>>=3B >=3Bbody.hmmessage<br>>=3B >=3B{<br>>=3B >=3Bfont-size: =
>> 10pt=3D3B<br>>=3B >=3Bfont-family:Tahoma<br>>=3B >=3B}<br>>=3B &g=
>> t=3B-->=3B<=3B/style>=3B<br>>=3B >=3B<=3B/head>=3B<br>>=3B =
>> >=3B<=3Bbody class=3D3D'hmmessage'>=3B<br>>=3B >=3B&=3Bgt=3D3B=
>> The following code from RTProcessC.c ensures that it is neeeded on e=3D<br=
>>> >=3B >=3Bvery Unix except<=3BBR>=3B&=3Bgt=3D3B &=3Bgt=3D3B /=
>> * NOTE: Even userthreads now depends<=3BBR>=3B=3D<br>>=3B >=3B&=
>> =3Bgt=3D3B &=3Bgt=3D3B * on availability of pthreads.<=3BBR>=3B&=
>> =3Bgt=3D3B &=3Bgt=3D3B * This can be=3D<br>>=3B >=3B fixed if need b=
>> e.<=3BBR>=3B&=3Bgt=3D3B &=3Bgt=3D3B */<=3BBR>=3B<=3BBR>=
>> =3B<br>>=3B >=3B&=3Bnbsp=3D3B<=3BBR>=3B<br>>=3B >=3BOk=3D2C =
>> "we" should probably go ahead and fix that.<=3BBR>=3B<br>>=3B >=3BI=
>> 'll try to=3D2C but no&=3Bnbsp=3D3Bpromises=3D2C sorry.<=3BBR>=3B<br=
>>> >=3B >=3B&=3Bnbsp=3D3B<=3BBR>=3B<br>>=3B >=3B&=3Bnbsp=3D=
>> 3B- Jay<=3BBR>=3B&=3Bnbsp=3D3B<=3BBR>=3B<br>>=3B >=3B&=3B=
>> gt=3D3B From: hosking at cs.purdue.edu<=3BBR>=3B&=3Bgt=3D3B Date: Mon=
>> =3D2C 18 Apr 2011 18:11=3D<br>>=3B >=3B:26 -0400<=3BBR>=3B&=3Bgt=
>> =3D3B To: mika at async.caltech.edu<=3BBR>=3B&=3Bgt=3D3B CC: m3devel at el=
>> egos=3D<br>>=3B >=3Boft.com<=3BBR>=3B&=3Bgt=3D3B Subject: Re: [M=
>> 3devel] 5.8.6 LINUXLIBC6 breakage=3D2C kerne=3D<br>>=3B >=3Bl 2.6.23=3D=
>> 2C glibc-2.6-4<=3BBR>=3B&=3Bgt=3D3B <=3BBR>=3B&=3Bgt=3D3B Pro=
>> bably unnecessary=3D2C given =3D<br>>=3B >=3Bthat I think there is anot=
>> her entry point to forking a process (I forget wh=3D<br>>=3B >=3Bere) i=
>> n the thread-specific portion of m3core. In which case the necessary =3D<br=
>>> >=3B >=3Bwork might be done there?<=3BBR>=3B&=3Bgt=3D3B <=3BB=
>> R>=3B&=3Bgt=3D3B On Apr 18=3D2C 2011=3D2C at 2:45=3D<br>>=3B >=3B =
>> PM=3D2C Mika Nystrom wrote:<=3BBR>=3B&=3Bgt=3D3B <=3BBR>=3B&=
>> =3Bgt=3D3B &=3Bgt=3D3B Tony Hosking writes:=3D<br>>=3B >=3B<=3BBR&=
>> gt=3B&=3Bgt=3D3B &=3Bgt=3D3B ...<=3BBR>=3B&=3Bgt=3D3B &=3Bg=
>> t=3D3B&=3Bgt=3D3B pthread_atfork should not be n=3D<br>>=3B >=3Beede=
>> d under user threads.<=3BBR>=3B&=3Bgt=3D3B &=3Bgt=3D3B ...<=3BB=
>> R>=3B&=3Bgt=3D3B &=3Bgt=3D3B <=3BBR>=3B&=3Bgt=3D3B =3D<br>&g=
>> t=3B >=3B&=3Bgt=3D3B The following code from RTProcessC.c ensures that=
>> it is neeeded on e=3D<br>>=3B >=3Bvery Unix except<=3BBR>=3B&=
>> =3Bgt=3D3B &=3Bgt=3D3B FreeBSD before 6. The comment is from the=3D<br>&=
>> gt=3B >=3B checked-in source file.<=3BBR>=3B&=3Bgt=3D3B &=3Bgt=
>> =3D3B <=3BBR>=3B&=3Bgt=3D3B &=3Bgt=3D3B /* NOTE: Even u=3D<br>>=
>> =3B >=3Bserthreads now depends<=3BBR>=3B&=3Bgt=3D3B &=3Bgt=3D3B=
>> * on availability of pthreads.<=3BBR>=3B&=3B=3D<br>>=3B >=3Bgt=
>> =3D3B &=3Bgt=3D3B * This can be fixed if need be.<=3BBR>=3B&=3Bgt=
>> =3D3B &=3Bgt=3D3B */<=3BBR>=3B&=3Bgt=3D3B =3D<br>>=3B >=3B&am=
>> p=3Bgt=3D3B <=3BBR>=3B&=3Bgt=3D3B &=3Bgt=3D3B INTEGER<=3BBR>=
>> =3B&=3Bgt=3D3B &=3Bgt=3D3B __cdecl<=3BBR>=3B&=3Bgt=3D3B &=
>> =3Bgt=3D3B =3D<br>>=3B >=3BRTProcess__RegisterForkHandlers(<=3BBR>=
>> =3B&=3Bgt=3D3B &=3Bgt=3D3B ForkHandler prepare=3D2C<=3BBR=3D<br>>=
>> =3B >=3B>=3B&=3Bgt=3D3B &=3Bgt=3D3B ForkHandler parent=3D2C<=3B=
>> BR>=3B&=3Bgt=3D3B &=3Bgt=3D3B ForkHandler child)<=3BBR=3D<br>>=
>> =3B >=3B>=3B&=3Bgt=3D3B &=3Bgt=3D3B {<=3BBR>=3B&=3Bgt=3D3B=
>> &=3Bgt=3D3B /* FreeBSD &=3Blt=3D3B 6 lacks pthread_atfork.=3D<br>>=
>> =3B >=3B Would be good to use autoconf.<=3BBR>=3B&=3Bgt=3D3B &=
>> =3Bgt=3D3B * VMS lacks pthread_atfork=3D<br>>=3B >=3B? Would be good to=
>> use autoconf.<=3BBR>=3B&=3Bgt=3D3B &=3Bgt=3D3B * Win32 lacks pth=
>> read_atf=3D<br>>=3B >=3Bork and fork. OK.<=3BBR>=3B&=3Bgt=3D3B &=
>> amp=3Bgt=3D3B *<=3BBR>=3B&=3Bgt=3D3B &=3Bgt=3D3B * As well=3D2C f=
>> or all =3D<br>>=3B >=3BPosix systems=3D2C we could implement<=3BBR>=
>> =3B&=3Bgt=3D3B &=3Bgt=3D3B * atfork ourselves=3D2C =3D<br>>=3B >=
>> =3Bas long as we provide a fork()<=3BBR>=3B&=3Bgt=3D3B &=3Bgt=3D3=
>> B * wrapper that code uses.<=3BB=3D<br>>=3B >=3BR>=3B&=3Bgt=3D3B=
>> &=3Bgt=3D3B */<=3BBR>=3B&=3Bgt=3D3B &=3Bgt=3D3B #if defined(_=
>> WIN32) \<=3BBR>=3B&=3Bgt=3D3B &=3Bgt=3D3B =3D<br>>=3B >=3B|| =
>> defined(__vms) \<=3BBR>=3B&=3Bgt=3D3B &=3Bgt=3D3B || (defined(__F=
>> reeBSD__) /* &=3Bamp=3D3B&=3Bam=3D<br>>=3B >=3Bp=3D3B (__FreeBSD_=
>> _ &=3Blt=3D3B 6)*/ )<=3BBR>=3B&=3Bgt=3D3B &=3Bgt=3D3B return 0=
>> =3D3B<=3BBR>=3B&=3Bgt=3D3B &=3Bgt=3D<br>>=3B >=3B=3D3B #else&=
>> lt=3BBR>=3B&=3Bgt=3D3B &=3Bgt=3D3B while (1)<=3BBR>=3B&=3Bgt=
>> =3D3B &=3Bgt=3D3B {<=3BBR>=3B&=3Bgt=3D3B &=3Bgt=3D3B in=3D<br>=
>> >=3B >=3Bt i =3D3D pthread_atfork(prepare=3D2C parent=3D2C child)=3D3B&=
>> lt=3BBR>=3B&=3Bgt=3D3B &=3Bgt=3D3B if (=3D<br>>=3B >=3Bi !=3D3D=
>> EAGAIN)<=3BBR>=3B&=3Bgt=3D3B &=3Bgt=3D3B return i=3D3B<=3BBR&g=
>> t=3B&=3Bgt=3D3B &=3Bgt=3D3B sleep(0)=3D3B<=3BBR=3D<br>>=3B >=3B=
>> >=3B&=3Bgt=3D3B &=3Bgt=3D3B }<=3BBR>=3B&=3Bgt=3D3B &=3Bgt=
>> =3D3B #endif<=3BBR>=3B&=3Bgt=3D3B &=3Bgt=3D3B }<=3BBR>=3B&=
>> =3Bgt=3D3B <=3BBR>=3B =3D<br>>=3B >=3B <=3B/body>=3B<=
>> br>>=3B >=3B<=3B/html>=3B=3D<br>>=3B >=3B<br>>=3B >=3B--_3d=
>> d397d4-ac1d-4148-a9ff-059d27dd794a_--<br> </body>
>> </html>=
>>
>> --_0203aac2-5c8e-49c7-9074-6bc448ecf342_--
More information about the M3devel
mailing list