From f4f3ede9d32822a9398992e1e80bfb18a3eae635 Mon Sep 17 00:00:00 2001 From: Not Zed Date: Thu, 4 Jan 2001 07:34:26 +0000 Subject: Removed old implementation. 2001-01-04 Not Zed * mail-ops.c (mail_do_send_mail): Removed old implementation. * folder-browser.c (do_message_selected): If we haven't got a real uid, then clear the display instead. * message-list.c (message_list_drag_data_get): Use new save message function, and also wait for it to finish before continuing. (folder_changed): (message_changed): Use mail_proxy_event instead of mail_do_forward. (mail_regen_list): New iplementation to replace the old. : remove from headers. Dont define timeit by default. (main_folder_changed): (message_list_set_folder): (message_list_set_threaded): (message_list_set_search): (message_list_hide_add): (message_list_hide_uids): (message_list_hide_clear): Use mail_regen_list instead of mail_do_regenerate_messagelist. (mail_do_regenerate_messagelist): Removed the old stuff. No functionality changed yet, just using different thread stuff. * mail-callbacks.c (save_msg_ok): Use new save message function. * component-factory.c (create_view): (add_storage): Use mail_scan_subfolders to build the folder info. (create_folder): Use new implementation with our own callback. (owner_set_cb): Changed b ack to use mail_get_folder, but now wait for it to finish. This will let any gui still run, but also gives us the required synchronous operation. (got_folder): Callback for when the folder has been opened. * mail-ops.c (mail_get_folderinfo): New function to just get the folder info in another thread. (mail_scan_subfolders): New scan subfolder implementation that uses mail_get_folderinfo. (mail_do_scan_subfolders): Removed old implementation. (mail_create_folder): Nerw implementation to create a folder, only. (mail_do_create_folder): Removed old implementation. (mail_save_messages): New implementation, fixes a couple of minor problems, and now provides a return so it can be waited on. Also check that the writes worked, etc. (mail_do_save_messages): Remove previous implementation. (mail_do_flag_messages): Removed, nothing uses it. (mail_do_flag_messages): Removed, nothing uses it anymore. (mail_get_folder): REturn the operation id, so callers can wait for it. (sync_folder_desc): (expunge_folder_desc): Add describe functions so we know what its doing. (mail_send_mail): More generic implementation of sending mail. * mail-mt.c (mail_msg_new): Lock around seq increment. And insert each new message into a hash table of active messages. (mail_msg_init): Init the active message table. (mail_msg_free): Remove the message from the active message table. (mail_msg_wait): New function, waits for a message to be processed, by id. (mail_msg_check_error): Dont display the error if it is a user-cancelled operation. (mail_proxy_event): new implementation of mail_op_forward_event. Only real difference is it uses the new thread stuff, and you can wait for it to finish if you want. (mail_proxy_event): If we're already in the main thread, just call the function. svn path=/trunk/; revision=7246 --- mail/mail-mt.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 105 insertions(+), 7 deletions(-) (limited to 'mail/mail-mt.c') diff --git a/mail/mail-mt.c b/mail/mail-mt.c index 3441228ea4..b12bd2b2de 100644 --- a/mail/mail-mt.c +++ b/mail/mail-mt.c @@ -20,18 +20,32 @@ static void set_view_data(const char *current_message, int busy); -static unsigned int mail_msg_seq; +#define MAIL_MT_LOCK(x) pthread_mutex_lock(&x) +#define MAIL_MT_UNLOCK(x) pthread_mutex_unlock(&x) + +static unsigned int mail_msg_seq; /* sequence number of each message */ +static GHashTable *mail_msg_active; /* table of active messages, must hold mail_msg_lock to access */ +static pthread_mutex_t mail_msg_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t mail_msg_cond = PTHREAD_COND_INITIALIZER; + +static pthread_t mail_gui_thread; /* so we can tell when we're in the main thread, or not */ void *mail_msg_new(mail_msg_op_t *ops, EMsgPort *reply_port, size_t size) { struct _mail_msg *msg; - + + MAIL_MT_LOCK(mail_msg_lock); + msg = g_malloc0(size); msg->ops = ops; msg->seq = mail_msg_seq++; msg->msg.reply_port = reply_port; camel_exception_init(&msg->ex); + g_hash_table_insert(mail_msg_active, (void *)msg->seq, msg); + + MAIL_MT_UNLOCK(mail_msg_lock); + return msg; } @@ -41,6 +55,14 @@ void mail_msg_free(void *msg) if (m->ops->destroy_msg) m->ops->destroy_msg(m); + + MAIL_MT_LOCK(mail_msg_lock); + + g_hash_table_remove(mail_msg_active, (void *)m->seq); + pthread_cond_broadcast(&mail_msg_cond); + + MAIL_MT_UNLOCK(mail_msg_lock); + camel_exception_clear(&m->ex); g_free(m); } @@ -52,7 +74,8 @@ void mail_msg_check_error(void *msg) char *text; GnomeDialog *gd; - if (!camel_exception_is_set(&m->ex)) + if (!camel_exception_is_set(&m->ex) + || m->ex.id == CAMEL_EXCEPTION_USER_CANCEL) return; if (m->ops->describe_msg) @@ -68,6 +91,34 @@ void mail_msg_check_error(void *msg) g_free(text); } +/* waits for a message to be finished processing (freed) + the messageid is from struct _mail_msg->seq */ +void mail_msg_wait(unsigned int msgid) +{ + struct _mail_msg *m; + int ismain = pthread_self() == mail_gui_thread; + + if (ismain) { + MAIL_MT_LOCK(mail_msg_lock); + m = g_hash_table_lookup(mail_msg_active, (void *)msgid); + while (m) { + MAIL_MT_UNLOCK(mail_msg_lock); + gtk_main_iteration(); + MAIL_MT_LOCK(mail_msg_lock); + m = g_hash_table_lookup(mail_msg_active, (void *)msgid); + } + MAIL_MT_UNLOCK(mail_msg_lock); + } else { + MAIL_MT_LOCK(mail_msg_lock); + m = g_hash_table_lookup(mail_msg_active, (void *)msgid); + while (m) { + pthread_cond_wait(&mail_msg_cond, &mail_msg_lock); + m = g_hash_table_lookup(mail_msg_active, (void *)msgid); + } + MAIL_MT_UNLOCK(mail_msg_lock); + } +} + EMsgPort *mail_gui_port; static GIOChannel *mail_gui_channel; EMsgPort *mail_gui_reply_port; @@ -168,6 +219,9 @@ void mail_msg_init(void) e_thread_set_msg_destroy(mail_thread_new, mail_msg_destroy, 0); e_thread_set_msg_received(mail_thread_new, mail_msg_received, 0); e_thread_set_reply_port(mail_thread_new, mail_gui_reply_port); + + mail_msg_active = g_hash_table_new(NULL, NULL); + mail_gui_thread = pthread_self(); } /* ********************************************************************** */ @@ -181,9 +235,6 @@ struct _set_msg { static pthread_mutex_t status_lock = PTHREAD_MUTEX_INITIALIZER; #define STATUS_BUSY_PENDING (2) -#define MAIL_MT_LOCK(x) pthread_mutex_lock(&x) -#define MAIL_MT_UNLOCK(x) pthread_mutex_unlock(&x) - /* blah blah */ #define STATUS_DELAY (5) @@ -194,7 +245,7 @@ static int status_shown; static char *status_message_next; static int status_message_clear; static int status_timeout_id; -static int status_busy; +/*static int status_busy;*/ struct _status_msg { struct _mail_msg msg; @@ -439,7 +490,54 @@ mail_get_password(char *prompt, gboolean secret) return ret; } +/* ******************** */ +struct _proxy_msg { + struct _mail_msg msg; + CamelObjectEventHookFunc func; + CamelObject *o; + void *event_data; + void *data; +}; + +static void +do_proxy_event(struct _mail_msg *mm) +{ + struct _proxy_msg *m = (struct _proxy_msg *)mm; + + m->func(m->o, m->event_data, m->data); +} + +struct _mail_msg_op proxy_event_op = { + NULL, + do_proxy_event, + NULL, + NULL, +}; + +int mail_proxy_event(CamelObjectEventHookFunc func, CamelObject *o, void *event_data, void *data) +{ + struct _proxy_msg *m; + int id; + int ismain = pthread_self() == mail_gui_thread; + + if (ismain) { + func(o, event_data, data); + /* id of -1 is 'always finished' */ + return -1; + } else { + /* we dont have a reply port for this, we dont care when/if it gets executed, just queue it */ + m = mail_msg_new(&proxy_event_op, NULL, sizeof(*m)); + m->func = func; + m->o = o; + m->event_data = event_data; + m->data = data; + + id = m->msg.seq; + e_msgport_put(mail_gui_port, (EMsg *)m); + return id; + } +} /* ******************** */ -- cgit v1.2.3