aboutsummaryrefslogtreecommitdiff
blob: e7229cb9e0af7353d4dc11078294f06c8104cde3 (plain)
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
60
commit a256766c10c52cb6667de8a65f5cbb332fad4cc7
Author: Jaroslav Kysela <perex@perex.cz>
Date:   Mon Dec 21 09:09:42 2009 +0100

    pcm: Close event timer in pcm_hw plugin
    
    Dan McCombs discovered that snd_pcm_close() invocations are not leading
    to associated timers being closed, which results in successively more
    timers being created but not freed.
    
    Original patch from Daniel T Chen <crimsun@ubuntu.com>.
    
    BugLink: https://bugs.launchpad.net/bugs/451893
    
    Signed-off-by: Jaroslav Kysela <perex@perex.cz>

diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
index 2095b01..b557912 100644
--- a/src/pcm/pcm_hw.c
+++ b/src/pcm/pcm_hw.c
@@ -338,18 +338,6 @@ static int snd_pcm_hw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
 	return 0;
 }
 
-static int snd_pcm_hw_hw_free(snd_pcm_t *pcm)
-{
-	snd_pcm_hw_t *hw = pcm->private_data;
-	int fd = hw->fd, err;
-	if (ioctl(fd, SNDRV_PCM_IOCTL_HW_FREE) < 0) {
-		err = -errno;
-		SYSMSG("SNDRV_PCM_IOCTL_HW_FREE failed");
-		return err;
-	}
-	return 0;
-}
-
 static void snd_pcm_hw_close_timer(snd_pcm_hw_t *hw)
 {
 	if (hw->period_timer) {
@@ -421,6 +409,20 @@ static int snd_pcm_hw_change_timer(snd_pcm_t *pcm, int enable)
 	} else {
 		snd_pcm_hw_close_timer(hw);
 		pcm->fast_ops = &snd_pcm_hw_fast_ops;
+		hw->period_event = 0;
+	}
+	return 0;
+}
+
+static int snd_pcm_hw_hw_free(snd_pcm_t *pcm)
+{
+	snd_pcm_hw_t *hw = pcm->private_data;
+	int fd = hw->fd, err;
+	snd_pcm_hw_change_timer(pcm, 0);
+	if (ioctl(fd, SNDRV_PCM_IOCTL_HW_FREE) < 0) {
+		err = -errno;
+		SYSMSG("SNDRV_PCM_IOCTL_HW_FREE failed");
+		return err;
 	}
 	return 0;
 }