perex 96d951
From a256766c10c52cb6667de8a65f5cbb332fad4cc7 Mon Sep 17 00:00:00 2001
perex 96d951
From: Jaroslav Kysela <perex@perex.cz>
perex 96d951
Date: Mon, 21 Dec 2009 09:09:42 +0100
perex 96d951
Subject: [PATCH] pcm: Close event timer in pcm_hw plugin
perex 96d951
perex 96d951
Dan McCombs discovered that snd_pcm_close() invocations are not leading
perex 96d951
to associated timers being closed, which results in successively more
perex 96d951
timers being created but not freed.
perex 96d951
perex 96d951
Original patch from Daniel T Chen <crimsun@ubuntu.com>.
perex 96d951
perex 96d951
BugLink: https://bugs.launchpad.net/bugs/451893
perex 96d951
perex 96d951
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
perex 96d951
---
perex 96d951
 src/pcm/pcm_hw.c |   26 ++++++++++++++------------
perex 96d951
 1 files changed, 14 insertions(+), 12 deletions(-)
perex 96d951
perex 96d951
diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c
perex 96d951
index 2095b01..b557912 100644
perex 96d951
--- a/src/pcm/pcm_hw.c
perex 96d951
+++ b/src/pcm/pcm_hw.c
perex 96d951
@@ -338,18 +338,6 @@ static int snd_pcm_hw_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t * params)
perex 96d951
 	return 0;
perex 96d951
 }
perex 96d951
 
perex 96d951
-static int snd_pcm_hw_hw_free(snd_pcm_t *pcm)
perex 96d951
-{
perex 96d951
-	snd_pcm_hw_t *hw = pcm->private_data;
perex 96d951
-	int fd = hw->fd, err;
perex 96d951
-	if (ioctl(fd, SNDRV_PCM_IOCTL_HW_FREE) < 0) {
perex 96d951
-		err = -errno;
perex 96d951
-		SYSMSG("SNDRV_PCM_IOCTL_HW_FREE failed");
perex 96d951
-		return err;
perex 96d951
-	}
perex 96d951
-	return 0;
perex 96d951
-}
perex 96d951
-
perex 96d951
 static void snd_pcm_hw_close_timer(snd_pcm_hw_t *hw)
perex 96d951
 {
perex 96d951
 	if (hw->period_timer) {
perex 96d951
@@ -421,6 +409,20 @@ static int snd_pcm_hw_change_timer(snd_pcm_t *pcm, int enable)
perex 96d951
 	} else {
perex 96d951
 		snd_pcm_hw_close_timer(hw);
perex 96d951
 		pcm->fast_ops = &snd_pcm_hw_fast_ops;
perex 96d951
+		hw->period_event = 0;
perex 96d951
+	}
perex 96d951
+	return 0;
perex 96d951
+}
perex 96d951
+
perex 96d951
+static int snd_pcm_hw_hw_free(snd_pcm_t *pcm)
perex 96d951
+{
perex 96d951
+	snd_pcm_hw_t *hw = pcm->private_data;
perex 96d951
+	int fd = hw->fd, err;
perex 96d951
+	snd_pcm_hw_change_timer(pcm, 0);
perex 96d951
+	if (ioctl(fd, SNDRV_PCM_IOCTL_HW_FREE) < 0) {
perex 96d951
+		err = -errno;
perex 96d951
+		SYSMSG("SNDRV_PCM_IOCTL_HW_FREE failed");
perex 96d951
+		return err;
perex 96d951
 	}
perex 96d951
 	return 0;
perex 96d951
 }
perex 96d951
-- 
perex 96d951
1.5.5.1
perex 96d951