aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--shell/ChangeLog10
-rw-r--r--shell/e-shell.c23
-rw-r--r--shell/e-shell.h1
-rw-r--r--shell/main.c23
4 files changed, 53 insertions, 4 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog
index eadbc94421..fc8579b7b4 100644
--- a/shell/ChangeLog
+++ b/shell/ChangeLog
@@ -1,5 +1,15 @@
2001-10-12 Ettore Perazzoli <ettore@ximian.com>
+ [Hopefully really fix #8615 and friends.]
+
+ * main.c (no_views_left_cb): Invoke `e_shell_disconnect_db()'
+ before unreffing the shell.
+
+ * e-shell.c (e_shell_disconnect_db): New.
+ (destroy): Call it instead of unreffing the db manually here.
+
+2001-10-12 Ettore Perazzoli <ettore@ximian.com>
+
* e-shell-folder-commands.c
(folder_selection_dialog_folder_selected_callback): Don't free the
folder_command_data here. It is supposed to be freed in the async
diff --git a/shell/e-shell.c b/shell/e-shell.c
index 65a469bcf2..1f8628c2fe 100644
--- a/shell/e-shell.c
+++ b/shell/e-shell.c
@@ -766,10 +766,7 @@ destroy (GtkObject *object)
shell = E_SHELL (object);
priv = shell->priv;
- if (shell->priv->db != CORBA_OBJECT_NIL) {
- bonobo_object_release_unref (shell->priv->db, NULL);
- shell->priv->db = CORBA_OBJECT_NIL;
- }
+ e_shell_disconnect_db (shell);
if (priv->iid != NULL)
oaf_active_server_unregister (priv->iid, bonobo_object_corba_objref (BONOBO_OBJECT (shell)));
@@ -1678,6 +1675,8 @@ e_shell_get_user_creatable_items_handler (EShell *shell)
}
+/* FIXME: These are ugly hacks, they really should not be needed. */
+
void
e_shell_unregister_all (EShell *shell)
{
@@ -1693,6 +1692,22 @@ e_shell_unregister_all (EShell *shell)
priv->component_registry = NULL;
}
+void
+e_shell_disconnect_db (EShell *shell)
+{
+ EShellPrivate *priv;
+
+ g_return_if_fail (E_IS_SHELL (shell));
+
+ priv = shell->priv;
+
+ if (priv->db == CORBA_OBJECT_NIL)
+ return;
+
+ bonobo_object_release_unref (priv->db, NULL);
+ priv->db = CORBA_OBJECT_NIL;
+}
+
const char *
e_shell_construct_result_to_string (EShellConstructResult result)
diff --git a/shell/e-shell.h b/shell/e-shell.h
index 3e09b3f072..4c17930b43 100644
--- a/shell/e-shell.h
+++ b/shell/e-shell.h
@@ -116,6 +116,7 @@ gboolean e_shell_restore_from_settings (EShell *shell);
void e_shell_destroy_all_views (EShell *shell);
void e_shell_unregister_all (EShell *shell);
+void e_shell_disconnect_db (EShell *shell);
void e_shell_component_maybe_crashed (EShell *shell,
const char *uri,
diff --git a/shell/main.c b/shell/main.c
index 2308862d4d..401a89d269 100644
--- a/shell/main.c
+++ b/shell/main.c
@@ -127,6 +127,29 @@ no_views_left_cb (EShell *shell, gpointer data)
e_shell_unregister_all (shell);
+ /* FIXME: And this is another ugly hack. We have a strange race
+ condition that I cannot work around. What happens is that the
+ EShell object gets unreffed and its aggregate EActivityHandler gets
+ destroyed too. But for some reason, the EActivityHanlder GtkObject
+ gets freed, while its CORBA object counterpart is still an active
+ server. So there is a slight chance that we receive CORBA
+ invocation that act on an uninitialized object, and we crash. (See
+ #8615.)
+
+ The CORBA invocation on the dead object only happens because we
+ ::unref the BonoboConf database server in the ::destroy method of
+ the shell. Since this is a CORBA call, it allows incoming CORBA
+ calls to happen -- and these get invoked on the partially
+ uninitialized object.
+
+ Since I am not 100% sure what the reason for this half-stale object
+ is, I am just going to make sure that no CORBA ops happen in
+ ::destroy... And this is achieved by placing this call here. (If
+ the DB is disconnected, there will be no ::unref of it in
+ ::destroy.) */
+
+ e_shell_disconnect_db (shell);
+
bonobo_object_unref (BONOBO_OBJECT (shell));
if (quit_box != NULL)