Re: Synchronous method: How to "wait" for Notification to occur?
Re: Synchronous method: How to "wait" for Notification to occur?
- Subject: Re: Synchronous method: How to "wait" for Notification to occur?
- From: Wade Tregaskis <email@hidden>
- Date: Fri, 22 Aug 2003 11:10:32 +1000
A class I have created has a synchronous method which must not return
until some asynchronous operation has completed and the result is
ready. The asynchronous operation typically takes 20 - 500 mS to
complete. The asynchronous operation signals its completion by a
Notification.
What's the most elegant way for the method to "wait" for the
Notification ? The main RunLoop must be kept active, and the "wait"
must not hog CPU time by continually checking if the Notification has
arrived. Any good ideas ?
I wish I had a perfect answer for this, but I also am at a loss as to
how to do this. I too have a setup which requires this functionality
unavoidably, and it's been giving me headaches for nearly two months.
The short answer is that there's no good way to do this (that I know
of; I've been looking for a very long time). The longer answer is that
there's two possibilities I'm aware of:
a) Run the appropriate run loops while you're waiting for data, have
the notifications set some sort of flag, and check for this flag inside
your blocking function (in between running the loop(s)). The problem
with this is that it doesn't always seem to work (run loops are
mysterious creatures), and also causes headaches if you run the loop,
which causes an event in another instance, which runs the run loop...
you get the idea. Either a stack overflow, or more likely your whole
system jams up because your second blocking call is waiting for data
from the first, which can't do anything until the second finished.
Nightmare.
Also, the above system can play real havoc with autoreleased objects,
since running the run loop sometimes clears them out. Then again,
sometimes it doesn't. Again, mysterious creatures. The only real
solution is to not use the run loop's autorelease pool, which obviously
isn't convenient if you're using a single-threaded design.
b) Use Objective-C++'s functions-in-functions support to have the
notification call back into the blocking method. I don't know how
exactly you go about doing this, but I do know that this has been used
successful by others in similar [pure C++] situations. My
understanding is that execution halts when you get to the embedded
function [as an arbitrary rule], so you can resume by simply calling
that function, which need not do anything - it will fall out back into
the embodying function. But there are some issues with how this works
with run loops, if at all, since if the original method came off the
run loop you're waiting on, you'll never receive the notification
anyway, because [obviously] you're still blocking, waiting for the
notification... argh.
Another alternative I'm tossing around in my head is to hand a lock to
a timer, which could be triggered by the notification... the blocking
method would thus simply try to acquire the lock, and then wait until
it's unlocked by the timer. Or somesuch. This is pretty much the same
as (b) though, and still raises the issue of how to get your run
loop(s) to work while you're blocking from within them.
You could possibly solve the run loop problem by segregating your code
so that you never call your blocking method from the run loop you're
waiting for the notification on.. but this is a terrible solution for
most applications, where you either (i) only have one run loop or (ii)
can't control what run loop will end up calling your blocking method.
Wade Tregaskis
-- Sed quis custodiet ipsos custodes?
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.