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: Jerry Krinock <email@hidden>
- Date: Sun, 4 Apr 2010 21:00:48 -0700
On 2010 Apr 04, at 14:44, Ken Thomases wrote:
> Have you read and understood the documentation for -[NSRunLoop runMode:beforeDate:]?
Read? Yes. Understood? Well, probably I was misled by the way things "just almost worked".
> ... Frankly, it seems like pure luck that it's ever exiting.
> If you schedule a timer from an operation that's running on a non-main queue, then that will happen on an arbitrary thread that you don't own and can't make any assumptions about. The timer will be scheduled on that thread's run loop, which is bad.
Indeed, it was on a secondary thread. Oh, so many things to think about when you're multithreading!
> First, ...
> Second, ...
> Third, ...
> Fourth, ...
>
> 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.
> If you prefer, you can keep using your 'while' loop and schedule such a "sentinel" operation on the main queue on the theory that it will count as an input source. While you're at it, that operation's isFinished property would replace the isDone flag.
I believe that my -terminateWork is part of such a sentinel operation already, although I made my own "main queue", since this app works in 10.5 where +[NSOperationQueue mainQueue] is not yet available. If you meant to make this operation run on the main thread, I don't know how to do that since -isConcurrent is ignored in Mac OS 10.6.
> If that still doesn't work, you can use -performSelector:withObject:afterDelay: (from the main thread) or -performSelectorOnMainThread:withObject:waitUntilDone: (from a background thread) to signal the completion. I believe either of those is known to count as an input source for the purposes of terminating -runMode:beforeDate:.
In the Threading Programming Guide ▸ Run Loops ▸ Input Sources, there is a subsection titled "Cocoa Perform Selector Sources". This seems to imply that a -performSelector::: method is indeed a run loop source, with all the incorporated privileges and responsibilities. Although they don't explicitly state the effect upon -runMode:beforeDate:, I see that "The run loop processes all queued perform selector calls each time through the loop". And, it seems to work ...
- (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!
I'm happy with this, although I suspect someone might suggest something less kludgey.
I still wonder why my original code exitted after a 60-second timeout, though. It's as though Apple saw me coming, and so Cocoa secretly does some kind of "thread garbage collection" when "multithreading dummy" programming errors are detected :)
_______________________________________________
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