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:27:40 +0100
Sorry I have to break this into several replies to get around the automatic size limits of post to this group. So here is the reply in a couple of bites:
On Mar 19, 2011, at 8:43 PM, Bill Monk wrote:
>> I have looked at (in fact studied in detail) the source code for Moriarity, AMShellWrapper, MyTask, and OpenFileKiller
>
> I don't mean this to be as harsh, the way it will look in print but...Really? Those projects show how simple it should be. You are making it complicated. And weird.
Uhmmm... My code was based on those projects, and its very very similar to those projects. Probably most similar to OpenFileKiller and MyTask since they both use the run loop approach ie they wanted to synchronously call NSTask using the asynchronous notification mechanisms. One interesting thing I found about MyTask is that the exit notification is never caught in the run loop (at least in my experimentation) since the run loop was working in a different mode yet the notification was delivered in the NSDefaultRunLoopMode...) But anyway my code was strongly based on theirs so it really shouldn't be all that different or shocking to you.
>> NSTask is most of the time working for me, but intermittently it's failing to return results. Either the result is silently dropped, or more infrequently I am getting exceptions in:
>>
>> [NSConcreteData initWithBytes:length:copy:freeWhenDone:bytesAreVM:] or
>> [NSConcreteFileHandle availableData] or
>> [NSConcreteFileHandle readDataOfLength:]
>>
>> depending on the tweaks / experiments I am attempting to play with.
>
> I've never seen anything like that with NSTask.
Other people have and its documented. Just google for it, or even look at the links I included in my original post. Likely there are / were making the same small subtle mistakes that I am / was.
> I do not find it flaky or intermittent. But when I run your app, following your instructions, I don't get crashes, I just get an ever-increasing number of unfinished tasks (with indeterminate progress indicators) in the Information pane at lower left. Looks like just another manifestation of the same problem.
Were you breaking on exceptions? Also it didn't crash since the exceptions were caught... Also if you are building from source then the tip revision as of now is of course not a good version to actually *do things* with. It was the example code which I was having problems with which I posted to this list...
> Some big differences between your code and how NSTask is supposed to work are:
>
> * What's all this polling in -waitTillFinished after calling -launch on the task? Forget running your own runloop here. Why?
This is exactly what OpenFileKiller and MyTask do. How can you say those other projects "show how simple it should be" if you haven't even read their code?!?... That was their way to get synchronous reading from the asynchronous notifications. It seemed like the standard way to do it from what I saw googling around. In fact if you look at the documentation on NSTask you see:
waitUntilExit
Block until the receiver is finished.
- (void)waitUntilExit
Discussion
This method first checks to see if the receiver is still running using isRunning.
Then it polls the current run loop using NSDefaultRunLoopMode until the task
completes.
Ie apple is internally messing with runLoops to make this work. The other sample codes written by others were just making this a bit more explicit I guess... Or working around bugs, or something... (Note there are lots of questions on NSTask if you google for it...)
> Either just exit and let the notifications tell you when the task is done, or you call -waitUntilExit on the task, and block right there.
Well yes. The waitUntilExit does seem to be working. Which was pointed out by Jonathan Mitchell. It appears strange to me that one can simply use this, and that someone as knowledgeable as Matt Gallagher was using the more complicated runLoop approach that I initially tried to use. Maybe the explicit runLoop approach solved some bugs at one time or another for him?
Note that the only piece of sample code which I have seen while googling around on NSTaskk that uses the [task waitUntilExit] approach is now the code Jonathan Mitchell pointed out to us.
> * Why are you trying to *infer* when the task is done? You've got the ivars isFinished_ and pendingTermination_, and methods -shouldFinishUp, -finishUp and -waitTillFinished (that runs the unnecessary runloop), a -setPendingTermination to call -finishUp after a 10 second delay after you guess that the task might be finished, and a -resetPendingTermination method to try again if the previous guess was wrong.
>
> This is madness - this is all unnecessary. You've got a crash, and you have to find and fix it. Adding all these layers just masks the problem, and makes it harder to find. None of the sample code you referenced go through any of these gyrations. Do they?
Yes. They do. Look at their code.
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