Re: Run Loop in Tool Idles for 60.0 seconds before exitting [Solved]
Re: Run Loop in Tool Idles for 60.0 seconds before exitting [Solved]
- Subject: Re: Run Loop in Tool Idles for 60.0 seconds before exitting [Solved]
- From: Ken Thomases <email@hidden>
- Date: Mon, 5 Apr 2010 10:26:34 -0500
On Apr 4, 2010, at 11:00 PM, Jerry Krinock wrote:
> On 2010 Apr 04, at 14:44, Ken Thomases wrote:
>
>> Since you're already using operations, why use the above 'while' loop, anyway? Why not use -[NSOperationQueue waitUntilAllOperationsAreFinished]. Or schedule a "sentinel" operation that depends on all of the other operations, either directly or indirectly, and then invoke -waitUntilFinished on it.
>
> Alas, many of my operations call back to perform Core Data operations on the main thread. (Syncing multiple managed object contexts never looked like much fun to me.) The disadvantage is that this nice, clean approach you suggest results in deadlock.
Ah, yes. This approach won't work in that case.
> - (void)tickleRunLoop {
> // No op
> }
>
> /* This method is called from the -main of the final NSOperation
> in an Agent task. Like all NSOperations, it's running on a
> secondary thread. */
> - (void)terminateWork {
> // Set the exit condition for Worker
> [[AgentPerformer sharedPerformer] setIsDone:YES] ;
>
> // Now install an input source on the main run loop, so that
> // in Worker-main.m, in main(), -runLoop:beforeDate: will
> // unblock, the above exit condition will be tested, found
> // to be true, and cause the loop to break so that Worker
> // can continue along to exit.
> [self performSelectorOnMainThread:@selector(tickleRunLoop)
> withObject:nil
> waitUntilDone:YES] ;
> }
>
> This is actually a simple modification of the code at the end of my original post, except that now we remember to call back to the main thread -- Thank you, Ken!
You're welcome.
> I'm happy with this, although I suspect someone might suggest something less kludgey.
You might have -terminateWork only do the -setIsDone: step. Then, instead of the operation's -main directly invoking -terminateWork, it could perform it on the main thread. That way, the setting of isDone is actually happening on the main thread, plus it serves as its own "tickle" of the run loop.
Also, there's no need to pass YES for the waitUntilDone: parameter. Since this is the last thing you need to be done on the background thread, there's no need to be sure it's complete before exiting. In general, it's best to avoid blocking the worker threads managed for your by NSOperationQueue or GCD.
> I still wonder why my original code exitted after a 60-second timeout, though.
Well, the run loop documentation specifically warns that you can't be sure that your input sources are the only input sources in the run loop. The frameworks may put their own input sources there, too.
In this case, my guess is that it was the last worker thread timing out from waiting for work, and shutting itself down. It may have performed some internal selector on NSOperationQueue on the main thread, to inform it that the worker thread had terminated.
Regards,
Ken
_______________________________________________
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