diff options
-rw-r--r-- | shell/ChangeLog | 10 | ||||
-rw-r--r-- | shell/e-shell.c | 23 | ||||
-rw-r--r-- | shell/e-shell.h | 1 | ||||
-rw-r--r-- | shell/main.c | 23 |
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) |