# HG changeset patch # User Stu Tomlinson # Date 1210187188 0 # Node ID 56a38b60576e924bc7fed35c544609b237634350 # Parent 485689a88b61e3459bef4ec33145db81237ba07c 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. diff -r 485689a88b61 -r 56a38b60576e pidgin/gtksound.c --- 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;