Re: Reading all data before the NSTask terminates,
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