• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Does waitUntilExit really mean that?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Does waitUntilExit really mean that?


  • Subject: Re: Does waitUntilExit really mean that?
  • From: Michael Domino <email@hidden>
  • Date: Tue, 7 Apr 2009 11:44:28 -0400

Ken,

Thanks very much for the reply. I have two methods to handle the notifications for the error and output pipes (see below). Since we are supposed to be reading to EOF, do I really need to call readToEndOfFileInBackgroundAndNotify at the end of each call?

To answer your question, after the code runs I get my error and output strings and parse them. If waitUntilExit is not going to wait long enough for the i/o process to complete, how would I go about ensuring that the run loop is run until both NSFileHandles have sent their notifications? Use NSTaskDidTerminateNotification instead of or in addition to waitUntilExit?

- (void)errorEndOfFileNotification:(NSNotification*)aNotification
{
NSFileHandle* theFileHandle = static_cast<NSFileHandle*>([aNotification object]);
NSData *data = [[aNotification userInfo] objectForKey:@"NSFileHandleNotificationDataItem"];

if(data && [data length]) {
if(theFileHandle == readHandleError) {
[self appendErrorString:[[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]];
}
}

// We need to schedule the file handle to again go read more data in the background.
[[aNotification object] readToEndOfFileInBackgroundAndNotify];
}


- (void)outputEndOfFileNotification:(NSNotification*)aNotification
{
NSFileHandle* theFileHandle = static_cast<NSFileHandle*>([aNotification object]);
NSData *data = [[aNotification userInfo] objectForKey:@"NSFileHandleNotificationDataItem"];

if(data && [data length]) {
if(theFileHandle == readHandleOutput) {
[self appendOutputString:[[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]];
}
}

// We need to schedule the file handle to again go read more data in the background.
[[aNotification object] readToEndOfFileInBackgroundAndNotify];
}


On Apr 6, 2009, at 8:16 PM, Ken Thomases wrote:

On Apr 6, 2009, at 12:47 PM, Michael Domino wrote:

Thanks for all the advice about how to make my pipe reads non- blocking, that works almost perfectly. I have a class now that handles the notifications (called msgTarget in the code snippet below). The puzzle here is the meaning of "waitUntilExit". My hdiutil info task was returning no data in both the output and error file handles. When I put in sleep(1), I started to get error strings, but no output strings. When I increased the wait to sleep(3), my standard output started coming through. Why would this be the case if waitUntilExit is actually waiting until the hdiutil task completes and exits? Is there some other latency in this process that my sleep() accounts for? I'd rather not rely on a kludge like this to get my output string. Is the problem using readToEndOfFileInBackgroundAndNotify instead of readInBackgroundAndNotify? I tried the latter call, but seem to get better results using readToEndOfFileInBackgroundAndNotify (or is that totally the wrong thing to do?).


[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];

What are you doing after the above code?

The closing of the write end of the pipes (signaling end-of-file) and the end of the task all happen roughly simultaneously. It is definitely possible that -waitUntilExit will return before the - readToEndOfFileInBackgroundAndNotify calls see the end-of-file.

Now, notifications generally do not require that a run loop be run. They are delivered synchronously. But these notifications are triggered by monitoring an external resource or events. Such monitoring _does_ typically require that the run loop be run.

-waitUntilExit is documented as running the run loop of the current thread. But in the race condition you're encountering, - waitUntilExit may exit before the NSFileHandles have detected EOF. So, you may have to ensure that the run loop is run until both NSFileHandles have sent their notifications.

Regards,
Ken


Michael Domino email@hidden



Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________

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

  • Follow-Ups:
    • Re: Does waitUntilExit really mean that?
      • From: Ken Thomases <email@hidden>
References: 
 >Does waitUntilExit really mean that? (From: Michael Domino <email@hidden>)
 >Re: Does waitUntilExit really mean that? (From: Ken Thomases <email@hidden>)

  • Prev by Date: Re: Does waitUntilExit really mean that?
  • Next by Date: Re: Does waitUntilExit really mean that?
  • Previous by thread: Re: Does waitUntilExit really mean that?
  • Next by thread: Re: Does waitUntilExit really mean that?
  • Index(es):
    • Date
    • Thread