1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
Description: handle EPIPE from alsa_snd_pcm_poll_descriptors
was: pa_linux_alsa.c:3636 Assertion failed
Origin: https://lists.columbia.edu/pipermail/portaudio/2019-July/001888.html
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=944509
Forwarded: not-needed
Justification: taken from upstream dev mailing list post
Author: Sam Mason <assumetrue@gmail.com>
Reviewed-by: Norbert Preining <norbert@preining.info>
Applied-Upstream: no
--- a/src/hostapi/alsa/pa_linux_alsa.c
+++ b/src/hostapi/alsa/pa_linux_alsa.c
@@ -3633,12 +3633,18 @@ error:
/** Fill in pollfd objects.
*/
-static PaError PaAlsaStreamComponent_BeginPolling( PaAlsaStreamComponent* self, struct pollfd* pfds )
+static PaError PaAlsaStreamComponent_BeginPolling( PaAlsaStreamComponent* self, struct pollfd* pfds, int *xrunOccurred )
{
PaError result = paNoError;
int ret = alsa_snd_pcm_poll_descriptors( self->pcm, pfds, self->nfds );
- (void)ret; /* Prevent unused variable warning if asserts are turned off */
- assert( ret == self->nfds );
+ if( -EPIPE == ret )
+ {
+ *xrunOccurred = 1;
+ }
+ else
+ {
+ assert( ret == self->nfds );
+ }
self->ready = 0;
@@ -3799,17 +3805,22 @@ static PaError PaAlsaStream_WaitForFrame
if( pollCapture )
{
capturePfds = self->pfds;
- PA_ENSURE( PaAlsaStreamComponent_BeginPolling( &self->capture, capturePfds ) );
+ PA_ENSURE( PaAlsaStreamComponent_BeginPolling( &self->capture, capturePfds, &xrun ) );
totalFds += self->capture.nfds;
}
if( pollPlayback )
{
/* self->pfds is in effect an array of fds; if necessary, index past the capture fds */
playbackPfds = self->pfds + (pollCapture ? self->capture.nfds : 0);
- PA_ENSURE( PaAlsaStreamComponent_BeginPolling( &self->playback, playbackPfds ) );
+ PA_ENSURE( PaAlsaStreamComponent_BeginPolling( &self->playback, playbackPfds, &xrun ) );
totalFds += self->playback.nfds;
}
+ if ( xrun )
+ {
+ break;
+ }
+
#ifdef PTHREAD_CANCELED
if( self->callbackMode )
{
|