Blob Blame History Raw
From a256766c10c52cb6667de8a65f5cbb332fad4cc7 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Mon, 21 Dec 2009 09:09:42 +0100
Subject: [PATCH] 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>
---
 src/pcm/pcm_hw.c |   26 ++++++++++++++------------
 1 files changed, 14 insertions(+), 12 deletions(-)

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;
 }
-- 
1.5.5.1