Re: NSTask is intermittently failing to return results.
Re: NSTask is intermittently failing to return results.
- Subject: Re: NSTask is intermittently failing to return results.
- From: Jason Harris <email@hidden>
- Date: Sun, 20 Mar 2011 01:39:16 +0100
Answer part III
On Mar 19, 2011, at 8:43 PM, Bill Monk wrote:
> * Except, when it finally does call finishUp (if it ever does; here it seems to get into an infinite loop), it's just too complicated. All you do here is unregister observers, read any remaining data, and dispose of file handles etc.
>
> Some comment on -finishUp are below.
>
>
> - (void) finishUp
> {
> if (isFinished_)
> return;
>
> DebugLog(@"...Finishing up for %@ ...", [self commandLineString]);
>
> [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(finishUp) object:nil];
> [self stopObserving:NSFileHandleReadCompletionNotification from:nil];
> [self stopObserving:NSTaskDidTerminateNotification from:nil];
>
> [task_ terminate];
>
> // Clear standard out and standard error
> NSData* data;
> while ((data = [outHandle_ availableDataIgnoringErrors]) && [data length])
> [outputData_ appendData:data];
> while ((data = [errHandle_ availableDataIgnoringErrors]) && [data length])
> [errorData_ appendData:data];
>
> outHandle_ = nil;
> errHandle_ = nil;
> result_ = [task_ terminationStatus];
> isFinished_ = YES;
> }
>
>
> -------
> if (isFinished_)
> return;
>
> You don't need to check (or maintain) an isFinished ivar - the task is finished. It just told you so.
isFinished was recording if the finalizer had been called.
Ie if the run loop had been working and the exit notification fired and was correctly caught and control returned to the runloop like I had intended then reading the code its pretty clear that finishUp could be called more than once. When things fire asynchronously you sometimes need to have guards. This condition was such a guard.
> -------
> cancelPreviousPerformRequestsWithTarget
>
> Lose all this stuff - it only serves to hide problems.You think it's helping and then the code gets on a different machine and instead of crashing, it does other weird stuff that never happened on your machine, like the never-ending tasks I'm seeing here.
Again, other people had this...
> --------
> [task_ terminate];
>
> Why? This accomplishes nothing - the task has terminated. If you -did- need to terminate it, say because the app is quitting, you'd do that elsewhere, not in the method that gets called in response to a task termination.
> --------
Apples Moriarty sample had this code. (Amongst other projects out there.)
> --------
> while ((data = [outHandle_ availableDataIgnoringErrors]) && [data length])
> [outputData_ appendData:data];
> while ((data = [errHandle_ availableDataIgnoringErrors]) && [data length])
> [errorData_ appendData:data];
>
>
> If it were my code, I would remove this wholly bogus availableDataIgnoringErrors method. At best, it's a band-aid covering up serious problems.
AMTask had this block of code without the error handling. Others do it as well when I googled around... As far as the error handling, again I very much wanted to remove this handling and solve the main problem... hence... *I posted to this news group* in order to find a way not to use this exception handling, and basically fix the problems I was having.
> Also, it is NOT ignoring "errors", it ignores NSFileHandleOperationException, which should not be happening. (And, a -regex- in the @catch block to check [error reason]??? Simplify...)
>
> Docs say: "Raised by NSFileHandle if attempts to determine file-handle type fail or if attempts to read from a file or channel fail."
>
> That exception is valuable info that your code has, somewhere, hosed things up. Stop trying to suppress useful crashes - embrace them and fix their causes.
Uhhhh... Thats the exact reason why I was posting here...
In summary please read the code in eg Moriarty, AMTask, OpenFileKiller, or MYTask code in order to follow up...
And again. I wasn't saying the code was perfect... In fact far from it. Hence my posting and request for help to this list... I was trying to use basically the other code out there that I had seen. In addition since I was having problems and couldn't find the solution I was trying the next best thing of course of trying to at least catch the errors. (Nowhere near as good as solving the original problem which I really very badly wanted to fix.)
Happily with Jonathan pointing out apples sample code of CommandLineToolPlugin.m, my code here is now much much simpler:
Cheers,
Jas_______________________________________________
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