• 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: Reading all data before the NSTask terminates,
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Reading all data before the NSTask terminates,


  • Subject: Re: Reading all data before the NSTask terminates,
  • From: Ingvar Nedrebo <email@hidden>
  • Date: Sun, 2 Oct 2005 02:11:42 +0100

Here is how I did it just recently. The taskStates enum defines one bit for each condition (my original code has a stdErr bit as well). The taskDone method then does final processing not until all conditions are set. No need for an embedded run loop. Also it makes no difference exactly where readInBackgroundAndNotify is sent in your read notification method.


@interface MyTask : NSObject { NSTask * task ; unsigned int taskStatus; NSMutableData * buffer; } @end

@implementation MyTask

enum {
    taskReadDone   = 1<<0,
    taskTerminated = 1<<1,
    taskAllDone    = (taskReadDone | taskTerminated)
} taskStates;

-(void)readData:(NSNotification *)noty
{
    NSData *data = [[noty userInfo]
       objectForKey:NSFileHandleNotificationDataItem];
    if ([data length])
    {
        [buffer appendData:data];
        [[noty object] readInBackgroundAndNotify];
    }
    else
        [self taskDone:taskReadDone];
}

-(void)taskTerminated:(NSNotification *)noty
{
    [self taskDone:taskTerminated];
}


-(void)taskDone:(unsigned int)whichBit { taskStatus |= whichBit; if (taskStatus == taskAllDone) { int returnCode = [[self task] terminationStatus]; // clean up task, remove observers etc. // process data } }

// rest of implementation...


On Oct 2, 2005, at 00:57, Frode wrote:

Hello!

I noticed that under some circumstances NSTaskDidTerminateNotification
is sent before all NSFileHandleReadCompletionNotification are
consumed. I suppose this is possible in all circumstances, isn't it?
However, I only experience this in certain cases, and to show it with
brutality I use sleep() to reproduce It. But in reality, sleep() is
replaced with a processData-message, that in debug build uses NSLog()
to print debug-messages and that is how I noticed it.


To remmedy this synchronization issue, I have to run the run-loop until
a condition is set. And I'm not very comfortable with run-loops. Is
there a smarter method to synchronize the notifications? And why do I
need to do this? I suppose It can occure even if I send
readInBackgroundAndNotify before I process the data (here represented
by a sleep()), don't you think so?


Am I supposed to temporary turn off some kind of signals when using
data-available notifications from a NSTasks? (Now, this is only
something I have thought of but maybee it is crazyness.)

Thanks for any help
Roger P.

-(void)commandGetData:(NSNotification *)obj {
NSData *incommingData = [[obj userInfo]
objectForKey:NSFileHandleNotificationDataItem];
if([incommingData length])
{
// uncommented [[obj object] readInBackgroundAndNotify]; // Is this
correct?
fprintf(stderr, "Received %u bytes: Sleeping for 1 seconds...",
[incommingData length]);
sleep(1);
fprintf(stderr, "done!\n");
[dataBuffer appendData:incommingData];
[[obj object] readInBackgroundAndNotify]; //??? This is wrong
}
else
{
fprintf(stderr, "Completed!\n");
readCompleted = YES;
}
}


-(void)commandTerminated:(NSNotification *)obj {
    // Synchronize notifications
    int    i = 1;
    while(readCompleted == NO)
    {
        fprintf(stderr, "Synchronizing#=> ", i++);
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate distantFuture]];
    }

    fprintf(stderr, "%s Shell terminated %p, %u bytes received\n",
__func__, [obj object], [dataBuffer length]);

     // ...
}

_______________________________________________
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


References: 
 >Reading all data before the NSTask terminates, synchronizing notifications (From: Frode <email@hidden>)

  • Prev by Date: Re: NSTextField eating Escape [Solved]
  • Next by Date: Too many @selector statements?
  • Previous by thread: Reading all data before the NSTask terminates, synchronizing notifications
  • Next by thread: Re: NSTextField eating Escape [Solved]
  • Index(es):
    • Date
    • Thread