Re: continuing after fork() (Re: Problems with NSTimer and NSRunLoop/CFRunLoop)
Re: continuing after fork() (Re: Problems with NSTimer and NSRunLoop/CFRunLoop)
- Subject: Re: continuing after fork() (Re: Problems with NSTimer and NSRunLoop/CFRunLoop)
- From: Mont Rothstein <email@hidden>
- Date: Wed, 12 Jan 2005 22:56:51 -0800
Thank you Chris for the detailed and informative reply, this problem
has been haunting me for some time.
If you don't mind I'd like to clarify my interpretation of your
response to make sure I have a handle on this.
First, since my last post I have determined that certain frameworks I
was including cause my child to fail. Without those frameworks the
child runs fine.
If I understand you correctly then the fact that without those
frameworks the child works is luck, because in both cases the app links
against Apple frameworks. I was headed down a path of attempting to
remove the dependency on the problem frameworks (my previous removal
was only a test and was at the expense of functionality). Given your
description I believe I should abandon that course and instead use
execve() because even the working version is at risk of failing.
Also, I am unclear from the man page on execve(). Will my parent
process still receive the exit from the child? And it sounds like I
need a second main() with (argc, argv, envp) that will be called by
execve().
Thanks again for your response.
-Mont
On Jan 11, 2005, at 8:10 PM, Chris Kane wrote:
You cannot continue executing the child process of a fork() for
executables which link with any Apple libraries(*) (directly or
indirectly) and want to use that functionality on the child side of
the fork(), without a paired execve() in the child. That is, if you
want to fork() and have the child continue to run and use Apple
libraries, the child must execve() and "continue" from main().
The problem is that fork() does not actually replicate all kernel
resources (and perhaps other bits I don't know about) from the parent
process into the child, but it does replicate memory. Thus there can
be code which thinks everything is happy because the memory holding
handles to kernel resources looks like it is initialized and whatnot,
but the kernel resources are missing underneath.
Sprinkling checks all over to see if the resource handle is good "in
case a fork() has happened since the last check" would be laborious
and in some cases expensive in some hot code paths, when continuing
after fork() is actually not very common. So the checks are left out.
I thought there was a Tech Note on this, and perhaps there was at one
point, but I can't find it now, or the information has moved
elsewhere.
Basically, after fork() you need to execve() (or other exec variant),
so that library initializers and whatnot are executed in the context
of the child to do any 1-time set-up or whatever else the libraries
normally do when an app is launched. The usual pattern is to pass an
extra argument or environment variable to the child to let it know to
not fork() again, that it is the child.
(*) this is not necessarily just true of Apple libraries, but can be
true of BSD/open source libraries as well. But "any Apple library" is
a good starting point. CoreFoundation and Foundation are two such
Apple libraries that I personally know about, and the Mach ports used
by the run loop system is one example of kernel resources which are
not replicated.
Chris Kane
Cocoa Frameworks, Apple
On Jan 6, 2005, at 7:14 PM, Mont Rothstein wrote:
John and Brendan, thanks for your suggestions.
John,
No, I didn't realize that CF is open source. I may just have to go
see if the timer and run loop stuff is.
As Brendan pointed out, the call being made to NSTimer is supposed to
add the timer to the run loop for me, and in fact it does in another
scenario.
Brendan,
I hadn't even though of a PoseAs, great idea.
I know that the timer has not been added because I have printed our
the description for the run loop, which includes all of the modes.
My problem occurs in a process that was created via fork(). Your
comment about being in another thread makes me wonder if this could
somehow be related. Are you aware of any issues with fork() and
NSRunLoops?
Thanks again,
-Mont
On Jan 6, 2005, at 6:45 PM, Brendan Younger wrote:
On Jan 6, 2005, at 8:32 PM, John Stiles wrote:
Unnecessary how?
If you don't attach your timer to a run loop in a mode, it doesn't
run, period.
True, but -[NSTimer
scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:]
automatically adds itself to the current run loop for the default
mode. -[NSTimer timerWithTimeInterval:etc.] doesn't add itself and
needs to be added manually. The original poster was using -[NSTimer
scheduledTimerWithTimeInterval:etc.].
To Mont Rothstein: if "performExpirationCheck:" is meant to be
called while a modal window is up in your application, you need to
add the timer to the run loop for NSModalPanelRunLoopMode since
-[NSTimer scheduledTimerWithTimeInterval:] adds itself for only
NSDefaultRunLoopMode.
Brendan Younger
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
email@hidden
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden