The reason why I asked this is because I need:
     -[NSTask waitUntilExitOrTimeout:(NSTimeInterval)].
But there is no such method. So, I wrote a wrapper around NSTask that does this.

On 2009 Sep 14, at 07:41, Adam R. Maxwell wrote:

Ordinarily, I'd guess that it's supposed to mean that you can't share instances between threads. However, guesswork when dealing with the threading docs drives me crazy.

For NSTask in particular, I recommend that you interpret that more conservatively...

Also, I presume it means that you should not invoke the same instance from more than one thread. I'm not sure how much more conservative you could get, other than to run it on the main thread.

I wrote an implementation of NSTask from scratch to work around the problem.

Whew, Adam. Since I'm 10.5+, and don't think I'll ever be running more than one NSTask at a time, I won't be quite that conservative. In my NSTask wrapper, I detach a new thread. In this new thread, I set up the task, then run the run loop once...

[task launch] ;
if ([task isRunning]) {
    // Write data to stdin file/pipe
    // ...
    // ...
}

NSDate* limitTime = [NSDate dateWithTimeIntervalSinceNow:timeout] ;
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
                         beforeDate:limitTime] ;
// The above will block and be run to here either due to
// the posting of an NSTaskDidTerminateNotification, or the
// passing of limitTime, whichever occurs first.
if (![task isRunning]) {
    taskResult = [task terminationStatus] ;

    // Read stdout and stderr
    // ...
    // ...
}
else {
    taskResult = SSYShellTaskerErrorTimedOut ;

    // Clean up
    kill([task processIdentifier], SIGKILL) ;

    // Set NSError indicating timeout
    // ...
    // ...
}

Actually, I originally was doing this on the main thread, except that the -[NSRunLoop runMode:beforeDate] was in a while() loop. When the loop ran, I would check and see if there was a timeout, task was finished, or neither (presumably some other input source triggered the run). But then I found an obscure bug: If I had disabled undo registration in order to do some behind-the-scenes changes, it would re-enable undo registration. Uh, yeah, it took me a while to track that one down. Apparently, running a run loop that is already running is not a good idea. I suppose I could also have done it with a timer.

So, unless someone sees something wrong with detaching a new thread for the sole purpose of running an NSTask, I'm good to go. This version passes all of my unit tests ;)


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to