[anjuta] libanjuta: Fix bgo #638980 - Crash when closing project
- From: James Liggett <jrliggett src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [anjuta] libanjuta: Fix bgo #638980 - Crash when closing project
- Date: Fri, 14 Jan 2011 04:40:24 +0000 (UTC)
commit d9df0fbe60d9a34d0d9cbc6bbac777c22730564c
Author: James Liggett <jrliggett cox net>
Date: Thu Jan 13 20:39:02 2011 -0800
libanjuta: Fix bgo #638980 - Crash when closing project
In some cases, an AnjutaDock might be holding the last reference of its
associated command bar, which could cause it to be destroyed by AnjutaDock's
dispose handler. A crash would then happen when AnjutaDock's parent runs
dispose, because that handler will do things that would make the pane selection
handler run, which would reference the now destroyed command bar. Disconnect
selection signals in AnjutaDock's dispose to prevent these potential crashes.
libanjuta/anjuta-dock.c | 44 ++++++++++++++++++++++++++++++++++----------
1 files changed, 34 insertions(+), 10 deletions(-)
---
diff --git a/libanjuta/anjuta-dock.c b/libanjuta/anjuta-dock.c
index 174b05c..c3bf5d0 100644
--- a/libanjuta/anjuta-dock.c
+++ b/libanjuta/anjuta-dock.c
@@ -38,6 +38,7 @@
struct _AnjutaDockPriv
{
GHashTable *panes;
+ GHashTable *dock_items;
GtkWidget *command_bar;
};
@@ -49,6 +50,7 @@ anjuta_dock_init (AnjutaDock *self)
self->priv = g_new0 (AnjutaDockPriv, 1);
self->priv->panes = g_hash_table_new_full (g_str_hash, g_str_equal,
NULL, g_object_unref);
+ self->priv->dock_items = g_hash_table_new (g_str_hash, g_str_equal);
}
static void
@@ -59,12 +61,32 @@ anjuta_dock_finalize (GObject *object)
self = ANJUTA_DOCK (object);
g_hash_table_destroy (self->priv->panes);
+ g_hash_table_destroy (self->priv->dock_items);
g_free (self->priv);
G_OBJECT_CLASS (anjuta_dock_parent_class)->finalize (object);
}
static void
+on_pane_selected (GdlDockItem *item, AnjutaCommandBar *command_bar)
+{
+ const gchar *pane_name;
+
+ pane_name = (const gchar *) g_object_get_data (G_OBJECT (item),
+ "pane-name");
+ anjuta_command_bar_show_action_group (command_bar, pane_name);
+}
+
+
+static void
+disconnect_select_signals (gpointer key, GdlDockItem *value,
+ AnjutaCommandBar *command_bar)
+{
+ g_signal_handlers_disconnect_by_func (value, G_CALLBACK (on_pane_selected),
+ command_bar);
+}
+
+static void
anjuta_dock_dispose (GObject *object)
{
AnjutaDock *self;
@@ -73,6 +95,15 @@ anjuta_dock_dispose (GObject *object)
if (self->priv->command_bar)
{
+ /* Disconnect pane selection signals before dropping the command bar
+ * reference. It is possible that we may be holding the last reference
+ * of the bar, creating the possibility that the parent implementation
+ * of dispose might do something that would call the signal handler that
+ * would reference the already destroyed command bar. */
+ g_hash_table_foreach (self->priv->dock_items,
+ (GHFunc) disconnect_select_signals,
+ self->priv->command_bar);
+
g_object_unref (self->priv->command_bar);
self->priv->command_bar = NULL;
}
@@ -137,16 +168,6 @@ anjuta_dock_add_pane (AnjutaDock *self, const gchar *pane_name,
user_data, behavior);
}
-static void
-on_pane_selected (GdlDockItem *item, AnjutaCommandBar *command_bar)
-{
- const gchar *pane_name;
-
- pane_name = (const gchar *) g_object_get_data (G_OBJECT (item),
- "pane-name");
- anjuta_command_bar_show_action_group (command_bar, pane_name);
-}
-
/**
* anjuta_dock_add_pane_full:
* @self: An AnjutaDock
@@ -204,6 +225,9 @@ anjuta_dock_add_pane_full (AnjutaDock *self, const gchar *pane_name,
G_CALLBACK (on_pane_selected),
self->priv->command_bar);
+ g_hash_table_insert (self->priv->dock_items, (gchar *) pane_name,
+ dock_item);
+
/* Show the new pane's commands in the command bar */
anjuta_command_bar_show_action_group (ANJUTA_COMMAND_BAR (self->priv->command_bar),
pane_name);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]