On Apr 6, 2009, at 7:50 PM, Michael Ash wrote:
On Mon, Apr 6, 2009 at 1:47 PM, Michael Domino <[email protected]> wrote:[task setLaunchPath:@"/usr/bin/hdiutil"]; [task setArguments:[NSArray arrayWithObjects:@"info", nil]]; [task setStandardError:messagePipeError]; [task setStandardOutput:messagePipeOutput];NSFileHandle* readHandleError =[messagePipeError fileHandleForReading]; [msgTarget setReadHandleError:readHandleError];NSFileHandle* readHandleOutput =[messagePipeOutput fileHandleForReading]; [msgTarget setReadHandleOutput:readHandleOutput]; [readHandleError readToEndOfFileInBackgroundAndNotify]; [readHandleOutput readToEndOfFileInBackgroundAndNotify]; [task launch]; sleep(3); [task waitUntilExit];status = [task terminationStatus];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).
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.
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).
-- Adam
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________ Cocoa-dev mailing list ([email protected]) 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: http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to [email protected]
