• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Stopping an NSRunLoop OR getting NSDistributedNotificationCenter notifications
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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

References: 
 >Re: Stopping an NSRunLoop OR getting NSDistributedNotificationCenter notifications (From: Chris Kane <email@hidden>)

  • Prev by Date: Re: selectColumn not working with bound tableview
  • Next by Date: Displaying Audio & Video in NSTextView
  • Previous by thread: Re: Stopping an NSRunLoop OR getting NSDistributedNotificationCenter notifications
  • Next by thread: NSWindow's setContentView
  • Index(es):
    • Date
    • Thread