• 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
[SOLVED (but not pretty)] Running run loops in 10.6
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SOLVED (but not pretty)] Running run loops in 10.6


  • Subject: [SOLVED (but not pretty)] Running run loops in 10.6
  • From: Jerry Krinock <email@hidden>
  • Date: Sun, 20 Sep 2009 20:20:18 -0700

Well, I don't think anyone is going to like this solution, but it seems to be working for me and it comes with a plausible explanation...

On 2009 Sep 16, at 14:07, Chris Kane wrote:

Go back to the main thread. Setup a oneshot NSTimer for the timeout period. Setup a notification handler to listen for the NSTaskDidTerminateNotification. If the timer fires first, kill the task, unregister the notification handler, etc. If the notification happens first, invalidate the timer, unregister the notification handler, etc. Don't run the run loop yourself. Let your code be event-driven.

This works fine for the main thread, but if I need to run this in a secondary thread or background tool, I still need something to make the thread's or tool's -[NSRunLoop runMode:beforeDate:] return, so that the thread or tool can exit. To solve that problem, at the end of my notification handler and timer handler, I send this message:


    [SSYRunLoopTickler tickle] ;

to the following class.  Further explanation is in the comments.


***** Header File *****

#import <Cocoa/Cocoa.h>

/*!
 @brief    A class providing a method to "tickle" the run loop with a
 dummy input source, causing a blocked -[NSRunLoop runMode:beforeDate:]
 to return.

@details This is useful in designs which worked in Mac OS 10.5 because
they have run loops in background tools or secondary threads that were
being run when needed by behind-the-scenes input sources. These input
sources were apparently added by Cocoa in Mac OS 10.5, but they are not
added in Mac OS 10.6. This is probably because 10.6 is using Grand
Central Dispatch or something else instead of run loops for whatever
it's doing behind the scenes.
*/
@interface SSYRunLoopTickler : NSObject {
}


/*!
 @brief    Inserts a dummy input source into the current run loop in
 NSDefaultRunLoopMode, and sends a message to it, which will cause a
 blocked -[NSRunLoop runMode:beforeDate:] elsewhere in the program to
 return.

 @details  Removes the dummy input source after a delay of 0.0.
*/
+ (void)tickle ;

@end


***** Implementation File *****

#import "SSYRunLoopTickler.h"

@implementation SSYRunLoopTickler

+ (void)tickle {
NSPort* sendPort = [NSMachPort port] ;
[[NSRunLoop currentRunLoop] addPort:sendPort
forMode:NSDefaultRunLoopMode] ;
NSPort* receivePort = [NSMachPort port] ;
NSPortMessage* message = [[NSPortMessage alloc] initWithSendPort:sendPort
receivePort:receivePort
components:nil] ;
BOOL sentOk = [message sendBeforeDate:[NSDate dateWithTimeIntervalSinceNow:1.0]] ;
if (!sentOk) {
// Should actually return an NSError, but I don't think
// this will ever happen in real life, so I'm just going
// to log it.
NSLog(@"%s failed to send its message.", __PRETTY_FUNCTION__) ;
}


    [message release] ;

    // If I remove the port now, the desired "tickle" causing a
    // blocked -[NSRunLoop runMode:beforeDate:] to return will
    // not occur.  But if I do so with a delay of 0.0, it works.
    [self performSelector:@selector(removePort:)
               withObject:sendPort
               afterDelay:0.0] ;
}

/*!
 Just a debugging note:  If the +tickle message is sent from a
 secondary thread which exits, the delayed performance of this
 method will not occur, but that is OK because when its thread
 ends the system should remove the port.
 */
+ (void)removePort:(NSPort*)port {
    [[NSRunLoop currentRunLoop] removePort:port
                                   forMode:NSDefaultRunLoopMode] ;
}


@end

_______________________________________________

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


References: 
 >NSTask is "Thread Unsafe". What does that mean? (From: Jerry Krinock <email@hidden>)
 >Re: NSTask is "Thread Unsafe". What does that mean? (From: "Adam R. Maxwell" <email@hidden>)
 >Need -[NSTask waitUntilExitOrTimeout:] (was NSTask "Thread Unsafe"...) (From: Jerry Krinock <email@hidden>)
 >Re: Need -[NSTask waitUntilExitOrTimeout:] (was NSTask "Thread Unsafe"...) (From: Chris Kane <email@hidden>)
 >Running run loops in 10.6 (was: Need -[NSTask waitUntilExitOrTimeout:]) (From: Jerry Krinock <email@hidden>)

  • Prev by Date: Data Model Versions and -fetchRequestTemplateForName
  • Next by Date: Re: NSTextField black outline, not drawing in background thread when in a custom NSControl?
  • Previous by thread: Re: Running run loops in 10.6 (was: Need -[NSTask waitUntilExitOrTimeout:])
  • Next by thread: coding NSNumber in NSArray?
  • Index(es):
    • Date
    • Thread