Re: Questions on MIDINotifications and threads
Re: Questions on MIDINotifications and threads
- Subject: Re: Questions on MIDINotifications and threads
- From: Kurt Revis <email@hidden>
- Date: Mon, 18 Feb 2002 22:22:04 -0800
On Monday, February 18, 2002, at 09:36 PM, Pete Yandell wrote:
Am I correct in assuming that my MIDINotifyProc will get called from a
thread over than my applications main thread?
No, the notify proc is called in your app's main thread--the
notification comes in through its run loop. (I'm not sure exactly how
this is implemented--I would think CoreMIDI would set up a one-shot
timer to do this but I haven't looked at it lately.)
What seems to be happening in my app at the moment is that a
notification arrives and then, half way through the method that
processes the notification, another notification arrives and interrupts
the first. (I presume this means that my MIDINotifyProc is actually
being run in two separate CoreMIDI threads simultaneously!) Meanwhile
my app is halfway through updating its data structures and gets mighty
confused. Is this expected behavior?
That's not actually what's happening. I bet you are calling CoreMIDI
from within your notification proc, and then your notification proc gets
called again in the middle of the CoreMIDI call. (Set a breakpoint on
your notification proc and check the backtrace.)
What is happening is that CoreMIDI internally uses the run loop to
communicate with the MIDIServer process. So calling, say,
MIDIGetNumberOfSources() causes a request to be sent to the MIDIServer,
and then the run loop is run. When the MIDIServer sends a response back,
it comes in through the run loop, and the CoreMIDI function returns it
to you.
The problem here is that CoreMIDI is running its internal run loop in
the default run loop mode (which is the same mode in which your app does
its top-level run loop processing). I really think this is a bug, and
that it should be running in its own private mode. (I've filed a bug on
this, #2852701.)
I think the notification is set to be delivered in the default run loop
mode. Normally this would mean that you'd only get it when you normally
get events in your app, but because of the above bug, it can also get
delivered while CoreMIDI is running the run loop, waiting for a response
from the MIDIServer... which, as you see, can be while you are already
handling the notification.
So how do you deal with this? You need to make your notifyProc
reentrant. Here's what I do:
static void getMIDINotification(const MIDINotification *message, void
*refCon)
{
static Boolean isHandlingNotification = FALSE;
static Boolean retryAfterDone = FALSE;
if (isHandlingNotification) {
retryAfterDone = TRUE;
return;
}
do {
isHandlingNotification = TRUE;
retryAfterDone = FALSE;
// Do your work here.
// It might cause more notifications to get delivered, which
will cause us
// to go through this loop again...
isHandlingNotification = FALSE;
} while (retryAfterDone);
}
Clear as mud?
--
Kurt Revis
email@hidden
_______________________________________________
coreaudio-api mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/coreaudio-api
Do not post admin requests to the list. They will be ignored.