// it's not clear from appl's docs that this really waits
// until all data is flushed.
-static ComponentResult BlockWhileAudioUnitIsRunning( AudioUnit audioUnit, AudioUnitElement element )
+static ComponentResult BlockWhileAudioUnitIsRunning(
+ AudioUnit audioUnit,
+ AudioUnitElement element)
{
+ long waitTime = 100;
+ // If PaUtil_GetRingBufferWriteAvailable starts repetitively and
+ // consecutively returning that there is no data available, do eventually
+ // give up in order to allow the caller to handle such cases.
+ long totalTimeout = 0;
Boolean isRunning = 1;
while( isRunning ) {
UInt32 s = sizeof( isRunning );
ComponentResult err = AudioUnitGetProperty( audioUnit, kAudioOutputUnitProperty_IsRunning, kAudioUnitScope_Global, element, &isRunning, &s );
if( err )
return err;
- Pa_Sleep( 100 );
+ Pa_Sleep( waitTime );
+
+ // If a timeout is encountered, continue. However, testing has
+ // shown that it is possible to unplug a device and to wait here
+ // forever. In order to allow the caller to handle such cases of
+ // repeated timeouts, do eventually given up.
+ totalTimeout += waitTime;
+ if( PA_COREAUDIO_MIN_TIMEOUT_MSEC_ <= totalTimeout)
+ {
+ return paTimedOut;
+ }
}
return noErr;
}
VVDBUG(("StopStream()\n"));
VDBUG( ("Waiting for BLIO.\n") );
- waitUntilBlioWriteBufferIsFlushed( &stream->blio );
+ waitUntilBlioWriteBufferIsFlushed( &stream->blio);
VDBUG( ( "Stopping stream.\n" ) );
stream->state = STOPPING;
if( stream->outputUnit )
{
ERR_WRAP(AudioOutputUnitStop(stream->outputUnit));
- ERR_WRAP( BlockWhileAudioUnitIsRunning(stream->outputUnit,0) );
+ ERR_WRAP( BlockWhileAudioUnitIsRunning(stream->outputUnit,0));
ERR_WRAP(AudioUnitReset(stream->outputUnit,kAudioUnitScope_Global,0));
}
}
while( frames > 0 ) {\r
long avail;\r
long toRead;\r
+ // If PaUtil_GetRingBufferReadAvailable starts repetitively and\r
+ // consecutively returning that there is no data available, do eventually\r
+ // give up in order to allow the caller to handle such cases. \r
+ long totalTimeout = 0;\r
do {\r
avail = PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer );\r
/*\r
return ret;\r
#else\r
Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );\r
+\r
+ // If a timeout is encountered, continue. However, testing has\r
+ // shown that it is possible to unplug a device and to wait here\r
+ // forever. In order to allow the caller to handle such cases of\r
+ // repeated timeouts, do eventually given up. \r
+ totalTimeout += PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL; \r
+ if( PA_COREAUDIO_MAX_TIMEOUT_MSEC_ <= totalTimeout) \r
+ {\r
+ return paTimedOut;\r
+ } \r
#endif\r
}\r
} while( avail == 0 );\r
while( frames > 0 ) {\r
long avail = 0;\r
long toWrite;\r
+ // If PaUtil_GetRingBufferWriteAvailable starts repetitively and\r
+ // consecutively returning that there is no data available, do eventually\r
+ // give up in order to allow the caller to handle such cases. \r
+ long totalTimeout = 0;\r
\r
do {\r
avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer );\r
return ret;\r
#else\r
Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );\r
+\r
+ // If a timeout is encountered, continue. However, testing has\r
+ // shown that it is possible to unplug a device and to wait here\r
+ // forever. In order to allow the caller to handle such cases of\r
+ // repeated timeouts, do eventually given up. \r
+ totalTimeout += PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL; \r
+ if( PA_COREAUDIO_MAX_TIMEOUT_MSEC_ <= totalTimeout) \r
+ {\r
+ return paTimedOut;\r
+ } \r
#endif\r
}\r
} while( avail == 0 );\r
void waitUntilBlioWriteBufferIsFlushed( PaMacBlio *blio )\r
{\r
if( blio->outputRingBuffer.buffer ) {\r
+ // If PaUtil_GetRingBufferWriteAvailable starts repetitively and\r
+ // consecutively returning that there is no data available, do eventually\r
+ // give up in order to allow the caller to handle such cases. \r
+ long totalTimeout = 0;\r
long avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer );\r
while( avail != blio->outputRingBuffer.bufferSize ) {\r
if( avail == 0 )\r
+ {\r
Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );\r
+\r
+ // If a timeout is encountered, continue. However, testing has\r
+ // shown that it is possible to unplug a device and to wait here\r
+ // forever. In order to allow the caller to handle such cases of\r
+ // repeated timeouts, do eventually given up. \r
+ totalTimeout += PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL; \r
+ if( PA_COREAUDIO_MIN_TIMEOUT_MSEC_ <= totalTimeout) \r
+ {\r
+ return paTimedOut;\r
+ } \r
+ }\r
avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer );\r
}\r
}\r
+ return paNoError;\r
}\r
\r
\r