From aad4202594a706636bc893b8716a573861216175 Mon Sep 17 00:00:00 2001 From: Not Zed Date: Mon, 29 Jan 2001 09:33:15 +0000 Subject: Debug function to compare the tree we think we have, after an incremental 2001-01-29 Not Zed * message-list.c (tree_equal): Debug function to compare the tree we think we have, after an incremental update. (build_tree): Check the tree after we've built it. * mail-mt.c (mail_get_password): If we are being called from the main gui thread, then just call the dialogue directly. Ideally we dont want this anyway but lets handle the case nicely. (mail_get_password): Try locking around the password request, to single-queue any password requests. (mail_msg_init): Push an exit handler to clean it up on completion. * mail-send-recv.c (receive_update_got_store): New function called when the store has been retrieved asynchronously. (mail_send_receive): Get the store asynchronously. This was causing problems where the password dialogue would try and be called from the main thread via a message. * mail-ops.c (mail_get_store): New function to get a store (a)synchronously. More or less taken from subscribe-dialog, which i will remove later. (mail_scan_subfolders): Try running the scan subfolder thing asynchronously, to help startup time. Not sure if this will work, but presumably the shell can handle the folders appearing later ok. svn path=/trunk/; revision=7886 --- mail/ChangeLog | 27 +++++++++++++++++++++ mail/mail-mt.c | 29 +++++++++++++++++++--- mail/mail-ops.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++- mail/mail-ops.h | 4 +++ mail/mail-send-recv.c | 36 ++++++++++++++------------- mail/main.c | 6 ++--- mail/message-list.c | 57 ++++++++++++++++++++++++++++++++++++++++++- 7 files changed, 201 insertions(+), 25 deletions(-) diff --git a/mail/ChangeLog b/mail/ChangeLog index de81f0a67c..3bef3dcf12 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,30 @@ +2001-01-29 Not Zed + + * message-list.c (tree_equal): Debug function to compare the tree + we think we have, after an incremental update. + (build_tree): Check the tree after we've built it. + + * mail-mt.c (mail_get_password): If we are being called from the + main gui thread, then just call the dialogue directly. Ideally we + dont want this anyway but lets handle the case nicely. + (mail_get_password): Try locking around the password request, to + single-queue any password requests. + (mail_msg_init): Push an exit handler to clean it up on completion. + + * mail-send-recv.c (receive_update_got_store): New function called + when the store has been retrieved asynchronously. + (mail_send_receive): Get the store asynchronously. This was + causing problems where the password dialogue would try and be + called from the main thread via a message. + + * mail-ops.c (mail_get_store): New function to get a store + (a)synchronously. More or less taken from subscribe-dialog, which + i will remove later. + (mail_scan_subfolders): Try running the scan subfolder thing + asynchronously, to help startup time. Not sure if this will work, + but presumably the shell can handle the folders appearing later + ok. + 2001-01-28 Jeffrey Stedfast * mail-config-druid.c (set_defaults): Turns out that I was wrong diff --git a/mail/mail-mt.c b/mail/mail-mt.c index 11cd181ce9..103ddc0de6 100644 --- a/mail/mail-mt.c +++ b/mail/mail-mt.c @@ -216,6 +216,17 @@ mail_msg_received(EThread *e, EMsg *msg, void *data) m->ops->receive_msg(m); } +void mail_msg_cleanup(void) +{ + e_thread_destroy(mail_thread_queued); + e_thread_destroy(mail_thread_new); + + e_msgport_destroy(mail_gui_port); + e_msgport_destroy(mail_gui_reply_port); + + /* FIXME: channels too, etc */ +} + void mail_msg_init(void) { mail_gui_reply_port = e_msgport_new(); @@ -238,6 +249,8 @@ void mail_msg_init(void) mail_msg_active = g_hash_table_new(NULL, NULL); mail_gui_thread = pthread_self(); + + atexit(mail_msg_cleanup); } /* ********************************************************************** */ @@ -492,9 +505,19 @@ mail_get_password(char *prompt, gboolean secret) m->prompt = prompt; m->secret = secret; - e_msgport_put(mail_gui_port, (EMsg *)m); - e_msgport_wait(pass_reply); - r = (struct _pass_msg *)e_msgport_get(pass_reply); + if (pthread_self() == mail_gui_thread) { + do_get_pass((struct _mail_msg *)m); + r = m; + } else { + static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; + + /* we want this single-threaded, this is the easiest way to do it without blocking ? */ + pthread_mutex_lock(&lock); + e_msgport_put(mail_gui_port, (EMsg *)m); + e_msgport_wait(pass_reply); + r = (struct _pass_msg *)e_msgport_get(pass_reply); + pthread_mutex_unlock(&lock); + } g_assert(r == m); diff --git a/mail/mail-ops.c b/mail/mail-ops.c index d24c47dd85..1a78c2c7af 100644 --- a/mail/mail-ops.c +++ b/mail/mail-ops.c @@ -1057,7 +1057,7 @@ void mail_scan_subfolders(CamelStore *store, EvolutionStorage *storage) int id; id = mail_get_folderinfo(store, do_scan_subfolders, storage); - mail_msg_wait(id); + /*mail_msg_wait(id);*/ } /* ** ATTACH MESSAGES ****************************************************** */ @@ -1188,6 +1188,71 @@ mail_get_folder(const char *uri, void (*done) (char *uri, CamelFolder *folder, v return id; } +/* ** GET STORE ******************************************************* */ + +struct _get_store_msg { + struct _mail_msg msg; + + char *uri; + CamelStore *store; + void (*done) (char *uri, CamelStore *store, void *data); + void *data; +}; + +static char *get_store_desc(struct _mail_msg *mm, int done) +{ + struct _get_store_msg *m = (struct _get_store_msg *)mm; + + return g_strdup_printf(_("Opening store %s"), m->uri); +} + +static void get_store_get(struct _mail_msg *mm) +{ + struct _get_store_msg *m = (struct _get_store_msg *)mm; + + m->store = camel_session_get_store(session, m->uri, &mm->ex); +} + +static void get_store_got(struct _mail_msg *mm) +{ + struct _get_store_msg *m = (struct _get_store_msg *)mm; + + if (m->done) + m->done(m->uri, m->store, m->data); +} + +static void get_store_free(struct _mail_msg *mm) +{ + struct _get_store_msg *m = (struct _get_store_msg *)mm; + + g_free(m->uri); + if (m->store) + camel_object_unref((CamelObject *)m->store); +} + +static struct _mail_msg_op get_store_op = { + get_store_desc, + get_store_get, + get_store_got, + get_store_free, +}; + +int +mail_get_store(const char *uri, void (*done) (char *uri, CamelStore *store, void *data), void *data) +{ + struct _get_store_msg *m; + int id; + + m = mail_msg_new(&get_store_op, NULL, sizeof(*m)); + m->uri = g_strdup(uri); + m->data = data; + m->done = done; + + id = m->msg.seq; + e_thread_put(mail_thread_new, (EMsg *)m); + return id; +} + /* ** CREATE FOLDER ******************************************************* */ /* trying to find a way to remove this entirely and just use get_folder() diff --git a/mail/mail-ops.h b/mail/mail-ops.h index 7b4fe0ec36..27c7dbcabf 100644 --- a/mail/mail-ops.h +++ b/mail/mail-ops.h @@ -58,6 +58,10 @@ void mail_get_messages(CamelFolder *folder, GPtrArray *uids, int mail_get_folder(const char *uri, void (*done) (char *uri, CamelFolder *folder, void *data), void *data); +/* and for a store */ +int mail_get_store(const char *uri, + void (*done) (char *uri, CamelStore *store, void *data), void *data); + /* build an attachment */ void mail_build_attachment(CamelFolder *folder, GPtrArray *uids, void (*done)(CamelFolder *folder, GPtrArray *messages, CamelMimePart *part, char *subject, void *data), void *data); diff --git a/mail/mail-send-recv.c b/mail/mail-send-recv.c index 6b375f2a1b..dce23ad56d 100644 --- a/mail/mail-send-recv.c +++ b/mail/mail-send-recv.c @@ -470,6 +470,24 @@ receive_get_folder(CamelFilterDriver *d, const char *uri, void *data, CamelExcep return folder; } +static void +receive_update_got_store(char *uri, CamelStore *store, void *data) +{ + struct _send_info *info = data; + + if (store) { + EvolutionStorage *storage = mail_lookup_storage(store); + if (storage) { + mail_update_subfolders(store, storage, receive_update_done, info); + gtk_object_unref((GtkObject *)storage); + } else { + receive_done("", info); + } + } else { + receive_done("", info); + } +} + void mail_send_receive(void) { GSList *sources; @@ -478,8 +496,6 @@ void mail_send_receive(void) struct _send_data *data; extern CamelFolder *outbox_folder; const MailConfigAccount *account; - CamelStore *store; - CamelException *ex; sources = mail_config_get_sources(); if (!sources) @@ -519,21 +535,7 @@ void mail_send_receive(void) break; case SEND_UPDATE: /* FIXME: error reporting? */ - ex = camel_exception_new(); - store = camel_session_get_store(session, info->uri, ex); - if (store) { - EvolutionStorage *storage = mail_lookup_storage(store); - if (storage) { - mail_update_subfolders(store, storage, receive_update_done, info); - gtk_object_unref((GtkObject *)storage); - } else { - receive_done("", info); - } - camel_object_unref((CamelObject *)store); - } else { - receive_done("", info); - } - camel_exception_free(ex); + mail_get_store(info->uri, receive_update_got_store, info); break; } scan = scan->next; diff --git a/mail/main.c b/mail/main.c index 2b3c08e452..7217a37ed2 100644 --- a/mail/main.c +++ b/mail/main.c @@ -31,11 +31,11 @@ #include "mail.h" #include "mail-mt.h" -#if 0 +#if 1 static int blowup(int status) { printf("memory blew up, status %d\n", status); - /*abort();*/ + abort(); return status; } #endif @@ -62,7 +62,7 @@ main (int argc, char *argv []) CORBA_ORB orb; struct sigaction sa, osa; -#if 0 +#if 1 /* used to make elfence work */ #if 0 free (malloc (10)); diff --git a/mail/message-list.c b/mail/message-list.c index 44d82c63f7..69ca413314 100644 --- a/mail/message-list.c +++ b/mail/message-list.c @@ -1460,6 +1460,8 @@ static void build_subtree (MessageList *ml, ETreePath *parent, CamelFolderThread static void build_subtree_diff (MessageList *ml, ETreePath *parent, ETreePath *path, CamelFolderThreadNode *c, int *row, GHashTable *expanded_nodes); +static int tree_equal(ETreeModel *etm, ETreePath *ap, CamelFolderThreadNode *bp); + static void build_tree (MessageList *ml, CamelFolderThread *thread, CamelFolderChangeInfo *changes) { @@ -1489,7 +1491,7 @@ build_tree (MessageList *ml, CamelFolderThread *thread, CamelFolderChangeInfo *c e_tree_model_node_set_expanded(etm, ml->tree_root, TRUE); } -#define BROKEN_ETREE /* avoid some broken code in etree(?) by not using the incremental update */ +/*#define BROKEN_ETREE*/ /* avoid some broken code in etree(?) by not using the incremental update */ top = e_tree_model_node_get_first_child(etm, ml->tree_root); #ifndef BROKEN_ETREE @@ -1502,6 +1504,8 @@ build_tree (MessageList *ml, CamelFolderThread *thread, CamelFolderChangeInfo *c #ifndef BROKEN_ETREE } else { build_subtree_diff(ml, ml->tree_root, top, thread->tree, &row, expanded_nodes); + top = e_tree_model_node_get_first_child(etm, ml->tree_root); + tree_equal(ml->table_model, top, thread->tree); } #endif free_tree_state(expanded_nodes); @@ -1601,6 +1605,57 @@ node_equal(ETreeModel *etm, ETreePath *ap, CamelFolderThreadNode *bp) return 0; } +/* debug function - compare the two trees to see if they are the same */ +static int +tree_equal(ETreeModel *etm, ETreePath *ap, CamelFolderThreadNode *bp) +{ + char *uid; + + while (ap && bp) { + if (!node_equal(etm, ap, bp)) { + g_warning("Nodes in tree differ"); + uid = e_tree_model_node_get_data(etm, ap); + if (id_is_uid(uid)) + printf("table uid = %s\n", id_uid(uid)); + else + printf("table subject = %s\n", id_subject(uid)); + if (bp->message) + printf("camel uid = %s\n", camel_message_info_uid(bp->message)); + else + printf("camel subject = %s\n", bp->root_subject); + return FALSE; + } else { + if (!tree_equal(etm, e_tree_model_node_get_first_child(etm, ap), bp->child)) + return FALSE; + } + bp = bp->next; + ap = e_tree_model_node_get_next(etm, ap); + } + + if (ap || bp) { + g_warning("Tree differs, out of nodes in one branch"); + if (ap) { + uid = e_tree_model_node_get_data(etm, ap); + if (uid) { + if (id_is_uid(uid)) + printf("table uid = %s\n", id_uid(uid)); + else + printf("table subject = %s\n", id_subject(uid)); + } else + printf("uid is empty?\n"); + } + if (bp) { + if (bp->message) + printf("camel uid = %s\n", camel_message_info_uid(bp->message)); + else + printf("camel subject = %s\n", bp->root_subject); + return FALSE; + } + return FALSE; + } + return TRUE; +} + /* adds a single node, retains save state, and handles adding children if required */ static void add_node_diff(MessageList *ml, ETreePath *parent, ETreePath *path, CamelFolderThreadNode *c, int *row, int myrow, GHashTable *expanded_nodes) -- cgit v1.2.3