Fixed+foolproofed some GTK+ reentrancy/recursion segfaults.
authorshort <>
Sun, 23 May 2004 21:25:36 +0000 (21:25 +0000)
committershort <>
Sun, 23 May 2004 21:25:36 +0000 (21:25 +0000)
src/ui-gnome.c

index b1ce30d..4c0c8ef 100644 (file)
@@ -89,6 +89,9 @@ static gboolean last_daemon_running,last_daemon_running_set=FALSE;
 
 static gboolean daemon_check_timeout_func(gpointer data /* unused */)
 {
+       if (!App)       /* Quitting? */
+               return FALSE;   /* stop running */
+
        state_start_stop();
        return TRUE;    /* continue running */
 }
@@ -97,6 +100,9 @@ static gboolean external_startup_check_timeout_func(gpointer data /* unused */)
 {
 gboolean state_startup_is_on;
 
+       if (!App)       /* Quitting? */
+               return FALSE;   /* stop running */
+
        if (startup_query(&state_startup_is_on))
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(AutostartCheckButton),state_startup_is_on);
        return TRUE;    /* continue running */
@@ -115,13 +121,26 @@ void on_PortButtonRandom_clicked(GtkButton *button,gpointer user_data)
 
 void on_AutostartCheckButton_toggled(GtkToggleButton *togglebutton,gpointer user_data)
 {
+static gint inside=0;
+
        g_return_if_fail(GTK_IS_TOGGLE_BUTTON(togglebutton));
 
+       /* Avoid reentrancy to prevent segfault during failed registration.
+        * FIXME: Who knows why? Some forbidden GTK recursion occurs.
+        */
+       g_assert(inside>=0);
+       if (inside)
+               return;
+       inside++;
+
        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(AutostartCheckButton)))
                startup_on();
        else
                startup_off();
        external_startup_check_timeout_func(NULL);      /* data; unused */
+
+       g_assert(inside==1);
+       inside--;
 }
 
 void on_ButtonStart_clicked(GtkButton *button,gpointer user_data)
@@ -151,10 +170,14 @@ void on_ButtonHide_clicked(GtkButton *button,gpointer user_data)
         * as 'App' widget will quit our gtk_main() automatically.
         */
        gtk_widget_destroy(GTK_WIDGET(App));
+       App=NULL;
 }
 
 static void ui_gnome_network_notify_hostip(guint32 hostip_guint32)
 {
+       if (!App)       /* Quitting? */
+               return;
+
        if (!hostip_guint32) {
 pid_t daemon_pid;
 
@@ -176,6 +199,9 @@ static void ui_gnome_g_log_handler(const gchar *log_domain,GLogLevelFlags log_le
 {
 GtkWidget *dialog;
 
+       if (!App)       /* Quitting? */
+               return;
+
        /**/ if (log_level & G_LOG_LEVEL_ERROR)
                dialog=gnome_app_error(App,message);
        else if (log_level & (G_LOG_LEVEL_CRITICAL|G_LOG_LEVEL_WARNING))