From: <the...@us...> - 2006-09-09 10:39:11
|
Revision: 17199 http://svn.sourceforge.net/gaim/?rev=17199&view=rev Author: thekingant Date: 2006-09-09 03:39:06 -0700 (Sat, 09 Sep 2006) Log Message: ----------- This should fix the bug where GStreamer would sometimes fail to initialize correctly. See the insanely long comment I added to the code if you want an explanation. I'm open to suggestions for a better way to fix this. Modified Paths: -------------- trunk/gtk/gtkmain.c Modified: trunk/gtk/gtkmain.c =================================================================== --- trunk/gtk/gtkmain.c 2006-09-09 07:06:44 UTC (rev 17198) +++ trunk/gtk/gtkmain.c 2006-09-09 10:39:06 UTC (rev 17199) @@ -89,6 +89,8 @@ #endif #ifdef HAVE_SIGNAL_H +static guint clean_pid_timeout = 0; + /* * Lists of signals we wish to catch and those we wish to ignore. * Each list terminated with -1 @@ -143,12 +145,44 @@ } #ifdef HAVE_SIGNAL_H -static void -clean_pid(void) +static void sighandler(int sig); + +/** + * Reap all our dead children. Sometimes Gaim 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 Gaim + * 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. + */ +static gboolean +clean_pid(gpointer data) { int status; pid_t pid; + clean_pid_timeout = 0; + do { pid = waitpid(-1, &status, WNOHANG); } while (pid != 0 && pid != (pid_t)-1); @@ -158,6 +192,12 @@ snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid); perror(errmsg); } + + /* Restore signal catching */ + signal(SIGCHLD, sighandler); + + /* This timer should not be called again by glib */ + return FALSE; } char *segfault_message; @@ -175,8 +215,9 @@ abort(); break; case SIGCHLD: - clean_pid(); - signal(SIGCHLD, sighandler); /* restore signal catching on this one! */ + if (clean_pid_timeout > 0) + gaim_timeout_remove(clean_pid_timeout); + clean_pid_timeout = gaim_timeout_add(1000, clean_pid, NULL); break; default: gaim_debug_warning("sighandler", "Caught signal %d\n", sig); @@ -761,6 +802,8 @@ gtk_main(); #ifdef HAVE_SIGNAL_H + if (clean_pid_timeout > 0) + gaim_timeout_remove(clean_pid_timeout); g_free(segfault_message); #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sea...@us...> - 2006-09-11 21:07:37
|
Revision: 17254 http://svn.sourceforge.net/gaim/?rev=17254&view=rev Author: seanegan Date: 2006-09-11 14:07:32 -0700 (Mon, 11 Sep 2006) Log Message: ----------- The Glib timeout was causing reentrency issues, so I reimplemented it with alarm() Modified Paths: -------------- trunk/gtk/gtkmain.c Modified: trunk/gtk/gtkmain.c =================================================================== --- trunk/gtk/gtkmain.c 2006-09-11 18:34:36 UTC (rev 17253) +++ trunk/gtk/gtkmain.c 2006-09-11 21:07:32 UTC (rev 17254) @@ -89,7 +89,6 @@ #endif #ifdef HAVE_SIGNAL_H -static guint clean_pid_timeout = 0; /* * Lists of signals we wish to catch and those we wish to ignore. @@ -102,6 +101,7 @@ SIGTERM, SIGQUIT, SIGCHLD, + SIGALRM, -1 }; @@ -175,14 +175,12 @@ * during initialization. But it's not in 0.10.0, so we shouldn't * use it. */ -static gboolean -clean_pid(gpointer data) +static void +clean_pid() { int status; pid_t pid; - clean_pid_timeout = 0; - do { pid = waitpid(-1, &status, WNOHANG); } while (pid != 0 && pid != (pid_t)-1); @@ -194,10 +192,7 @@ } /* Restore signal catching */ - signal(SIGCHLD, sighandler); - - /* This timer should not be called again by glib */ - return FALSE; + signal(SIGALRM, sighandler); } char *segfault_message; @@ -215,10 +210,13 @@ abort(); break; case SIGCHLD: - if (clean_pid_timeout > 0) - gaim_timeout_remove(clean_pid_timeout); - clean_pid_timeout = gaim_timeout_add(1000, clean_pid, NULL); + /* Restore signal catching */ + signal(SIGCHLD, sighandler); + alarm(1); break; + case SIGALRM: + clean_pid(); + break; default: gaim_debug_warning("sighandler", "Caught signal %d\n", sig); gaim_connections_disconnect_all(); @@ -802,8 +800,6 @@ gtk_main(); #ifdef HAVE_SIGNAL_H - if (clean_pid_timeout > 0) - gaim_timeout_remove(clean_pid_timeout); g_free(segfault_message); #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <the...@us...> - 2006-11-07 07:21:39
|
Revision: 17695 http://svn.sourceforge.net/gaim/?rev=17695&view=rev Author: thekingant Date: 2006-11-06 23:21:27 -0800 (Mon, 06 Nov 2006) Log Message: ----------- Get rid of an assertion failure when quiting Gaim when hidden. The docklet needs to be uninit before the blist Modified Paths: -------------- trunk/gtk/gtkmain.c Modified: trunk/gtk/gtkmain.c =================================================================== --- trunk/gtk/gtkmain.c 2006-11-07 07:13:34 UTC (rev 17694) +++ trunk/gtk/gtkmain.c 2006-11-07 07:21:27 UTC (rev 17695) @@ -310,8 +310,8 @@ /* Uninit */ gaim_gtk_conversations_uninit(); gaim_gtk_status_uninit(); + gaim_gtk_docklet_uninit(); gaim_gtk_blist_uninit(); - gaim_gtk_docklet_uninit(); gaim_gtk_connection_uninit(); gaim_gtk_account_uninit(); gaim_gtk_xfers_uninit(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |