From 6dc395e2641eb93323879e9dac7980d27a8ba878 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Wed, 6 Dec 2000 23:03:49 +0000 Subject: Fix up shutdown so that things that should be destroyed get destroyed. Among other things, this fixes the bug where IMAP stores weren't disconnected at shutdown. * mail-threads.c (update_active_views): Update for folder_browser_factory_get_control_list change to EList. * folder-browser-factory.c: Turn control_list into an EList so that we can safely remove items from it while it's being iterated (which will happen as FolderBrowsers are destroyed at shutdown while the thread code is trying to update the status bars). (control_destroy_cb): Just destroy the folder_browser. (browser_destroy_cb): New callback for FolderBrowser destroy. Remove the control from control_list here instead of control_destroy_cb, because the controls don't seem to get destroyed reliably... * component-factory.c: Clean up stuff. (factory_destroy): Get rid of this. (owner_unset_cb): Schedule an idle handler to quit. (idle_quit): Wait for all of the FolderBrowsers to be destroyed and then destroy the storages and quit. svn path=/trunk/; revision=6830 --- mail/ChangeLog | 27 ++++++++++ mail/component-factory.c | 112 ++++++++++++++---------------------------- mail/folder-browser-factory.c | 40 ++++++++++++--- mail/folder-browser-factory.h | 3 +- mail/mail-threads.c | 8 +-- 5 files changed, 101 insertions(+), 89 deletions(-) diff --git a/mail/ChangeLog b/mail/ChangeLog index 8b20759f18..929a71f83b 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,30 @@ +2000-12-06 Dan Winship + + Fix up shutdown so that things that should be destroyed get + destroyed. Among other things, this fixes the bug where IMAP + stores weren't disconnected at shutdown. + + * mail-threads.c (update_active_views): Update for + folder_browser_factory_get_control_list change to EList. + + * folder-browser-factory.c: Turn control_list into an EList so + that we can safely remove items from it while it's being iterated + (which will happen as FolderBrowsers are destroyed at shutdown + while the thread code is trying to update the status bars). + (control_destroy_cb): Just destroy the folder_browser. + (browser_destroy_cb): New callback for FolderBrowser destroy. + Remove the control from control_list here instead of + control_destroy_cb, because the controls don't seem to get + destroyed reliably... + + * component-factory.c: Clean up stuff. + (factory_destroy): Get rid of this. + (owner_unset_cb): Schedule an idle handler to quit. + (idle_quit): Wait for all of the FolderBrowsers to be destroyed + and then destroy the storages and quit. + + * mail-summary.h (create_summary_view): Fix prototype + 2000-12-06 Jeffrey Stedfast * mail-config.c (mail_config_folder_to_cachename): Use diff --git a/mail/component-factory.c b/mail/component-factory.c index 1b781aa7bc..a54f329a60 100644 --- a/mail/component-factory.c +++ b/mail/component-factory.c @@ -56,16 +56,10 @@ static void create_vfolder_storage (EvolutionShellComponent *shell_component); #define COMPONENT_FACTORY_ID "OAFIID:GNOME_Evolution_Mail_ShellComponentFactory" #define SUMMARY_FACTORY_ID "OAFIID:GNOME_Evolution_Mail_ExecutiveSummaryComponentFactory" -static BonoboGenericFactory *factory = NULL; +static BonoboGenericFactory *component_factory = NULL; static BonoboGenericFactory *summary_factory = NULL; -static gint running_objects = 0; static GHashTable *storages_hash; -static const EvolutionShellComponentFolderType folder_types[] = { - { "mail", "evolution-inbox.png" }, - { NULL, NULL } -}; - /* EvolutionShellComponent methods and signals. */ static EvolutionShellComponentResult @@ -78,7 +72,6 @@ create_view (EvolutionShellComponent *shell_component, EvolutionShellClient *shell_client; GNOME_Evolution_Shell corba_shell; BonoboControl *control; - GtkWidget *folder_browser_widget; if (g_strcasecmp (folder_type, "mail") != 0) return EVOLUTION_SHELL_COMPONENT_UNSUPPORTEDTYPE; @@ -89,12 +82,6 @@ create_view (EvolutionShellComponent *shell_component, control = folder_browser_factory_new_control (physical_uri, corba_shell); if (!control) return EVOLUTION_SHELL_COMPONENT_NOTFOUND; - - folder_browser_widget = bonobo_control_get_widget (control); - - g_assert (folder_browser_widget != NULL); - g_assert (IS_FOLDER_BROWSER (folder_browser_widget)); - *control_return = control; return EVOLUTION_SHELL_COMPONENT_OK; @@ -125,6 +112,8 @@ owner_set_cb (EvolutionShellComponent *shell_component, mail_session_init (); mail_config_init (); + storages_hash = g_hash_table_new (NULL, NULL); + create_vfolder_storage (shell_component); corba_shell = bonobo_object_corba_objref (BONOBO_OBJECT (shell_client)); @@ -143,73 +132,49 @@ owner_set_cb (EvolutionShellComponent *shell_component, mail_operation_wait_for_finish (); } -static void -owner_unset_cb (EvolutionShellComponent *shell_component, gpointer user_data) -{ - mail_operations_terminate (); - gtk_main_quit (); -} - static void free_storage (gpointer service, gpointer storage, gpointer data) { camel_service_disconnect (service, TRUE, NULL); camel_object_unref (service); - gtk_object_unref (storage); + bonobo_object_unref (storage); } -static void -factory_destroy (BonoboEmbeddable *embeddable, - BonoboObject *destroy_factory) +static gboolean +idle_quit (gpointer user_data) { - running_objects--; - if (running_objects > 0) - return; - - if (destroy_factory) - bonobo_object_unref (BONOBO_OBJECT (destroy_factory)); - else - g_warning ("Serious ref counting error"); - destroy_factory = NULL; + if (e_list_length (folder_browser_factory_get_control_list ())) + return TRUE; g_hash_table_foreach (storages_hash, free_storage, NULL); g_hash_table_destroy (storages_hash); - storages_hash = NULL; + mail_operations_terminate (); gtk_main_quit (); -} - -static BonoboObject * -summary_fn (BonoboGenericFactory *factory, void *closure) -{ - BonoboObject *summary_component_factory; - - running_objects++; - summary_component_factory = executive_summary_component_factory_new (create_summary_view, - NULL); - gtk_signal_connect (GTK_OBJECT (summary_component_factory), "destroy", - GTK_SIGNAL_FUNC (factory_destroy), summary_factory); + return FALSE; +} - return summary_component_factory; +static void +owner_unset_cb (EvolutionShellComponent *shell_component, gpointer user_data) +{ + g_idle_add_full (G_PRIORITY_LOW, idle_quit, NULL, NULL); } +static const EvolutionShellComponentFolderType folder_types[] = { + { "mail", "evolution-inbox.png" }, + { NULL, NULL } +}; + static BonoboObject * -factory_fn (BonoboGenericFactory *factory, void *closure) +component_fn (BonoboGenericFactory *factory, void *closure) { EvolutionShellComponent *shell_component; - running_objects++; + shell_component = evolution_shell_component_new ( + folder_types, create_view, create_folder, + NULL, NULL, NULL); - shell_component = evolution_shell_component_new (folder_types, - create_view, - create_folder, - NULL, - NULL, - NULL); - - gtk_signal_connect (GTK_OBJECT (shell_component), "destroy", - GTK_SIGNAL_FUNC (factory_destroy), factory); gtk_signal_connect (GTK_OBJECT (shell_component), "owner_set", GTK_SIGNAL_FUNC (owner_set_cb), NULL); gtk_signal_connect (GTK_OBJECT (shell_component), "owner_unset", @@ -218,31 +183,26 @@ factory_fn (BonoboGenericFactory *factory, void *closure) return BONOBO_OBJECT (shell_component); } +static BonoboObject * +summary_fn (BonoboGenericFactory *factory, void *closure) +{ + return executive_summary_component_factory_new (create_summary_view, + NULL); +} + void component_factory_init (void) { - if (factory != NULL) - return; - - factory = bonobo_generic_factory_new (COMPONENT_FACTORY_ID, factory_fn, NULL); - summary_factory = bonobo_generic_factory_new (SUMMARY_FACTORY_ID, summary_fn, NULL); - storages_hash = g_hash_table_new (NULL, NULL); + component_factory = bonobo_generic_factory_new (COMPONENT_FACTORY_ID, + component_fn, NULL); + summary_factory = bonobo_generic_factory_new (SUMMARY_FACTORY_ID, + summary_fn, NULL); - if (factory == NULL) { + if (component_factory == NULL || summary_factory == NULL) { e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, _("Cannot initialize Evolution's mail component.")); exit (1); } - - if (summary_factory == NULL) { - e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, - _("Cannot initialize Evolution's mail summary component.")); - } - - if (storages_hash == NULL) { - e_notice (NULL, GNOME_MESSAGE_BOX_ERROR, - _("Cannot initialize Evolution's mail storage hash.")); - } } /* FIXME: remove */ diff --git a/mail/folder-browser-factory.c b/mail/folder-browser-factory.c index 0095ded338..1846bc2ac0 100644 --- a/mail/folder-browser-factory.c +++ b/mail/folder-browser-factory.c @@ -31,7 +31,7 @@ #include "mail-session.h" /* The FolderBrowser BonoboControls we have. */ -static GList *control_list = NULL; +static EList *control_list = NULL; /* * Add with 'folder_browser' @@ -207,13 +207,30 @@ control_activate_cb (BonoboControl *control, static void control_destroy_cb (BonoboControl *control, - gpointer user_data) + GtkObject *folder_browser) { - GtkWidget *folder_browser = user_data; - - control_list = g_list_remove (control_list, control); + gtk_object_destroy (folder_browser); +} - gtk_object_destroy (GTK_OBJECT (folder_browser)); +static void +browser_destroy_cb (FolderBrowser *fb, + BonoboControl *control) +{ + EIterator *it; + + /* We do this from browser_destroy_cb rather than + * control_destroy_cb because currently, the controls + * don't seem to all get destroyed properly at quit + * time (but the widgets get destroyed by X). FIXME. + */ + + for (it = e_list_get_iterator (control_list); e_iterator_is_valid (it); e_iterator_next (it)) { + if (e_iterator_get (it) == control) { + e_iterator_delete (it); + break; + } + } + gtk_object_unref (GTK_OBJECT (it)); } BonoboControl * @@ -246,14 +263,21 @@ folder_browser_factory_new_control (const char *uri, gtk_signal_connect (GTK_OBJECT (control), "destroy", control_destroy_cb, folder_browser); + gtk_signal_connect (GTK_OBJECT (folder_browser), "destroy", + browser_destroy_cb, control); + + if (!control_list) + control_list = e_list_new (NULL, NULL, NULL); - control_list = g_list_prepend (control_list, control); + e_list_append (control_list, control); return control; } -GList * +EList * folder_browser_factory_get_control_list (void) { + if (!control_list) + control_list = e_list_new (NULL, NULL, NULL); return control_list; } diff --git a/mail/folder-browser-factory.h b/mail/folder-browser-factory.h index d2d35d38b7..f55a069ede 100644 --- a/mail/folder-browser-factory.h +++ b/mail/folder-browser-factory.h @@ -13,9 +13,10 @@ #include #include "Evolution.h" +#include "e-util/e-list.h" BonoboControl *folder_browser_factory_new_control (const char *uri, const GNOME_Evolution_Shell shell); -GList *folder_browser_factory_get_control_list (void); +EList *folder_browser_factory_get_control_list (void); #endif /* _FOLDER_BROWSER_FACTORY_H */ diff --git a/mail/mail-threads.c b/mail/mail-threads.c index 6491a936c5..4ded984dd4 100644 --- a/mail/mail-threads.c +++ b/mail/mail-threads.c @@ -1081,16 +1081,16 @@ retrieve_shell_view_interface_from_control (BonoboControl *control) static void update_active_views (void) { - GList *controls; - GList *p; + EList *controls; + EIterator *it; controls = folder_browser_factory_get_control_list (); - for (p = controls; p != NULL; p = p->next) { + for (it = e_list_get_iterator (controls); e_iterator_is_valid (it); e_iterator_next (it)) { BonoboControl *control; GNOME_Evolution_ShellView shell_view_interface; CORBA_Environment ev; - control = BONOBO_CONTROL (p->data); + control = BONOBO_CONTROL (e_iterator_get (it)); shell_view_interface = gtk_object_get_data (GTK_OBJECT (control), "mail_threads_shell_view_interface"); -- cgit