ALSA: snd-usb-caiaq: Missing lock around use of buffer positions
authorMark Hills <mark@pogo.org.uk>
Sat, 24 Oct 2009 11:59:35 +0000 (12:59 +0100)
committerTakashi Iwai <tiwai@suse.de>
Fri, 30 Oct 2009 11:29:16 +0000 (12:29 +0100)
Fix a race which causes snd_pcm_update_hw_ptr_pos() to report a bug.

Signed-off-by: Mark Hills <mark@pogo.org.uk>
Acked-by: Daniel Mack <daniel@caiaq.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/usb/caiaq/audio.c

index 121af0644fd9bc901fbbc62cb676738e9049e0c7..e76017cd5acf1bee8f5d1195864df68a1144e15b 100644 (file)
@@ -269,16 +269,22 @@ snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub)
 {
        int index = sub->number;
        struct snd_usb_caiaqdev *dev = snd_pcm_substream_chip(sub);
+       snd_pcm_uframes_t ptr;
+
+       spin_lock(&dev->spinlock);
 
        if (dev->input_panic || dev->output_panic)
-               return SNDRV_PCM_POS_XRUN;
+               ptr = SNDRV_PCM_POS_XRUN;
 
        if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               return bytes_to_frames(sub->runtime,
+               ptr = bytes_to_frames(sub->runtime,
                                        dev->audio_out_buf_pos[index]);
        else
-               return bytes_to_frames(sub->runtime,
+               ptr = bytes_to_frames(sub->runtime,
                                        dev->audio_in_buf_pos[index]);
+
+       spin_unlock(&dev->spinlock);
+       return ptr;
 }
 
 /* operators for both playback and capture */