Re: AudioUnit problem: CFRunLoopRunInMode() spins after first thread exits, and second thread begins?
Re: AudioUnit problem: CFRunLoopRunInMode() spins after first thread exits, and second thread begins?
- Subject: Re: AudioUnit problem: CFRunLoopRunInMode() spins after first thread exits, and second thread begins?
- From: Stephen Davis <email@hidden>
- Date: Thu, 16 Oct 2008 10:08:27 -0700
On Oct 16, 2008, at 9:17 AM, Jeremy Friesner wrote:
Hi Jeff,
Jeff Moore wrote:
>According to the documentation for CFRunLoopRunInMode(),
kCFRunLoopRunFinished is returned whenever the
>run loop doesn't have any sources or timers installed on it. That
makes me think that there is a problem
>with how you are setting things up.
I think you're probably right, but it's not obvious to me what I'm
doing wrong. The setup and teardown code is the same code in both
the first (working) thread and the second (CPU-spinning) thread.
To make it easier to figure out, I've boiled my code down to a
simple unit test. If you compile the standalone .cpp file at the
following URL ("g++ coreaudio_unit_test.cpp -framework AudioUnit -
framework CoreServices") and run it with no arguments, it should
reproduce the problem.
http://public.msli.com/lcs/jaf/coreaudio_unit_test.cpp
Expected behavior of the unit test:
(1) Play an ugly sine wave for 5 seconds, with minimal CPU usage
(2) Pause for two seconds of silence
(3) Goto (1)
Observed behavior of the unit test (on my 8-core Xeon MacPro, with
Leopard/10.5.5):
(1) Plays an ugly sine wave for 5 seconds, with minimal CPU usage
(2) Pauses for two seconds of silence
(3) Plays the ugly sine wave for 5 more seconds, but now it uses
100% CPU on one core, according to Activity Monitor (!!!)
(4) Goto (2)
Can anyone reproduce this problem using the program at the URL
above? If so, any ideas as to what is going wrong?
As Jeff said, a CFRunLoop must have a runloop "source" attached to it
in order to block when you call CFRunLoopRunInMode(). Since you don't
create a source yourself, what is probably happening is that your
initial thread makes some call that ends up implicitly creating a
runloop source on that thread and things work normally. Subsequent
iterations of the thread don't get that implicit source creation so
the runloop just returns immediately and you spin like mad.
You can create a custom runloop source that is never signaled. This
will keep the runloop from returning immediately. It would look
something like this (coded from memory, no guarantees):
static void DoNothingPerformProc( void * refcon )
{
// never called, does nothing
}
{
...
CFRunLoopSourceContext context = {};
CFRunLoopSourceRef source;
context.version = 0;
context.perform = DoNothingPerformProc;
source = CFRunLoopSourceCreate( nil, 0, &context );
if ( source != nil )
{
CFRunLoopAddSource( CFRunLoopGetCurrent(), source,
kCFRunLoopDefaultMode );
--- you need to clean up this runloop source when the thread exits ---
...
}
hth,
stephen
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden