aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/ChangeLog27
-rw-r--r--mail/mail-mt.c29
-rw-r--r--mail/mail-ops.c67
-rw-r--r--mail/mail-ops.h4
-rw-r--r--mail/mail-send-recv.c36
-rw-r--r--mail/main.c6
-rw-r--r--mail/message-list.c57
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 <NotZed@Ximian.com>
+
+ * 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 <fejj@ximian.com>
* 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)