changeset 22836:56a38b60576e

Kill off sound playing child processes if they are still around after 15 seconds, as they will be if we are piling up children due to blocking on the audio device. This prevents a barrage of sounds when the device becomes available.
author Stu Tomlinson <stu@nosnilmot.com>
date Wed, 07 May 2008 19:06:28 +0000
parents 485689a88b61
children 7d4fcb142572
files pidgin/gtksound.c
diffstat 1 files changed, 38 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/pidgin/gtksound.c	Wed May 07 18:10:43 2008 +0000
+++ b/pidgin/gtksound.c	Wed May 07 19:06:28 2008 +0000
@@ -384,6 +384,26 @@
 }
 #endif
 
+#ifndef _WIN32
+static gboolean
+expire_old_child(gpointer data)
+{
+	pid_t pid = GPOINTER_TO_INT(data);
+
+	if (waitpid(pid, NULL, WNOHANG | WUNTRACED) < 0) {
+		if (errno == ECHILD)
+			return FALSE;
+		else
+			purple_debug_warning("gtksound", "Child is ill, pid: %d (%s)\n", pid, strerror(errno));
+	}
+
+	if (kill(pid, SIGKILL) < 0)
+		purple_debug_error("gtksound", "Killing process %d failed (%s)\n", pid, strerror(errno));
+
+	return FALSE;
+}
+#endif
+
 static void
 pidgin_sound_play_file(const char *filename)
 {
@@ -418,7 +438,9 @@
 		const char *sound_cmd;
 		char *command;
 		char *esc_filename;
+		char **argv = NULL;
 		GError *error = NULL;
+		GPid pid;
 
 		sound_cmd = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/sound/command");
 
@@ -436,11 +458,25 @@
 		else
 			command = g_strdup_printf("%s %s", sound_cmd, esc_filename);
 
-		if(!g_spawn_command_line_async(command, &error)) {
-			purple_debug_error("gtksound", "sound command could not be launched: %s\n", error->message);
+		if (!g_shell_parse_argv(command, NULL, &argv, &error)) {
+			purple_debug_error("gtksound", "error parsing command %s (%s)\n",
+							   command, error->message);
 			g_error_free(error);
+			g_free(esc_filename);
+			g_free(command);
+			return;
 		}
 
+		if (!g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
+						  NULL, NULL, &pid, &error)) {
+			purple_debug_error("gtksound", "sound command could not be launched: %s\n",
+							   error->message);
+			g_error_free(error);
+		} else {
+			purple_timeout_add_seconds(15, expire_old_child, GINT_TO_POINTER(pid));
+		}
+
+		g_strfreev(argv);
 		g_free(esc_filename);
 		g_free(command);
 		return;