Issue with getting availableData from NSFileHandle on Intel Mac.

  • Hi All ,

    Getting availableData from NSFileHandle is taking time (nearly 30
    secs) on Intel Mac .

    [[[aTask standardOutput] fileHandleForReading] availableData]

    But while running on a PPC , i'm able to get the data in less than a
    second.
    Below is code snippet . Can anyone help me out in this issue.

        NSTask* aTask = [[[NSTask alloc] init] autorelease];
        [aTask setStandardOutput:[NSPipe pipe]];
        [aTask setLaunchPath:@"/bin/launchctl"];
        [aTask setArguments:[NSArray arrayWithObject:@"list"]];
        [aTask launch];
        [aTask waitUntilExit];

        NSData *data = [[[aTask standardOutput] fileHandleForReading]
    availableData];
        NSString *str = [[[NSString alloc] initWithData:data
    encoding:NSUTF8StringEncoding] autorelease];
        NSArray *tasksList = [str componentsSeparatedByString:@"\n"];

    Thanks In Advance
    Sudheer.
  • On 24 Sep 2007, at 12:49, Sudheer dantuluri wrote:

    > Getting availableData from NSFileHandle is taking time (nearly 30
    > secs) on Intel Mac .
    >
    > [[[aTask standardOutput] fileHandleForReading] availableData]
    >
    > But while running on a PPC , i'm able to get the data in less than
    > a second.
    > Below is code snippet . Can anyone help me out in this issue.
    >
    >
    > NSTask* aTask = [[[NSTask alloc] init] autorelease];
    > [aTask setStandardOutput:[NSPipe pipe]];
    > [aTask setLaunchPath:@"/bin/launchctl"];
    > [aTask setArguments:[NSArray arrayWithObject:@"list"]];
    > [aTask launch];
    > [aTask waitUntilExit];  // (*)
    >
    > NSData *data = [[[aTask standardOutput] fileHandleForReading]
    > availableData];

    Pipes don't have an infinitely large buffer.  As a result, your code
    (above) is broken on both PowerPC *and* Intel.

    For instance, consider the case where there are many LaunchDaemon
    plists installed on the user's machine.  When the pipe buffer
    overflows, launchctl will block.  But your code is blocked waiting
    for it to terminate (the line I marked (*) above).  Neither program
    will ever make progress.

    You need to use a loop rather than calling -waitUntilExit; for instance:

      NSMutableData *data = [NSMutableData data];
      NSData *someData;
      NSFileHandle *readHandle = [[aTask standardOutput]
    fileHandleForReading];

      while ((someData = [readHandle availableData]) && [someData
    length]) {
        [data appendData:someData];  // Or, if possible, process the
    data here
      }

    You might also want some exception handling code, because -
    availableData doesn't handle EINTR properly (rather than retrying its
    read() call, it throws an exception), which can occasionally cause
    trouble.

    As for the 30 second problem, it sounds like some sort of time-out,
    probably intended to "solve" a deadlock situation.  Try writing the
    code as above and see if it goes away.

    Kind regards,

    Alastair.

    --
    http://alastairs-place.net
previous month september 2007 next month
MTWTFSS
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Go to today