Re: waiting for async callback in main thread
Re: waiting for async callback in main thread
- Subject: Re: waiting for async callback in main thread
- From: John Engelhart <email@hidden>
- Date: Wed, 28 Oct 2009 02:13:17 -0400
On Wed, Oct 28, 2009 at 12:21 AM, Kyle Sluder <email@hidden> wrote:
> On Tue, Oct 27, 2009 at 8:53 PM, John Engelhart
> <email@hidden> wrote:
> > I would *STRONGLY* advise against doing this. While it may be perfectly
> safe
> > to recursively run a CFRunLoop, this says nothing about the implications
> of
> > doing so. At first glance, it would seem that everything a run loop
> "does"
> > as a result of 'running' needs to be safe to call recursively as well.
> This
> > condition is much harder to satisfy, and virtually guaranteed not hold
> true
> > for code that gets executed by the main threads run loop.
>
> Cocoa apps re-enter their run loops all the time. Mouse tracking
> would be an excellent example, but also turning asynchronous
> operations into synchronous ones, just like the OP described. (I was
> going to mention Distributed Objects, but perhaps that would not be a
> shining example.)
>
While Cocoa might do this, there's probably a few "important details" that
you're glossing over. Using a different run loop mode for the the recursive
run of the loop is a good example. I'd be willing to bet there's an
implicit assumption that the tranistion to NSModalPanelRunLoopMode or
NSEventTrackingRunLoopMode "only happens once". In a nutshell, one does not
recursively become modal or recursively begin tracking the mouse, you either
are or you aren't, and it would be an "illegal state transition" to go from
modal to modal.
For the sake of argument, let's say that this is what happens under the
hood. It's easy to see how this "only happens once" provides a natural
recursion barrier. While Cocoa / AppKit is pretty complex and may
technically violate "strict modal recursive mutual exclusion" (a save panel
that displays an alert sheet, for example), it's probably mostly true "in
spirit". Even the documentation for
(NSAlert)-beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo:
has rules about what you need to do if you want to "chain sheets from
the alertDidEndSelector", most of them would seem to be related to keeping
the "temporal ordering of events" assumptions valid.
> The key is to use a custom run loop mode. Schedule your observation
> only in the MyWaitingForResponseRunLoop mode, and only run that mode
> in your while loop. Reentrancy issue solved.
This assumes that you can control the run loop modes that the call back is
permitted to be run on, probably via some kind of modes:(NSArray
*)runLoopModesArray argument. If the SDK
uses performSelectorOnMainThread:withObject:waitUntilDone:, for example,
then the call back will be delivered on NSRunLoopCommonModes and running the
main run loop in MyWaitingForResponseRunLoop mode will cause the main thread
to dead lock.
_______________________________________________
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