]> git.alsa-project.org Git - alsa-lib.git/commitdiff
pcm_plugin: fix appl pointer not correct when mmap_commit() return error
authorShengjiu Wang <shengjiu.wang@freescale.com>
Wed, 6 Apr 2016 11:02:12 +0000 (19:02 +0800)
committerTakashi Iwai <tiwai@suse.de>
Thu, 7 Apr 2016 14:19:01 +0000 (16:19 +0200)
When snd_pcm_mmap_commit() return error, the appl pointer is also updated.
which cause the avail_update()'s result wrong.
This patch move the snd_pcm_mmap_appl_forward() to the place when
snd_pcm_mmap_commit() is successfully returned.

Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
src/pcm/pcm_plugin.c

index d007e8c8bd4ab2245c6d413616d94b2ac7dffc45..940491dbc84bc2e0c74c435cd2aa33290dcab36d 100644 (file)
@@ -279,18 +279,22 @@ static snd_pcm_sframes_t snd_pcm_plugin_write_areas(snd_pcm_t *pcm,
                        return -EPIPE;
                }
                snd_atomic_write_begin(&plugin->watom);
-               snd_pcm_mmap_appl_forward(pcm, frames);
                result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
                if (result > 0 && (snd_pcm_uframes_t)result != slave_frames) {
                        snd_pcm_sframes_t res;
                        res = plugin->undo_write(pcm, slave_areas, slave_offset + result, slave_frames, slave_frames - result);
-                       if (res < 0)
+                       if (res < 0) {
+                               snd_atomic_write_end(&plugin->watom);
                                return xfer > 0 ? (snd_pcm_sframes_t)xfer : res;
+                       }
                        frames -= res;
                }
-               snd_atomic_write_end(&plugin->watom);
-               if (result <= 0)
+               if (result <= 0) {
+                       snd_atomic_write_end(&plugin->watom);
                        return xfer > 0 ? (snd_pcm_sframes_t)xfer : result;
+               }
+               snd_pcm_mmap_appl_forward(pcm, frames);
+               snd_atomic_write_end(&plugin->watom);
                offset += frames;
                xfer += frames;
                size -= frames;
@@ -325,19 +329,23 @@ static snd_pcm_sframes_t snd_pcm_plugin_read_areas(snd_pcm_t *pcm,
                        return -EPIPE;
                }
                snd_atomic_write_begin(&plugin->watom);
-               snd_pcm_mmap_appl_forward(pcm, frames);
                result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
                if (result > 0 && (snd_pcm_uframes_t)result != slave_frames) {
                        snd_pcm_sframes_t res;
                        
                        res = plugin->undo_read(slave, areas, offset, frames, slave_frames - result);
-                       if (res < 0)
+                       if (res < 0) {
+                               snd_atomic_write_end(&plugin->watom);
                                return xfer > 0 ? (snd_pcm_sframes_t)xfer : res;
+                       }
                        frames -= res;
                }
-               snd_atomic_write_end(&plugin->watom);
-               if (result <= 0)
+               if (result <= 0) {
+                       snd_atomic_write_end(&plugin->watom);
                        return xfer > 0 ? (snd_pcm_sframes_t)xfer : result;
+               }
+               snd_pcm_mmap_appl_forward(pcm, frames);
+               snd_atomic_write_end(&plugin->watom);
                offset += frames;
                xfer += frames;
                size -= frames;
@@ -423,19 +431,23 @@ snd_pcm_plugin_mmap_commit(snd_pcm_t *pcm,
                frames = plugin->write(pcm, areas, appl_offset, frames,
                                       slave_areas, slave_offset, &slave_frames);
                snd_atomic_write_begin(&plugin->watom);
-               snd_pcm_mmap_appl_forward(pcm, frames);
                result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
-               snd_atomic_write_end(&plugin->watom);
                if (result > 0 && (snd_pcm_uframes_t)result != slave_frames) {
                        snd_pcm_sframes_t res;
                        
                        res = plugin->undo_write(pcm, slave_areas, slave_offset + result, slave_frames, slave_frames - result);
-                       if (res < 0)
+                       if (res < 0) {
+                               snd_atomic_write_end(&plugin->watom);
                                return xfer > 0 ? xfer : res;
+                       }
                        frames -= res;
                }
-               if (result <= 0)
+               if (result <= 0) {
+                       snd_atomic_write_end(&plugin->watom);
                        return xfer > 0 ? xfer : result;
+               }
+               snd_pcm_mmap_appl_forward(pcm, frames);
+               snd_atomic_write_end(&plugin->watom);
                if (frames == cont)
                        appl_offset = 0;
                else
@@ -490,19 +502,23 @@ static snd_pcm_sframes_t snd_pcm_plugin_avail_update(snd_pcm_t *pcm)
                        frames = (plugin->read)(pcm, areas, hw_offset, frames,
                                              slave_areas, slave_offset, &slave_frames);
                        snd_atomic_write_begin(&plugin->watom);
-                       snd_pcm_mmap_hw_forward(pcm, frames);
                        result = snd_pcm_mmap_commit(slave, slave_offset, slave_frames);
-                       snd_atomic_write_end(&plugin->watom);
                        if (result > 0 && (snd_pcm_uframes_t)result != slave_frames) {
                                snd_pcm_sframes_t res;
                                
                                res = plugin->undo_read(slave, areas, hw_offset, frames, slave_frames - result);
-                               if (res < 0)
+                               if (res < 0) {
+                                       snd_atomic_write_end(&plugin->watom);
                                        return xfer > 0 ? (snd_pcm_sframes_t)xfer : res;
+                               }
                                frames -= res;
                        }
-                       if (result <= 0)
+                       if (result <= 0) {
+                               snd_atomic_write_end(&plugin->watom);
                                return xfer > 0 ? (snd_pcm_sframes_t)xfer : result;
+                       }
+                       snd_pcm_mmap_hw_forward(pcm, frames);
+                       snd_atomic_write_end(&plugin->watom);
                        if (frames == cont)
                                hw_offset = 0;
                        else