aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog22
-rw-r--r--embed/downloader-view.c4
-rw-r--r--embed/mozilla/mozilla-embed-find.cpp5
-rw-r--r--embed/mozilla/mozilla-embed-persist.cpp7
-rw-r--r--embed/mozilla/mozilla-embed.cpp10
-rw-r--r--lib/Makefile.am2
-rw-r--r--lib/ephy-object-helpers.c38
-rw-r--r--lib/ephy-object-helpers.h32
-rw-r--r--src/ephy-extensions-manager.c11
-rw-r--r--src/ephy-main.c10
-rw-r--r--src/ephy-shell.c4
-rw-r--r--src/ephy-window.c3
12 files changed, 126 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index 6dd85bf65..8afc9e9f6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2005-06-10 Christian Persch <chpe@cvs.gnome.org>
+
+ * lib/Makefile.am:
+ * lib/ephy-object-helpers.c:
+ * lib/ephy-object-helpers.h:
+
+ Common helper function to unref a GObject from idle.
+
+ * embed/downloader-view.c: (downloader_view_finalize):
+ * embed/mozilla/mozilla-embed-find.cpp:
+ * embed/mozilla/mozilla-embed-persist.cpp:
+ * embed/mozilla/mozilla-embed.cpp:
+ * src/ephy-extensions-manager.c: (unload_extension):
+ * src/ephy-main.c: (main):
+ * src/ephy-shell.c: (toolwindow_hide_cb):
+ * src/ephy-window.c: (ephy_window_finalize):
+
+ Always unref the shell from idle, never directly. That's because
+ in case we hold the last reference, we would end up terminating
+ embedding/XPCOM from a mozilla callback. Fixes bug #151037,
+ and moz#236688.
+
2005-06-08 Christian Persch <chpe@cvs.gnome.org>
* src/ephy-window.c:
diff --git a/embed/downloader-view.c b/embed/downloader-view.c
index 4b518a39a..7499264ed 100644
--- a/embed/downloader-view.c
+++ b/embed/downloader-view.c
@@ -23,6 +23,7 @@
#include "downloader-view.h"
#include "ephy-file-helpers.h"
+#include "ephy-object-helpers.h"
#include "ephy-embed-shell.h"
#include "ephy-stock-icons.h"
#include "ephy-gui.h"
@@ -229,9 +230,10 @@ downloader_view_finalize (GObject *object)
g_object_unref (dv->priv->status_icon);
g_hash_table_destroy (dv->priv->downloads_hash);
- g_object_unref (embed_shell);
G_OBJECT_CLASS (parent_class)->finalize (object);
+
+ ephy_object_idle_unref (embed_shell);
}
DownloaderView *
diff --git a/embed/mozilla/mozilla-embed-find.cpp b/embed/mozilla/mozilla-embed-find.cpp
index d589630b5..92e755e2b 100644
--- a/embed/mozilla/mozilla-embed-find.cpp
+++ b/embed/mozilla/mozilla-embed-find.cpp
@@ -28,6 +28,8 @@
#include "mozilla-embed-find.h"
#include "ephy-embed-find.h"
#include "ephy-embed-shell.h"
+#include "ephy-object-helpers.h"
+#include "ephy-debug.h"
#define MOZILLA_EMBED_FIND_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), MOZILLA_TYPE_EMBED_FIND, MozillaEmbedFindPrivate))
@@ -103,6 +105,7 @@ mozilla_embed_find_constructor (GType type, guint n_construct_properties,
GObjectConstructParam *construct_params)
{
g_object_ref (embed_shell);
+
/* we depend on single because of mozilla initialization */
ephy_embed_shell_get_embed_single (embed_shell);
@@ -119,7 +122,7 @@ mozilla_embed_find_finalize (GObject *object)
parent_class->finalize (object);
- g_object_unref (embed_shell);
+ ephy_object_idle_unref (embed_shell);
}
static void
diff --git a/embed/mozilla/mozilla-embed-persist.cpp b/embed/mozilla/mozilla-embed-persist.cpp
index c10d677ae..b84fdfe59 100644
--- a/embed/mozilla/mozilla-embed-persist.cpp
+++ b/embed/mozilla/mozilla-embed-persist.cpp
@@ -26,6 +26,7 @@
#include "mozilla-embed.h"
#include "ephy-embed-shell.h"
#include "ephy-file-helpers.h"
+#include "ephy-object-helpers.h"
#include "EphyBrowser.h"
#include "EphyHeaderSniffer.h"
#include "MozDownload.h"
@@ -102,6 +103,8 @@ mozilla_embed_persist_finalize (GObject *object)
persist->priv->mPersist = nsnull;
G_OBJECT_CLASS (parent_class)->finalize (object);
+
+ ephy_object_idle_unref (embed_shell);
}
void
@@ -339,7 +342,9 @@ static GObject *
mozilla_embed_persist_constructor (GType type, guint n_construct_properties,
GObjectConstructParam *construct_params)
{
- /* we depend on single because of mozilla initialization */
+ g_object_ref (embed_shell);
+
+ /* this will ensure that mozilla is started up */
ephy_embed_shell_get_embed_single (embed_shell);
return parent_class->constructor (type, n_construct_properties,
diff --git a/embed/mozilla/mozilla-embed.cpp b/embed/mozilla/mozilla-embed.cpp
index 8a9d3aadc..1b7733e0d 100644
--- a/embed/mozilla/mozilla-embed.cpp
+++ b/embed/mozilla/mozilla-embed.cpp
@@ -29,6 +29,7 @@
#include "ephy-embed-shell.h"
#include "ephy-command-manager.h"
#include "ephy-string.h"
+#include "ephy-object-helpers.h"
#include "ephy-debug.h"
#include "EphyBrowser.h"
@@ -201,6 +202,8 @@ static GObject *
mozilla_embed_constructor (GType type, guint n_construct_properties,
GObjectConstructParam *construct_params)
{
+ g_object_ref (embed_shell);
+
/* we depend on single because of mozilla initialization */
ephy_embed_shell_get_embed_single (embed_shell);
@@ -289,6 +292,8 @@ mozilla_embed_finalize (GObject *object)
}
G_OBJECT_CLASS (parent_class)->finalize (object);
+
+ ephy_object_idle_unref (embed_shell);
}
static void
@@ -1127,6 +1132,8 @@ _mozilla_embed_new_xul_dialog (void)
{
GtkWidget *window, *embed;
+ g_object_ref (embed_shell);
+
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
embed = gtk_moz_embed_new ();
gtk_widget_show (embed);
@@ -1148,5 +1155,8 @@ _mozilla_embed_new_xul_dialog (void)
G_CALLBACK (xul_title_cb),
window, (GConnectFlags) 0);
+ g_object_weak_ref (G_OBJECT (window),
+ (GWeakNotify) ephy_object_idle_unref, embed_shell);
+
return GTK_MOZ_EMBED (embed);
}
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 6254b9aa0..79f4fb016 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -19,6 +19,7 @@ NOINST_H_FILES = \
ephy-module.h \
ephy-node-filter.h \
ephy-node-common.h \
+ ephy-object-helpers.h \
ephy-prefs.h \
ephy-shlib-loader.h \
ephy-signal-accumulator.h \
@@ -54,6 +55,7 @@ libephymisc_la_SOURCES = \
ephy-node-filter.c \
ephy-node-common.h \
ephy-node-db.c \
+ ephy-object-helpers.c \
ephy-prefs.h \
ephy-shlib-loader.c \
ephy-signal-accumulator.c \
diff --git a/lib/ephy-object-helpers.c b/lib/ephy-object-helpers.c
new file mode 100644
index 000000000..6ef398c89
--- /dev/null
+++ b/lib/ephy-object-helpers.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2005 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#include "config.h"
+
+#include "ephy-object-helpers.h"
+
+static gboolean
+idle_unref (gpointer object)
+{
+ g_object_unref (object);
+
+ /* don't run again */
+ return FALSE;
+}
+
+void
+ephy_object_idle_unref (gpointer object)
+{
+ g_idle_add ((GSourceFunc) idle_unref, object);
+}
diff --git a/lib/ephy-object-helpers.h b/lib/ephy-object-helpers.h
new file mode 100644
index 000000000..4624c390b
--- /dev/null
+++ b/lib/ephy-object-helpers.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2005 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#ifndef EPHY_OBJECT_HELPERS_H
+#define EPHY_OBJECT_HELPERS_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+void ephy_object_idle_unref (gpointer object);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ephy-extensions-manager.c b/src/ephy-extensions-manager.c
index 055178a56..a140ad34d 100644
--- a/src/ephy-extensions-manager.c
+++ b/src/ephy-extensions-manager.c
@@ -31,6 +31,7 @@
#include "ephy-shell.h"
#include "eel-gconf-extensions.h"
#include "ephy-file-helpers.h"
+#include "ephy-object-helpers.h"
#include "ephy-debug.h"
#include <libxml/tree.h>
@@ -891,14 +892,6 @@ detach_window (EphyWindow *window,
ephy_extension_detach_window (extension, window);
}
-static gboolean
-idle_unref (GObject *object)
-{
- g_object_unref (object);
-
- return FALSE;
-}
-
static void
unload_extension (EphyExtensionsManager *manager,
ExtensionInfo *info)
@@ -925,7 +918,7 @@ unload_extension (EphyExtensionsManager *manager,
* extension has its own functions queued in the idle loop, the
* functions must exist in memory before being called.
*/
- g_idle_add ((GSourceFunc) idle_unref, info->extension);
+ ephy_object_idle_unref (info->extension);
}
ephy_loader_release_object (info->loader, G_OBJECT (info->extension));
diff --git a/src/ephy-main.c b/src/ephy-main.c
index 4305d8175..d60d15a52 100644
--- a/src/ephy-main.c
+++ b/src/ephy-main.c
@@ -22,6 +22,7 @@
#include "ephy-shell.h"
#include "ephy-file-helpers.h"
+#include "ephy-object-helpers.h"
#include "ephy-state.h"
#include "ephy-debug.h"
#include "ephy-stock-icons.h"
@@ -135,13 +136,6 @@ shell_weak_notify (gpointer data,
gtk_main_quit ();
}
-static gboolean
-idle_unref (GObject *object)
-{
- g_object_unref (object);
- return FALSE;
-}
-
/* Copied from libnautilus/nautilus-program-choosing.c; Needed in case
* we have no DESKTOP_STARTUP_ID (with its accompanying timestamp).
*/
@@ -308,7 +302,7 @@ main (int argc, char *argv[])
else if (new_instance && ephy_shell)
{
g_object_weak_ref (G_OBJECT (ephy_shell), shell_weak_notify, NULL);
- g_idle_add ((GSourceFunc) idle_unref, ephy_shell);
+ ephy_object_idle_unref (ephy_shell);
gtk_main ();
}
diff --git a/src/ephy-shell.c b/src/ephy-shell.c
index ab555f905..4b9bd1993 100644
--- a/src/ephy-shell.c
+++ b/src/ephy-shell.c
@@ -47,6 +47,7 @@
#include "print-dialog.h"
#include "ephy-prefs.h"
#include "ephy-gui.h"
+#include "ephy-object-helpers.h"
#ifdef ENABLE_DBUS
#include "ephy-dbus.h"
@@ -940,7 +941,8 @@ toolwindow_hide_cb (GtkWidget *widget, EphyShell *es)
session = EPHY_SESSION (ephy_shell_get_session (es));
ephy_session_remove_window (ephy_shell->priv->session, GTK_WINDOW (widget));
- g_object_unref (ephy_shell);
+
+ ephy_object_idle_unref (ephy_shell);
}
GtkWidget *
diff --git a/src/ephy-window.c b/src/ephy-window.c
index 4404d90ec..1d6b22996 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -56,6 +56,7 @@
#include "ephy-fullscreen-popup.h"
#include "ephy-action-helper.h"
#include "ephy-find-toolbar.h"
+#include "ephy-object-helpers.h"
#include <string.h>
#include <glib/gi18n.h>
@@ -2852,7 +2853,7 @@ ephy_window_finalize (GObject *object)
LOG ("Ephy Window finalized %p", object);
- g_object_unref (ephy_shell);
+ ephy_object_idle_unref (ephy_shell);
}
/**