changeset 22427:eab5bc54e163

Tell gstreamer not to fork; remove the SIGCHLD -> SIGALRM hack, which made Pidgin unrunnable on non-Linux platforms. This involves depending on gstreamer >= 0.10.10, which has been around since 2006-09-14. This isn't a problem, right? Fixes #1496.
author Will Thompson <will.thompson@collabora.co.uk>
date Thu, 06 Mar 2008 11:34:11 +0000
parents 5762dcb1909c
children d83adbf0c92c
files configure.ac pidgin/gtkmain.c pidgin/gtksound.c
diffstat 3 files changed, 8 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/configure.ac	Thu Mar 06 07:41:52 2008 +0000
+++ b/configure.ac	Thu Mar 06 11:34:11 2008 +0000
@@ -662,7 +662,7 @@
 	[AC_HELP_STRING([--disable-gstreamer], [compile without GStreamer audio support])],
 	enable_gst="$enableval", enable_gst="yes")
 if test "x$enable_gst" != "xno"; then
-	PKG_CHECK_MODULES(GSTREAMER, [gstreamer-0.10], [
+	PKG_CHECK_MODULES(GSTREAMER, [gstreamer-0.10 >= 0.10.10], [
 		AC_DEFINE(USE_GSTREAMER, 1, [Use GStreamer for playing sounds])
 		AC_SUBST(GSTREAMER_CFLAGS)
 		AC_SUBST(GSTREAMER_LIBS)
--- a/pidgin/gtkmain.c	Thu Mar 06 07:41:52 2008 +0000
+++ b/pidgin/gtkmain.c	Thu Mar 06 11:34:11 2008 +0000
@@ -99,7 +99,6 @@
 	SIGTERM,
 	SIGQUIT,
 	SIGCHLD,
-	SIGALRM,
 	-1
 };
 
@@ -140,38 +139,11 @@
 #ifdef HAVE_SIGNAL_H
 static void sighandler(int sig);
 
-/**
- * Reap all our dead children.  Sometimes libpurple forks off a separate
- * process to do some stuff.  When that process exits we are
- * informed about it so that we can call waitpid() and let it
- * stop being a zombie.
- *
- * We used to do this immediately when our signal handler was
- * called, but because of GStreamer we now wait one second before
- * reaping anything.  Why?  For some reason GStreamer fork()s
- * during their initialization process.  I don't understand why...
- * but they do it, and there's nothing we can do about it.
- *
- * Anyway, so then GStreamer waits for its child to die and then
- * it continues with the initialization process.  This means that
- * we have a race condition where GStreamer is waitpid()ing for its
- * child to die and we're catching the SIGCHLD signal.  If GStreamer
- * is awarded the zombied process then everything is ok.  But if libpurple
- * reaps the zombie process then the GStreamer initialization sequence
- * fails.
- *
- * So the ugly solution is to wait a second to give GStreamer time to
- * reap that bad boy.
- *
- * GStreamer 0.10.10 and newer have a gst_register_fork_set_enabled()
- * function that can be called by applications to disable forking
- * during initialization.  But it's not in 0.10.0, so we shouldn't
- * use it.
- *
- * All of this child process reaping stuff is currently only used for
- * processes that were forked to play sounds.  It's not needed for
- * forked DNS child, which have their own waitpid() call.  It might
- * be wise to move this code into gtksound.c.
+/*
+ * This child process reaping stuff is currently only used for processes that
+ * were forked to play sounds.  It's not needed for forked DNS child, which
+ * have their own waitpid() call.  It might be wise to move this code into
+ * gtksound.c.
  */
 static void
 clean_pid(void)
@@ -188,9 +160,6 @@
 		snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid);
 		perror(errmsg);
 	}
-
-	/* Restore signal catching */
-	signal(SIGALRM, sighandler);
 }
 
 char *segfault_message;
@@ -220,12 +189,8 @@
 		abort();
 		break;
 	case SIGCHLD:
-		/* Restore signal catching */
-		signal(SIGCHLD, sighandler);
-		alarm(1);
-		break;
-	case SIGALRM:
 		clean_pid();
+		signal(SIGCHLD, sighandler);    /* restore signal catching on this one! */
 		break;
 	default:
 		purple_debug_warning("sighandler", "Caught signal %d\n", sig);
--- a/pidgin/gtksound.c	Thu Mar 06 07:41:52 2008 +0000
+++ b/pidgin/gtksound.c	Thu Mar 06 11:34:11 2008 +0000
@@ -302,6 +302,7 @@
 
 #ifdef USE_GSTREAMER
 	purple_debug_info("sound", "Initializing sound output drivers.\n");
+	gst_registry_fork_set_enabled (FALSE);
 	if ((gst_init_failed = !gst_init_check(NULL, NULL, &error))) {
 		purple_notify_error(NULL, _("GStreamer Failure"),
 					_("GStreamer failed to initialize."),