Re: Stopping an NSRunLoop OR getting NSDistributedNotificationCenter notifications
Re: Stopping an NSRunLoop OR getting NSDistributedNotificationCenter notifications
- Subject: Re: Stopping an NSRunLoop OR getting NSDistributedNotificationCenter notifications
- From: James Bucanek <email@hidden>
- Date: Mon, 19 Jun 2006 10:08:15 -0700
Chris Kane wrote on Monday, June 19, 2006:
>Yes, NSDistributedNotifications are only delivered to the main thread.
>
>With your lock, btw, it's unclear if you are locking it in one thread
>and unlocking it in another, but if that's what you're doing, don't
>do that, the results are undefined -- POSIX allows that not to "work"
>completely at the pthreads layer. Even if you just want to change
>the condition, always -lock first, then -unlockWithCondition:, so
>that you've always locked the lock you're unlocking on that thread.
That's exactly why I'm using NSConditionalLock, and no I'm not locking in one thread and unlocking in another. I got bit by that last year and rewrote all of my code to use NSConditionalLocks.
I even filed a bug report that the documentation for NSLock doesn't mention this fact. Lo and behold, the last time I checked the NSLock documentation there was a big bold warning about locking in one thread and unlocking in another. Bug reports really do work!
>There's no need to poll every second, and when you see code looping
>and running the run loop, it isn't necessarily a polling loop. You
>have to look carefully at which method is being used.
>
>What you're supposed to do in your situation (per the original
>designers, more or less), is use
>
>- (BOOL)runBeforeDate:(NSDate *)limitDate;
>
>and loop, using [NSDate distantFuture] for the parameter. You'd use
>an NSPort which you'd registered with the run loop on the main
>thread, and NSPortMessage, to send a message to the main thread when
>the background thread wants it to terminate. The port's delegate
>handles the message, and the handling can be pretty trivial (like
>setting a flag). The Before variant methods return after processing
>approximately one input source; really, it's more like after one
>cycling of the run loop which has serviced a port. Of course, once
>you've switched to runBeforeDate: and a loop on the main thread, the
>need for the background thread may disappear and you could save
>yourself the trouble with the NSPort/NSPortMessage.
OK, I clearly don't understand the difference between runUntilDate: and runMode:beforeDate:. Re-reading the documentation again (slowly and out loud), I get the picture that runUntilDate: runs the loop repeatedly returning only after date has occurred. But runMode:beforeDate: processes exactly one event and then returns. Is that correct?
If that's correct, then I can do this far more simply than I thought. I don't even think I need anything as elaborate as you've outlined, as the message that will be terminating the process will always occur on the main thread (in response to a DO message or a distributed notification). So I don't think I have any cross-thread communications issues; the while(isRunning) loop that's running the loop should cycle as soon as my -stopDaemon message returns.
Random thought: Your NSPort/NSPortMessage idea is excellent, but wouldn’t' a performOnMainThread: message work just as well?
This is awesome. Thanks for the explanation.
>However, if you just want the process to die, just call exit() from
>the background thread. You need not futz with the main thread
>(except you need to change it to run the run loop to pick up
>distributed notifications).
That's what I'm doing now, but from a code structure standpoint it's just really ugly. The reason is that I have nested functions and classes, each of which conditionally initializes and then cleans up after itself as the sub-functions/objects/threads return. With exit() I have to somehow get the lower-level classes to destroy and clean up after the high-level classes before it calls exit(). Ugg.
--
James Bucanek
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden