pa_linux_alsa: fix hang in callback caused by abort
The author of this patch is Alan Horstmann. Fixes ticket #251
This commit is contained in:
parent
05da7a854d
commit
f17d549093
1 changed files with 26 additions and 9 deletions
|
|
@ -3805,8 +3805,23 @@ static PaError PaAlsaStream_WaitForFrames( PaAlsaStream *self, unsigned long *fr
|
|||
totalFds += self->playback.nfds;
|
||||
}
|
||||
|
||||
#ifdef PTHREAD_CANCELED
|
||||
if( self->callbackMode )
|
||||
{
|
||||
/* To allow 'Abort' to terminate the callback thread, enable cancelability just for poll() (& disable after) */
|
||||
pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL );
|
||||
}
|
||||
#endif
|
||||
|
||||
pollResults = poll( self->pfds, totalFds, pollTimeout );
|
||||
|
||||
#ifdef PTHREAD_CANCELED
|
||||
if( self->callbackMode )
|
||||
{
|
||||
pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, NULL );
|
||||
}
|
||||
#endif
|
||||
|
||||
if( pollResults < 0 )
|
||||
{
|
||||
/* XXX: Depend on preprocessor condition? */
|
||||
|
|
@ -4175,12 +4190,18 @@ static void *CallbackThreadFunc( void *userData )
|
|||
int streamStarted = 0;
|
||||
|
||||
assert( stream );
|
||||
/* Not implemented */
|
||||
assert( !stream->primeBuffers );
|
||||
|
||||
/* Execute OnExit when exiting */
|
||||
pthread_cleanup_push( &OnExit, stream );
|
||||
|
||||
/* Not implemented */
|
||||
assert( !stream->primeBuffers );
|
||||
#ifdef PTHREAD_CANCELED
|
||||
/* 'Abort' will use thread cancellation to terminate the callback thread, but the Alsa-lib functions
|
||||
* are NOT cancel-safe, (and can end up in an inconsistent state). So, disable cancelability for
|
||||
* the thread here, and just re-enable it for the poll() in PaAlsaStream_WaitForFrames(). */
|
||||
pthread_testcancel();
|
||||
pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, NULL );
|
||||
#endif
|
||||
|
||||
/* @concern StreamStart If the output is being primed the output pcm needs to be prepared, otherwise the
|
||||
* stream is started immediately. The latter involves signaling the waiting main thread.
|
||||
|
|
@ -4265,10 +4286,6 @@ static void *CallbackThreadFunc( void *userData )
|
|||
{
|
||||
xrun = 0;
|
||||
|
||||
#ifdef PTHREAD_CANCELED
|
||||
pthread_testcancel();
|
||||
#endif
|
||||
|
||||
/** @concern Xruns Under/overflows are to be reported to the callback */
|
||||
if( stream->underrun > 0.0 )
|
||||
{
|
||||
|
|
@ -4299,11 +4316,12 @@ static void *CallbackThreadFunc( void *userData )
|
|||
#if 0
|
||||
CallbackUpdate( &stream->threading );
|
||||
#endif
|
||||
|
||||
CalculateTimeInfo( stream, &timeInfo );
|
||||
PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, cbFlags );
|
||||
cbFlags = 0;
|
||||
|
||||
/* CPU load measurement should include processing activivity external to the stream callback */
|
||||
/* CPU load measurement should include processing activity external to the stream callback */
|
||||
PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
|
||||
|
||||
framesGot = framesAvail;
|
||||
|
|
@ -4334,7 +4352,6 @@ static void *CallbackThreadFunc( void *userData )
|
|||
{
|
||||
/* Go back to polling for more frames */
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if( paContinue != callbackResult )
|
||||
|
|
|
|||
Loading…
Reference in a new issue