Re: Does waitUntilExit really mean that?
Re: Does waitUntilExit really mean that?
- Subject: Re: Does waitUntilExit really mean that?
- From: Michael Ash <email@hidden>
- Date: Tue, 7 Apr 2009 00:02:01 -0400
On Mon, Apr 6, 2009 at 11:10 PM, Adam R. Maxwell <email@hidden> wrote:
>
> On Apr 6, 2009, at 7:50 PM, Michael Ash wrote:
>> First off, I wouldn't write code like this. You have no guarantee that
>> readToEndOfFileInBackgroundAndNotify will actually read everything
>> while your code is stuck in waitUntilExit, so you have the same
>> potential for deadlock as before. It's quite possible that it
>> immediately starts reading on a background thread and so you're
>> perfectly safe, but it's bad to rely on that sort of thing.
>
> Wouldn't it be pretty useless if it didn't do that, though? If this is
> really a problem, I'd like to know, since I use something similar. The main
> difference is that I call -readToEndOfFileInBackgroundAndNotifyForModes:
> with a private runloop mode, then call -waitUntilExit. When -waitUntilExit
> returns, I run the runloop in that mode for a short time to pick up the
> notifications (IIRC it takes one pass per pipe).
Why would it be useless? The idea is to perform the read in the
background, without blocking your thread, but it explicitly requires
you to run the runloop in order to get the notification, and could
very well implicitly require you to run the runloop in order to do any
work at all. It would still be extremely *useful*, as it would still
function as a fire-and-forget "go read this and tell me when you're
done" method. It just wouldn't work for this "go read this right now
in another thread without me even going back to the runloop" scenario
you two are using it for. I contend based on the documentation that
this use is simply not supported. It says "in the background" but says
nothing about another thread. It could very well be implemented by
installing the socket directly on the runloop, for example by using
CFFileDEscriptor, and performing all reads on the thread you call it
from. It obviously isn't implemented that way *now*, but it could be
done that way in the future. It would still be a very useful method,
but it wouldn't work the way you're using it.
>> I'd just
>> ditch your waitUntilExit altogether. All you should really care about
>> is an end to the data coming in.
>
> I'd ditch the sleep and keep the -waitUntilExit, since NSTask throws an
> exception if you call -terminationStatus before the task has actually
> exited. And I'd put most of this code in an exception handler, since NSTask
> has a really unpleasant habit of throwing exceptions unexpectedly.
Well obviously if you're going to dump the waitUntilExt, you'd dump
the terminationStatus too. Either forget about it altogether, because
it's probably not important here, or register for
NSTaskDidTerminateNotification and query the terminationStatus in the
callback.
>> But as for your actual problem, my guess is that it has to do with the
>> fact that you're reading before you launch the task.
>
> Like Ken pointed out earlier in this thread, running the runloop briefly
> after -waitUntilExit would take care of the problem, but I prefer to use a
> separate runloop to avoid any other callouts. Some code that I'm currently
> using for this is at
> http://code.google.com/p/mactlmgr/source/browse/trunk/TLMTask.m (BSD
> license).
Running the runloop after waitUntilExit may well fix some of the
problems but it's not going to fix the fundamental problem that this
code is unsafe.
If you're using asynchronous methods like these, then you really
should rework your code to actually be asynchronous. It's not
universal, but most of the time if you find yourself running the
runloop manually, it's a sign that you're doing something wrong. Start
the reads, sign up for the appropriate notifications, *then return*
and let the frameworks do their thing. They'll tell you when they're
done.
If you do insist on running an inner runloop, then you'll need to do
that *first*, before you use waitUntilExit, to avoid the potential
deadlock.
Mike
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden