]> git.alsa-project.org Git - alsa-lib.git/commitdiff
pcm: fix wait condition in snd_pcm_write_areas() to avoid return zero
authorJaroslav Kysela <perex@perex.cz>
Tue, 9 Apr 2019 07:14:33 +0000 (09:14 +0200)
committerJaroslav Kysela <perex@perex.cz>
Tue, 9 Apr 2019 08:27:36 +0000 (10:27 +0200)
The hw_ptr might be updated during the snd_pcm_may_wait_for_avail_min() call,
so even if it returns zero (OK), the avail must be updated again.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
src/pcm/pcm.c

index 11aec8052135a3bf6d44fe959f0262da419b20a6..f0dc28d35bac0c1b8bf331a4f783d0afe32d754e 100644 (file)
@@ -7389,18 +7389,27 @@ snd_pcm_sframes_t snd_pcm_write_areas(snd_pcm_t *pcm, const snd_pcm_channel_area
                        err = avail;
                        goto _end;
                }
-               if ((state == SND_PCM_STATE_RUNNING &&
-                    size > (snd_pcm_uframes_t)avail &&
-                    snd_pcm_may_wait_for_avail_min(pcm, avail))) {
-                       if (pcm->mode & SND_PCM_NONBLOCK) {
-                               err = -EAGAIN;
+               if (state == SND_PCM_STATE_RUNNING &&
+                   size > (snd_pcm_uframes_t)avail) {
+                       if (snd_pcm_may_wait_for_avail_min(pcm, avail)) {
+                               if (pcm->mode & SND_PCM_NONBLOCK) {
+                                       err = -EAGAIN;
+                                       goto _end;
+                               }
+
+                               err = snd_pcm_wait_nocheck(pcm, -1);
+                               if (err < 0)
+                                       break;
+                               goto _again;
+                       }
+                       /* the snd_pcm_may_wait_for_avail_min may check against the
+                        * updated hw.ptr (slaves), get the avail again here
+                        */
+                       avail = __snd_pcm_avail_update(pcm);
+                       if (avail < 0) {
+                               err = avail;
                                goto _end;
                        }
-
-                       err = snd_pcm_wait_nocheck(pcm, -1);
-                       if (err < 0)
-                               break;
-                       goto _again;                    
                }
                frames = size;
                if (frames > (snd_pcm_uframes_t) avail)