aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
author5 <NotZed@Ximian.com>2001-09-26 06:18:52 +0800
committerMichael Zucci <zucchi@src.gnome.org>2001-09-26 06:18:52 +0800
commitba5b1b6be7d3beed85c1f6b51d5808f9a7d72b5f (patch)
tree1cb7ee7b3057358d5540e7ebd08bc0382d7e3c8a
parentc76e6322cf850d3e7a909ae1353bdde8b2911cac (diff)
downloadgsoc2013-evolution-ba5b1b6be7d3beed85c1f6b51d5808f9a7d72b5f.tar.gz
gsoc2013-evolution-ba5b1b6be7d3beed85c1f6b51d5808f9a7d72b5f.tar.zst
gsoc2013-evolution-ba5b1b6be7d3beed85c1f6b51d5808f9a7d72b5f.zip
Deal with destroy vs finalise semantics. Only destroy widgets here.
2001-09-25 <NotZed@Ximian.com> * folder-browser.c (folder_browser_destroy): Deal with destroy vs finalise semantics. Only destroy widgets here. (folder_browser_finalise): object finalise function, actually unref/free all other objects here. (folder_browser_class_init): Init the finalise hook. (got_folder): Check if message_list == NULL -> we've been destroyed before the thread got a chance to finish loading the folder. (folder_browser_is_drafts): Dont use a g_return_if_fail to return in what could be a valid state of the object. (folder_browser_is_sent): Likewise. (folder_browser_copy): Do nothing if message_list == NULL. * main.c (main): call mail_msg_cleanup() before leaving threads. * component-factory.c (owner_unset_cb): Wait for all outstanding operations to finish before setting up to quit. (idle_quit): Wait for all outstanding ops to finish before cleanup. (unref_standard_folders): NULL out the standard folder before unreffing it. * mail-mt.c (mail_msg_wait_all): New function to wait for all outstanding thread operations. (mail_msg_cleanup): Destroy the io channels before we're finished. Also wait for all outstanding threads first. Made public. (mail_msg_init): Dont call mail_msg_cleanup atexit automatically. svn path=/trunk/; revision=13129
-rw-r--r--mail/ChangeLog32
-rw-r--r--mail/component-factory.c12
-rw-r--r--mail/folder-browser.c67
-rw-r--r--mail/mail-mt.c35
-rw-r--r--mail/mail-mt.h1
-rw-r--r--mail/main.c3
6 files changed, 127 insertions, 23 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 0a9670b38f..8f869194bb 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,35 @@
+2001-09-25 <NotZed@Ximian.com>
+
+ * folder-browser.c (folder_browser_destroy): Deal with destroy vs
+ finalise semantics. Only destroy widgets here.
+ (folder_browser_finalise): object finalise function, actually
+ unref/free all other objects here.
+ (folder_browser_class_init): Init the finalise hook.
+ (got_folder): Check if message_list == NULL -> we've been
+ destroyed before the thread got a chance to finish loading the
+ folder.
+ (folder_browser_is_drafts): Dont use a g_return_if_fail to return
+ in what could be a valid state of the object.
+ (folder_browser_is_sent): Likewise.
+ (folder_browser_copy): Do nothing if message_list == NULL.
+
+ * main.c (main): call mail_msg_cleanup() before leaving threads.
+
+ * component-factory.c (owner_unset_cb): Wait for all outstanding
+ operations to finish before setting up to quit.
+ (idle_quit): Wait for all outstanding ops to finish before
+ cleanup.
+ (unref_standard_folders): NULL out the standard folder before
+ unreffing it.
+
+ * mail-mt.c (mail_msg_wait_all): New function to wait for all
+ outstanding thread operations.
+ (mail_msg_cleanup): Destroy the io channels before we're
+ finished. Also wait for all outstanding threads first. Made
+ public.
+ (mail_msg_init): Dont call mail_msg_cleanup atexit automatically.
+
+
2001-09-25 Jeffrey Stedfast <fejj@ximian.com>
* mail-format.c (get_data_wrapper_text): If the data wrapper
diff --git a/mail/component-factory.c b/mail/component-factory.c
index cddf142891..5019702e3a 100644
--- a/mail/component-factory.c
+++ b/mail/component-factory.c
@@ -603,8 +603,12 @@ unref_standard_folders (void)
int i;
for (i = 0; i < sizeof (standard_folders) / sizeof (standard_folders[0]); i++) {
- if (standard_folders[i].folder)
- camel_object_unref (CAMEL_OBJECT (*standard_folders[i].folder));
+ if (standard_folders[i].folder) {
+ CamelFolder *folder = *standard_folders[i].folder;
+
+ *standard_folders[i].folder = NULL;
+ camel_object_unref (CAMEL_OBJECT (folder));
+ }
}
}
@@ -712,6 +716,8 @@ free_storage (gpointer service, gpointer storage, gpointer data)
static gboolean
idle_quit (gpointer user_data)
{
+ mail_msg_wait_all();
+
if (e_list_length (folder_browser_factory_get_control_list ()))
return TRUE;
@@ -730,6 +736,8 @@ owner_unset_cb (EvolutionShellComponent *shell_component, gpointer user_data)
if (mail_config_get_empty_trash_on_exit ())
empty_trash (NULL, NULL, NULL);
+
+ mail_msg_wait_all();
unref_standard_folders ();
mail_importer_uninit ();
diff --git a/mail/folder-browser.c b/mail/folder-browser.c
index f577d46e88..492a17b900 100644
--- a/mail/folder-browser.c
+++ b/mail/folder-browser.c
@@ -109,13 +109,13 @@ enum {
static guint folder_browser_signals [LAST_SIGNAL] = {0, };
static void
-folder_browser_destroy (GtkObject *object)
+folder_browser_finalise (GtkObject *object)
{
FolderBrowser *folder_browser;
CORBA_Environment ev;
-
- folder_browser = FOLDER_BROWSER (object);
-
+
+ folder_browser = FOLDER_BROWSER(object);
+
CORBA_exception_init (&ev);
if (folder_browser->search_full)
@@ -124,17 +124,22 @@ folder_browser_destroy (GtkObject *object)
if (folder_browser->sensitize_timeout_id)
g_source_remove (folder_browser->sensitize_timeout_id);
- if (folder_browser->shell != CORBA_OBJECT_NIL)
+ if (folder_browser->shell != CORBA_OBJECT_NIL) {
CORBA_Object_release (folder_browser->shell, &ev);
+ folder_browser->shell = CORBA_OBJECT_NIL;
+ }
- if (folder_browser->shell_view != CORBA_OBJECT_NIL)
+ if (folder_browser->shell_view != CORBA_OBJECT_NIL) {
CORBA_Object_release(folder_browser->shell_view, &ev);
+ folder_browser->shell_view = CORBA_OBJECT_NIL;
+ }
if (folder_browser->uicomp)
bonobo_object_unref (BONOBO_OBJECT (folder_browser->uicomp));
g_free (folder_browser->uri);
-
+ folder_browser->uri = NULL;
+
if (folder_browser->folder) {
camel_object_unhook_event(CAMEL_OBJECT(folder_browser->folder), "folder_changed",
folder_changed, folder_browser);
@@ -142,14 +147,9 @@ folder_browser_destroy (GtkObject *object)
folder_changed, folder_browser);
mail_sync_folder (folder_browser->folder, NULL, NULL);
camel_object_unref (CAMEL_OBJECT (folder_browser->folder));
+ folder_browser->folder = NULL;
}
- if (folder_browser->message_list)
- gtk_widget_destroy (GTK_WIDGET (folder_browser->message_list));
-
- if (folder_browser->mail_display)
- gtk_widget_destroy (GTK_WIDGET (folder_browser->mail_display));
-
CORBA_exception_free (&ev);
if (folder_browser->view_collection) {
@@ -163,9 +163,31 @@ folder_browser_destroy (GtkObject *object)
}
gtk_object_unref (GTK_OBJECT (folder_browser->invisible));
+ folder_browser->invisible = NULL;
+
if (folder_browser->clipboard_selection)
g_byte_array_free (folder_browser->clipboard_selection, TRUE);
+
+ folder_browser_parent_class->finalize(object);
+}
+
+static void
+folder_browser_destroy (GtkObject *object)
+{
+ FolderBrowser *folder_browser;
+
+ folder_browser = FOLDER_BROWSER (object);
+
+ if (folder_browser->message_list) {
+ gtk_widget_destroy (GTK_WIDGET (folder_browser->message_list));
+ folder_browser->message_list = NULL;
+ }
+ if (folder_browser->mail_display) {
+ gtk_widget_destroy (GTK_WIDGET (folder_browser->mail_display));
+ folder_browser->mail_display = NULL;
+ }
+
folder_browser_parent_class->destroy (object);
}
@@ -173,6 +195,7 @@ static void
folder_browser_class_init (GtkObjectClass *object_class)
{
object_class->destroy = folder_browser_destroy;
+ object_class->finalize = folder_browser_finalise;
folder_browser_parent_class = gtk_type_class (PARENT_TYPE);
@@ -630,6 +653,9 @@ folder_browser_copy (GtkWidget *menuitem, FolderBrowser *fb)
gboolean cut;
int i;
+ if (fb->message_list == NULL)
+ return;
+
cut = menuitem == NULL;
if (!GTK_WIDGET_HAS_FOCUS (fb->message_list)) {
@@ -748,6 +774,9 @@ got_folder(char *uri, CamelFolder *folder, void *data)
FolderBrowser *fb = data;
d(printf ("got folder '%s' = %p\n", uri, folder));
+
+ if (fb->message_list == NULL)
+ goto done;
fb->folder = folder;
if (folder == NULL)
@@ -824,7 +853,10 @@ folder_browser_is_drafts (FolderBrowser *fb)
const GSList *accounts;
MailConfigAccount *account;
- g_return_val_if_fail (IS_FOLDER_BROWSER (fb) && fb->uri, FALSE);
+ g_return_val_if_fail (IS_FOLDER_BROWSER (fb), FALSE);
+
+ if (fb->uri == NULL)
+ return FALSE;
if (fb->folder == drafts_folder)
return TRUE;
@@ -854,8 +886,11 @@ folder_browser_is_sent (FolderBrowser *fb)
const GSList *accounts;
MailConfigAccount *account;
- g_return_val_if_fail (IS_FOLDER_BROWSER (fb) && fb->uri, FALSE);
-
+ g_return_val_if_fail (IS_FOLDER_BROWSER (fb), FALSE);
+
+ if (fb->uri == NULL)
+ return FALSE;
+
if (fb->folder == sent_folder)
return TRUE;
diff --git a/mail/mail-mt.c b/mail/mail-mt.c
index 69646e44fd..2ce8f6cab4 100644
--- a/mail/mail-mt.c
+++ b/mail/mail-mt.c
@@ -260,6 +260,28 @@ void mail_msg_wait(unsigned int msgid)
}
}
+void mail_msg_wait_all(void)
+{
+ struct _mail_msg *m;
+ int ismain = pthread_self() == mail_gui_thread;
+
+ if (ismain) {
+ MAIL_MT_LOCK(mail_msg_lock);
+ while (g_hash_table_size(mail_msg_active) > 0) {
+ MAIL_MT_UNLOCK(mail_msg_lock);
+ gtk_main_iteration();
+ MAIL_MT_LOCK(mail_msg_lock);
+ }
+ MAIL_MT_UNLOCK(mail_msg_lock);
+ } else {
+ MAIL_MT_LOCK(mail_msg_lock);
+ while (g_hash_table_size(mail_msg_active) > 0) {
+ pthread_cond_wait(&mail_msg_cond, &mail_msg_lock);
+ }
+ MAIL_MT_UNLOCK(mail_msg_lock);
+ }
+}
+
EMsgPort *mail_gui_port;
static GIOChannel *mail_gui_channel;
EMsgPort *mail_gui_reply_port;
@@ -366,16 +388,19 @@ mail_msg_received(EThread *e, EMsg *msg, void *data)
}
}
-static void mail_msg_cleanup(void)
+void mail_msg_cleanup(void)
{
+ mail_msg_wait_all();
+
e_thread_destroy(mail_thread_queued_slow);
e_thread_destroy(mail_thread_queued);
e_thread_destroy(mail_thread_new);
+ g_io_channel_unref(mail_gui_channel);
+ g_io_channel_unref(mail_gui_reply_channel);
+
e_msgport_destroy(mail_gui_port);
e_msgport_destroy(mail_gui_reply_port);
-
- /* FIXME: channels too, etc */
}
void mail_msg_init(void)
@@ -406,8 +431,6 @@ void mail_msg_init(void)
mail_msg_active = g_hash_table_new(NULL, NULL);
mail_gui_thread = pthread_self();
-
- atexit(mail_msg_cleanup);
}
/* ********************************************************************** */
@@ -450,6 +473,8 @@ pass_got (char *string, void *data)
service = mca->transport;
}
+ mail_config_service_set_save_passwd (service, remember);
+
if (mca) {
mail_config_service_set_save_passwd (service, remember);
diff --git a/mail/mail-mt.h b/mail/mail-mt.h
index 8f90c3b0c7..c8717d33ac 100644
--- a/mail/mail-mt.h
+++ b/mail/mail-mt.h
@@ -56,6 +56,7 @@ void mail_msg_free(void *msg);
void mail_msg_check_error(void *msg);
void mail_msg_cancel(unsigned int msgid);
void mail_msg_wait(unsigned int msgid);
+void mail_msg_wait_all(void);
/* request a string/password */
char *mail_get_password (CamelService *service, const char *prompt,
diff --git a/mail/main.c b/mail/main.c
index 41a9482167..dc2042f19b 100644
--- a/mail/main.c
+++ b/mail/main.c
@@ -139,6 +139,9 @@ main (int argc, char *argv [])
GDK_THREADS_ENTER ();
bonobo_main ();
+
+ mail_msg_cleanup();
+
GDK_THREADS_LEAVE ();
mail_config_write_on_exit ();