Kill off sound playing child processes if they are still around after 15

Wed, 07 May 2008 19:06:28 +0000

author
Stu Tomlinson <nosnilmot@pidgin.im>
date
Wed, 07 May 2008 19:06:28 +0000
changeset 23027
5df4eac489e2
parent 23026
361e8a25262b
child 23028
b17c77748d6d

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.

pidgin/gtksound.c file | annotate | diff | comparison | revisions
--- 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;

mercurial