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: Tue, 20 Jun 2006 09:59:25 -0700
Chris Kane wrote on Monday, June 19, 2006:
>Also, source which are processed by reentrant activations of the run
>loop don't count as part of this "return after doing something"
>business. For example, if a timer fires, and runs the run loop
>during its callout, it may process any number of other "events/
>sources", which won't cause the base activation to return when the
>timer callout returns to the run loop.
For anyone who's interested, I have the working just fine now. But just to dig a little deeper, I was wondering about the reentrant run loop problem.
I assume that if a timer ran the current run loop itself it could potentially "steal" my event from the port, process it, then keep going because it doesn't check my magic "stop" variable. It that correct?
I also assume that if the reentrant run loop was run in a different mode (NSModalPanelRunLoopMode or NSConnectionReplyMode), then my port (which is NSDefaultRunLoopMode) wouldn't process that event because it's in a different mode? So I should only get in trouble if a timer or performSelector caused a reentrant run loop to run in the NSDefaultRunLoopMode mode, stealing my event but not checking for the exit state?
(This is almost purely an academic discussion; I just want to understand the problem. My application has no GUI and won't be putting up modal dialogs or anything like that, so I can't see why it would ever be using reentrant run loops -- with a possible exception for Distributed Objects.)
Finally, I have one more niggling question: -[NSPortMessage sendBeforeDate:] states that
"If the message cannot be sent immediately, the sending thread blocks until
either the message is sent or aDate is reached. Sent messages are queued to
minimize blocking, but failure can occur if multiple messages are sent to a
port faster than the port’s owner can receive them, causing the queue to fill
up."
I'm sending sendBeforeDate: on the main thread and I'm worried about the potential for a deadlock. Should I be spawning a separate thread to send the message or can I always rely on the message queuing to prevent blocking of a single message?
For anyone who's interested, here's the code I wrote to do this:
----------------------------------------------------------------------
@interface QuantumScheduler : NSObject
{
@private
BOOL isRunning; // daemon is running
NSPort* receiveStopMessagePort;
....
- (void)run
{
NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
NSDate* endOfTime = [NSDate distantFuture];
receiveStopMessagePort = [[NSPort port] retain];
[receiveStopMessagePort setDelegate:self];
[runLoop addPort:receiveStopMessagePort forMode:NSDefaultRunLoopMode];
isRunning = YES;
while (isRunning && [runLoop runMode:NSDefaultRunLoopMode
beforeDate:endOfTime])
;
}
- (void)fireTerminateMessage
{
// Send an empty message to the receiveStopMessagePort; This is a
special port just for getting "terminate" requests
NSPortMessage* emptyQuitMessage = [[NSPortMessage alloc]
initWithSendPort:receiveStopMessagePort
receivePort:receiveStopMessagePort
components:[NSArray arrayWithObject:[NSData data]]];
[emptyQuitMessage sendBeforeDate:[NSDate distantFuture]];
}
- (void)handlePortMessage:(NSPortMessage*)portMessage
{
#pragma unused(portMessage)
// The message is unimportant; the only message that this port
receives is the request to stop running.
// Sending a message through a port ensures that the run loop
will get a chance
// to test the isRunning flag and terminate the run loop.
isRunning = NO;
}
--
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