Hi Jens.

Why do you just set a short timeout rather than distantFuture? That's why I 
usually do.

-Jeff


On Aug 5, 2010, at 12:10 PM, Jens Alfke wrote:

> I’ve got a place in my code where I need to block waiting for an 
> otherwise-asynchronous action to complete, so I use a fairly standard 
> technique of running a nested runloop. But sometimes the runloop just keeps 
> waiting forever even after the action’s completed, so my app locks up.
> 
> The wait code looks like:
>    while (_busy) {
>        if (![[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode 
> beforeDate: [NSDate distantFuture]])
>            break;
>    }
> 
> where _busy is an instance variable that will be set to NO by a notification 
> observer method when the async action notifies me that it’s complete.
> 
> What I see happening when the bug strikes is that the underlying async code 
> completes (it gets a notification from an NSTask it started), but the runloop 
> keeps going forever, without returning from my above -runMode: call. This 
> doesn’t jibe with my understanding of -runMode: — the docs say it returns 
> after an input source is processed.
> 
> Here [fig. 1] is the backtrace from gdb at the moment the NSTask notification 
> is received. The runloop is inside a function “__CFRunLoopDoBlocks”, which in 
> turn calls a block belonging to NSConcreteTask. Presumably this is some 
> implementation detail of NSTask, that it uses a block to delay the actual 
> launch.
> 
> What I’m guessing is that running a delayed block does not count as an “input 
> source”. That’s kind of frustrating, because it makes the runloop’s behavior 
> highly dependent on internal details of framework classes — in this case, how 
> was I to know that NSTask used a block and not an input source to handle 
> this? And presumably that means the behavior has changed in 10.6, which would 
> explain some weird NSTask related problems I’ve seen over the past year.
> 
> Anyway. How the heck do I work around this? It seems that I need some kind of 
> call that will give the runloop a swift kick and get it to exit the runMode: 
> method. But I don’t see any explicit API for that. Do I need to kludge 
> something together by adding an input source? (A delayed-perform probably 
> won’t work, because I think those are implemented using timers, which are 
> documented as not causing -runMode: to exit.)
> 
> —Jens
> 
> PS: Oh yes, this is 10.6.4, on a 2009-model iMac.
> 
> [fig. 1: the backtrace:]
> 
> #0  -[KSDownloadAction taskExited:] (self=0x30f440, _cmd=0x29032, 
> notification=0x403040) at KSDownloadAction.m:323
> #1  0x929201c3 in _nsnote_callback ()
> #2  0x97fcb3c3 in __CFXNotificationPost ()
> #3  0x97fcadca in _CFXNotificationPostNotification ()
> #4  0x92915090 in -[NSNotificationCenter 
> postNotificationName:object:userInfo:] ()
> #5  0x929aebf5 in __-[NSConcreteTask launchWithDictionary:]_block_invoke_2 ()
> #6  0x97ffc861 in __CFRunLoopDoBlocks ()
> #7  0x97fad613 in __CFRunLoopRun ()
> #8  0x97fac094 in CFRunLoopRunSpecific ()
> #9  0x97fabec1 in CFRunLoopRunInMode ()
> #10 0x9295a378 in -[NSRunLoop(NSRunLoop) runMode:beforeDate:] ()
> #11 0x00011887 in -[KSRegistration updateSynchronously] (self=0x207ac0, 
> _cmd=0x28b9d) at KSRegistration.m:153
> #12 0x00010f40 in main (argc=4, argv=0xbffff66c) at main.m:288

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to