diff options
-rw-r--r-- | mail/ChangeLog | 78 | ||||
-rw-r--r-- | mail/folder-browser.c | 12 | ||||
-rw-r--r-- | mail/mail-callbacks.c | 96 | ||||
-rw-r--r-- | mail/mail-ops.c | 98 | ||||
-rw-r--r-- | mail/mail-tools.c | 7 | ||||
-rw-r--r-- | mail/mail-view.c | 7 | ||||
-rw-r--r-- | mail/message-list.c | 150 | ||||
-rw-r--r-- | mail/message-list.h | 12 |
8 files changed, 315 insertions, 145 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog index df5e22876a..193d276e05 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,7 @@ +2000-12-24 Not Zed <NotZed@HelixCode.com> + + * Merge from camel-mt-branch. + 2000-12-23 Christopher James Lahey <clahey@helixcode.com> * message-list.c (filter_date): Changed this to do different @@ -46,6 +50,80 @@ * mail-ops.c (do_view_messages): Only update display every 2 seconds. +2000-12-23 Not Zed <NotZed@HelixCode.com> + + * message-list.h (MessageList): Add a specific hide data lock. + + * message-list.c (message_list_drag_data_get): Do not use + cursor_uid, but get all currentlys elected messages directly off + the message-list. + (message_list_destroy): Removed mail_tool_camel_lock stuff. + (on_click): " + (message_list_hide_add, message_list_hide_uids, hide_load_state, + hide_save_state, message_list_hide_clear): ", but use a specfic + lock for the hide data. + (do_regenerate_messagelist): remove mail_tool_camel_lock stuff, + add hide_lock where required. + (message_list_init): Setup the hide_lock. + (message_list_destroy): Free the hide_lock. + +2000-12-22 Not Zed <NotZed@HelixCode.com> + + * mail-ops.c (mail_do_sync_folder): Run sync in different thread + each time. Just a quick litlte hack to check multithreading. + There are now few operations that single-queue. Need to work out + a way to make the allocation of threads & resources easier, so we + dont get overwhelmed with threads, but we dont block when we dont + have to, either. + + * message-list.c (main_folder_changed): If we have only changed + events, then process them directly. + (mail_do_regenerate_messagelist): Run regenerate in a new thread + each time, another quick hack to check mutlithreading. + + * mail-view.c (view_delete_msg): Call camel folder set message + flags directly. mail_do_set_message_flags() is now completely + unused. + + * folder-browser.c (mark_msg_seen): Call camel folder + set_message_flags directly. + + * mail-callbacks.c (flag_messages): New function, that just sets + flags of all selected messages, without all that messy thread + stuff (setting flags is in-memory). + (mark_as_seen): Use flag_messages(). + (mark_as_unseen): " + (undelete_msg): " + (delete_msg): " + +2000-12-20 Not Zed <NotZed@HelixCode.com> + + * message-list.c (message_list_select): Free messageinfo lookups. + (message_list_drag_data_get): " + (subtree_unread): " + (subtree_size): " + (subtree_earliest): " + (ml_tree_value_at): " Also, keep the message info around in a + static variable, and ref'd, so that any internal references we + have to it dont vanish while we're not looking. This has a couple + of problems ... esp since we never unref the last access, although + camel-folder-summary wont check this when its unref'd, so we're + 'safe'. + (save_node_state): free messageinfo lookups. + (on_click): " + (get_message_info): deconstify return. + + * mail-tools.c (mail_tool_move_folder_contents): Free messageinfo + lookups. + + * mail-ops.c (do_filter_ondemand): Free messageinfo lookups. + (do_flag_messages): " + (do_fetch_mail): Remove mail_tool_lock stuff. + (mail_operation_run): Quick hack to run an operation + asynchrounously, in a brand-new thread. + + * folder-browser.c (on_right_click): Free messageinfo lookups. + 2000-12-16 Not Zed <NotZed@HelixCode.com> * message-list.c (build_tree): Always use the slow (full-update) diff --git a/mail/folder-browser.c b/mail/folder-browser.c index 829848650c..5a94c91ba9 100644 --- a/mail/folder-browser.c +++ b/mail/folder-browser.c @@ -555,7 +555,7 @@ static gint on_right_click (ETable *table, gint row, gint col, GdkEvent *event, FolderBrowser *fb) { extern CamelFolder *drafts_folder; - const CamelMessageInfo *info; + CamelMessageInfo *info; GPtrArray *uids; int enable_mask = 0; int last_item, i; @@ -668,6 +668,8 @@ on_right_click (ETable *table, gint row, gint col, GdkEvent *event, FolderBrowse else have_undeleted = TRUE; + camel_folder_free_message_info(fb->folder, info); + if (have_seen && have_unseen && have_deleted && have_undeleted) break; } @@ -852,15 +854,11 @@ static gint mark_msg_seen (gpointer data) { MessageList *ml = data; - GPtrArray *uids; if (!ml->cursor_uid) return FALSE; - - uids = g_ptr_array_new (); - g_ptr_array_add (uids, g_strdup (ml->cursor_uid)); - mail_do_flag_messages (ml->folder, uids, FALSE, - CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN); + + camel_folder_set_message_flags(ml->folder, ml->cursor_uid, CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN); return FALSE; } diff --git a/mail/mail-callbacks.c b/mail/mail-callbacks.c index 5307eb976f..32104dba76 100644 --- a/mail/mail-callbacks.c +++ b/mail/mail-callbacks.c @@ -620,36 +620,40 @@ invert_selection (BonoboUIComponent *uih, void *user_data, const char *path) e_table_invert_selection (ml->table); } -void -mark_as_seen (BonoboUIComponent *uih, void *user_data, const char *path) +/* flag all selected messages */ +static void +flag_messages(FolderBrowser *fb, guint32 mask, guint32 set) { - FolderBrowser *fb = FOLDER_BROWSER(user_data); MessageList *ml = fb->message_list; GPtrArray *uids; - + int i; + if (ml->folder == NULL) return; - + + /* could just use specific callback but i'm lazy */ uids = g_ptr_array_new (); message_list_foreach (ml, enumerate_msg, uids); - mail_do_flag_messages (ml->folder, uids, FALSE, - CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN); + camel_folder_freeze(ml->folder); + for (i=0;i<uids->len;i++) { + camel_folder_set_message_flags(ml->folder, uids->pdata[i], mask, set); + g_free(uids->pdata[i]); + } + camel_folder_thaw(ml->folder); + + g_ptr_array_free(uids, TRUE); +} + +void +mark_as_seen (BonoboUIComponent *uih, void *user_data, const char *path) +{ + flag_messages(FOLDER_BROWSER(user_data), CAMEL_MESSAGE_SEEN, CAMEL_MESSAGE_SEEN); } void mark_as_unseen (BonoboUIComponent *uih, void *user_data, const char *path) { - FolderBrowser *fb = FOLDER_BROWSER(user_data); - MessageList *ml = fb->message_list; - GPtrArray *uids; - - if (ml->folder == NULL) - return; - - uids = g_ptr_array_new (); - message_list_foreach (ml, enumerate_msg, uids); - mail_do_flag_messages (ml->folder, uids, FALSE, - CAMEL_MESSAGE_SEEN, 0); + flag_messages(FOLDER_BROWSER(user_data), CAMEL_MESSAGE_SEEN, 0); } void @@ -764,65 +768,13 @@ save_msg (GtkWidget *widget, gpointer user_data) void delete_msg (GtkWidget *button, gpointer user_data) { - FolderBrowser *fb = user_data; - MessageList *ml = fb->message_list; - GPtrArray *uids; - - uids = g_ptr_array_new (); - message_list_foreach (ml, enumerate_msg, uids); - - /* - * Toggling a flag is an "instantaneous" operation, so if - * we're only doing one, just do it and return, rather than - * queueing it for the other thread. This makes the "Delete" - * key work correctly (move to the next message) again. - * - Dan - */ - if (uids->len == 1) { - char *uid = uids->pdata[0]; - - mail_tool_camel_lock_up (); - camel_folder_set_message_flags (ml->folder, uid, - CAMEL_MESSAGE_DELETED, - CAMEL_MESSAGE_DELETED); - mail_tool_camel_lock_down (); - } else { - mail_do_flag_messages (ml->folder, uids, FALSE, - CAMEL_MESSAGE_DELETED, - CAMEL_MESSAGE_DELETED); - } + flag_messages(FOLDER_BROWSER(user_data), CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_DELETED); } void undelete_msg (GtkWidget *button, gpointer user_data) { - FolderBrowser *fb = user_data; - MessageList *ml = fb->message_list; - GPtrArray *uids; - - uids = g_ptr_array_new (); - message_list_foreach (ml, enumerate_msg, uids); - - /* - * Toggling a flag is an "instantaneous" operation, so if - * we're only doing one, just do it and return, rather than - * queueing it for the other thread. This makes the "Delete" - * key work correctly (move to the next message) again. - * - Dan - */ - if (uids->len == 1) { - char *uid = uids->pdata[0]; - - mail_tool_camel_lock_up (); - camel_folder_set_message_flags (ml->folder, uid, - CAMEL_MESSAGE_DELETED, - 0); - mail_tool_camel_lock_down (); - } else { - mail_do_flag_messages (ml->folder, uids, FALSE, - CAMEL_MESSAGE_DELETED, - 0); - } + flag_messages(FOLDER_BROWSER(user_data), CAMEL_MESSAGE_DELETED, 0); } void diff --git a/mail/mail-ops.c b/mail/mail-ops.c index 5e0e4a56e7..bea8e335f2 100644 --- a/mail/mail-ops.c +++ b/mail/mail-ops.c @@ -37,6 +37,9 @@ #include "folder-browser.h" #include "e-util/e-html-utils.h" +/* temporary 'hack' */ +int mail_operation_run(const mail_operation_spec *op, void *in, int free); + /* ** FETCH MAIL ********************************************************** */ typedef struct fetch_mail_input_s @@ -244,9 +247,6 @@ do_fetch_mail (gpointer in_data, gpointer op_data, CamelException *ex) filter_driver_set_logfile (filter, logfile); filter_driver_set_status_func (filter, mail_op_report_status, NULL); - /* why on earth we 'up' a lock to get it, ... */ - mail_tool_camel_lock_up (); - camel_folder_freeze (input->destination); if (!strncmp (input->source_url, "mbox:", 5)) { @@ -315,8 +315,6 @@ do_fetch_mail (gpointer in_data, gpointer op_data, CamelException *ex) camel_folder_thaw (input->destination); - mail_tool_camel_lock_down (); - /*camel_object_unref (CAMEL_OBJECT (input->destination));*/ gtk_object_unref (GTK_OBJECT (filter)); } @@ -458,10 +456,12 @@ do_filter_ondemand (gpointer in_data, gpointer op_data, CamelException *ex) CamelMessageInfo *info; message = camel_folder_get_message (input->source, input->uids->pdata[i], ex); - info = (CamelMessageInfo *) camel_folder_get_message_info (input->source, input->uids->pdata[i]); + info = camel_folder_get_message_info (input->source, input->uids->pdata[i]); /* filter the message - use "incoming" rules since we don't want special "demand" filters? */ filter_driver_filter_message (driver, message, info, "", FILTER_SOURCE_INCOMING, ex); + + camel_folder_free_message_info(input->source, info); } if (logfile) @@ -1178,12 +1178,13 @@ do_flag_messages (gpointer in_data, gpointer op_data, CamelException *ex) } if (input->invert) { - const CamelMessageInfo *info; + CamelMessageInfo *info; mail_tool_camel_lock_up (); info = camel_folder_get_message_info (input->source, input->uids->pdata[i]); camel_folder_set_message_flags (input->source, input->uids->pdata[i], input->mask, ~info->flags); + camel_folder_free_message_info(input->source, info); mail_tool_camel_lock_down (); } else { mail_tool_set_uid_flags (input->source, input->uids->pdata[i], @@ -1985,7 +1986,8 @@ mail_do_sync_folder (CamelFolder *folder) { g_return_if_fail (CAMEL_IS_FOLDER (folder)); - mail_operation_queue (&op_sync_folder, folder, FALSE); + /*mail_operation_queue (&op_sync_folder, folder, FALSE);*/ + mail_operation_run (&op_sync_folder, folder, FALSE); } /* ** DISPLAY MESSAGE ***************************************************** */ @@ -2112,9 +2114,87 @@ mail_do_display_message (MessageList *ml, MailDisplay *md, const char *uid, input->uid = g_strdup (uid); input->timeout = timeout; - mail_operation_queue (&op_display_message, input, TRUE); + /* this is only temporary */ + /*mail_operation_queue (&op_display_message, input, TRUE);*/ + mail_operation_run (&op_display_message, input, TRUE); +} + +/* dum de dum, below is an entirely async 'operation' thingy */ +struct _op_data { + void *out; + void *in; + CamelException *ex; + const mail_operation_spec *op; + int pipe[2]; + int free; + GIOChannel *channel; +}; + +static void * +runthread(void *oin) +{ + struct _op_data *o = oin; + + o->op->callback(o->in, o->out, o->ex); + + printf("thread run, sending notificaiton\n"); + + write(o->pipe[1], "", 1); + + return oin; } +static gboolean +runcleanup(GIOChannel *source, GIOCondition cond, void *d) +{ + struct _op_data *o = d; + + printf("ggot notification, blup\n"); + + o->op->cleanup(o->in, o->out, o->ex); + + /*close(o->pipe[0]);*/ + close(o->pipe[1]); + + if (o->free) + g_free(o->in); + g_free(o->out); + camel_exception_free(o->ex); + g_free(o); + + g_io_channel_unref(source); + + return FALSE; +} + +#include <pthread.h> + +/* quick hack, like queue, but it runs it instantly in a new thread ! */ +int +mail_operation_run(const mail_operation_spec *op, void *in, int free) +{ + struct _op_data *o; + pthread_t id; + + o = g_malloc0(sizeof(*o)); + o->op = op; + o->in = in; + o->out = g_malloc0(op->datasize); + o->ex = camel_exception_new(); + o->free = free; + pipe(o->pipe); + + o->channel = g_io_channel_unix_new(o->pipe[0]); + g_io_add_watch(o->channel, G_IO_IN, (GIOFunc)runcleanup, o); + + o->op->setup(o->in, o->out, o->ex); + + pthread_create(&id, 0, runthread, o); + + return TRUE; +} + + /* ** EDIT MESSAGES ******************************************************* */ typedef struct edit_messages_input_s { diff --git a/mail/mail-tools.c b/mail/mail-tools.c index 80e9638ce1..0014d48553 100644 --- a/mail/mail-tools.c +++ b/mail/mail-tools.c @@ -284,10 +284,10 @@ mail_tool_move_folder_contents (CamelFolder *source, CamelFolder *dest, gboolean /* Copy the messages */ for (i = 0; i < uids->len; i++) { CamelMimeMessage *msg; - const CamelMessageInfo *info = NULL; + CamelMessageInfo *info = NULL; const gboolean last_message = (i+1 == uids->len); time_t now; - + /* Info */ /* @@ -317,6 +317,9 @@ mail_tool_move_folder_contents (CamelFolder *source, CamelFolder *dest, gboolean if (summary_capability) info = camel_folder_get_message_info (source, uids->pdata[i]); camel_folder_append_message (dest, msg, info, ex); + if (summary_capability) + camel_folder_free_message_info(source, info); + if (camel_exception_is_set (ex)) { camel_object_unref (CAMEL_OBJECT (msg)); goto cleanup; diff --git a/mail/mail-view.c b/mail/mail-view.c index 54ec02de32..cd18b4ff69 100644 --- a/mail/mail-view.c +++ b/mail/mail-view.c @@ -130,12 +130,7 @@ view_delete_msg (GtkWidget *button, gpointer user_data) { mail_view_data *data = (mail_view_data *) user_data; - GPtrArray *uids; - - uids = g_ptr_array_new(); - g_ptr_array_add (uids, g_strdup (data->uid)); - mail_do_flag_messages (data->source, uids, TRUE, - CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_DELETED); + camel_folder_set_message_flags(data->source, data->uid, CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_DELETED); } static void diff --git a/mail/message-list.c b/mail/message-list.c index bc33ae5237..c34b01c18f 100644 --- a/mail/message-list.c +++ b/mail/message-list.c @@ -330,7 +330,7 @@ get_message_uid (MessageList *message_list, int row) /* Gets the CamelMessageInfo for the message displayed at the given * view row. */ -static const CamelMessageInfo * +static CamelMessageInfo * get_message_info (MessageList *message_list, int row) { const char *uid; @@ -364,7 +364,7 @@ message_list_select (MessageList *message_list, int base_row, MessageListSelectDirection direction, guint32 flags, guint32 mask) { - const CamelMessageInfo *info; + CamelMessageInfo *info; int vrow, mrow, last; ETable *et = message_list->table; @@ -393,8 +393,10 @@ message_list_select (MessageList *message_list, int base_row, if (info && (info->flags & mask) == flags) { e_table_set_cursor_row (et, mrow); gtk_signal_emit(GTK_OBJECT (message_list), message_list_signals [MESSAGE_SELECTED], camel_message_info_uid(info)); + camel_folder_free_message_info(message_list->folder, info); return; } + camel_folder_free_message_info(message_list->folder, info); vrow += direction; } @@ -402,6 +404,12 @@ message_list_select (MessageList *message_list, int base_row, } static void +add_uid (MessageList *ml, const char *uid, gpointer data) +{ + g_ptr_array_add ((GPtrArray *) data, g_strdup (uid)); +} + +static void message_list_drag_data_get (ETable *table, int row, int col, @@ -412,7 +420,7 @@ message_list_drag_data_get (ETable *table, gpointer user_data) { MessageList *mlist = (MessageList *) user_data; - const CamelMessageInfo *minfo = get_message_info (mlist, row); + CamelMessageInfo *minfo; GPtrArray *uids = NULL; char *tmpl, *tmpdir, *filename, *subject; @@ -433,14 +441,21 @@ message_list_drag_data_get (ETable *table, g_free (tmpl); return; } - + + minfo = get_message_info (mlist, row); + if (minfo == NULL) { + g_warning("Row %d is invalid", row); + g_free(tmpl); + return; + } subject = g_strdup (camel_message_info_subject (minfo)); + camel_folder_free_message_info(mlist->folder, minfo); e_filename_make_safe (subject); filename = g_strdup_printf ("%s/%s.eml", tmpdir, subject); g_free (subject); uids = g_ptr_array_new (); - g_ptr_array_add (uids, g_strdup (mlist->cursor_uid)); + message_list_foreach (mlist, add_uid, uids); mail_do_save_messages (mlist->folder, uids, filename); @@ -646,7 +661,7 @@ ml_tree_icon_at (ETreeModel *etm, ETreePath *path, void *model_data) static int subtree_unread(MessageList *ml, ETreePath *node) { - const CamelMessageInfo *info; + CamelMessageInfo *info; char *uid; while (node) { @@ -656,8 +671,11 @@ subtree_unread(MessageList *ml, ETreePath *node) g_warning("I got a NULL uid at node %p", node); } else if (id_is_uid(uid) && (info = camel_folder_get_message_info(ml->folder, id_uid(uid)))) { - if (!(info->flags & CAMEL_MESSAGE_SEEN)) + if (!(info->flags & CAMEL_MESSAGE_SEEN)) { + camel_folder_free_message_info(ml->folder, info); return TRUE; + } + camel_folder_free_message_info(ml->folder, info); } if ((child = e_tree_model_node_get_first_child (E_TREE_MODEL (ml->table_model), node))) if (subtree_unread(ml, child)) @@ -670,7 +688,7 @@ subtree_unread(MessageList *ml, ETreePath *node) static int subtree_size(MessageList *ml, ETreePath *node) { - const CamelMessageInfo *info; + CamelMessageInfo *info; char *uid; int size = 0; @@ -682,6 +700,7 @@ subtree_size(MessageList *ml, ETreePath *node) } else if (id_is_uid(uid) && (info = camel_folder_get_message_info(ml->folder, id_uid(uid)))) { size += info->size; + camel_folder_free_message_info(ml->folder, info); } if ((child = e_tree_model_node_get_first_child (E_TREE_MODEL (ml->table_model), node))) size += subtree_size(ml, child); @@ -694,7 +713,7 @@ subtree_size(MessageList *ml, ETreePath *node) static time_t subtree_earliest(MessageList *ml, ETreePath *node, int sent) { - const CamelMessageInfo *info; + CamelMessageInfo *info; char *uid; time_t earliest = 0, date; @@ -711,6 +730,7 @@ subtree_earliest(MessageList *ml, ETreePath *node, int sent) date = info->date_received; if (earliest == 0 || date < earliest) earliest = date; + camel_folder_free_message_info(ml->folder, info); } if ((child = e_tree_model_node_get_first_child (E_TREE_MODEL (ml->table_model), node))) { date = subtree_earliest(ml, child, sent); @@ -728,9 +748,10 @@ static void * ml_tree_value_at (ETreeModel *etm, ETreePath *path, int col, void *model_data) { MessageList *message_list = model_data; - const CamelMessageInfo *msg_info; char *uid; static char *saved; + CamelMessageInfo *info; + static CamelMessageInfo *msg_info; /* simlated(tm) static dynamic memory (sigh) */ if (saved) { @@ -748,10 +769,21 @@ ml_tree_value_at (ETreeModel *etm, ETreePath *path, int col, void *model_data) goto fake; uid = id_uid(uid); - msg_info = camel_folder_get_message_info (message_list->folder, uid); - if (msg_info == NULL) { - g_warning("UID for message-list not found in folder: %s", uid); - return NULL; + /* we need ot keep the msg_info ref'd as we return the data, sigh. + + Well, since we have it around, also check to see if its the same + one each call, and save the folder lookup */ + if (msg_info == NULL || strcmp(camel_message_info_uid(msg_info), uid) != 0) { + /* FIXME: what if the folder changes? Nothing sets the folder + yet, but this probably means we need to cache this inside the ml itself */ + if (msg_info) + camel_folder_free_message_info(message_list->folder, msg_info); + + msg_info = camel_folder_get_message_info (message_list->folder, uid); + if (msg_info == NULL) { + g_warning("UID for message-list not found in folder: %s", uid); + return NULL; + } } switch (col){ @@ -856,9 +888,10 @@ ml_tree_value_at (ETreeModel *etm, ETreePath *path, int col, void *model_data) if ( (child = e_tree_model_node_get_first_child(etm, path)) && (uid = e_tree_model_node_get_data (etm, child)) && id_is_uid(uid) - && (msg_info = camel_folder_get_message_info (message_list->folder, id_uid(uid))) ) { + && (info = camel_folder_get_message_info (message_list->folder, id_uid(uid))) ) { /* well, we could scan more children, build up a (more accurate) list, but this should do ok */ - saved = g_strdup_printf(_("%s, et al."), camel_message_info_from(msg_info)); + saved = g_strdup_printf(_("%s, et al."), camel_message_info_from(info)); + camel_folder_free_message_info(message_list->folder, info); } else { return _("<unknown>"); } @@ -871,9 +904,10 @@ ml_tree_value_at (ETreeModel *etm, ETreePath *path, int col, void *model_data) if ( (child = e_tree_model_node_get_first_child(etm, path)) && (uid = e_tree_model_node_get_data (etm, child)) && id_is_uid(uid) - && (msg_info = camel_folder_get_message_info (message_list->folder, id_uid(uid))) ) { + && (info = camel_folder_get_message_info (message_list->folder, id_uid(uid))) ) { /* well, we could scan more children, build up a (more accurate) list, but this should do ok */ - saved = g_strdup_printf(_("%s, et al."), camel_message_info_to(msg_info)); + saved = g_strdup_printf(_("%s, et al."), camel_message_info_to(info)); + camel_folder_free_message_info(message_list->folder, info); } else { return _("<unknown>"); } @@ -1115,6 +1149,8 @@ message_list_init (GtkObject *object) message_list->hidden_pool = NULL; message_list->hide_before = ML_HIDE_NONE_START; message_list->hide_after = ML_HIDE_NONE_END; + + message_list->hide_lock = g_mutex_new(); } static void @@ -1139,7 +1175,6 @@ message_list_destroy (GtkObject *object) if (message_list->seen_id) gtk_timeout_remove (message_list->seen_id); - mail_tool_camel_lock_up(); if (message_list->folder) { camel_object_unhook_event((CamelObject *)message_list->folder, "folder_changed", folder_changed, message_list); @@ -1154,8 +1189,9 @@ message_list_destroy (GtkObject *object) message_list->hidden = NULL; message_list->hidden_pool = NULL; } - mail_tool_camel_lock_down(); + g_mutex_free(message_list->hide_lock); + GTK_OBJECT_CLASS (message_list_parent_class)->destroy (object); } @@ -1291,7 +1327,7 @@ static void save_node_state(MessageList *ml, FILE *out, ETreePath *node) { char *data; - const CamelMessageInfo *info; + CamelMessageInfo *info; while (node) { ETreePath *child = e_tree_model_node_get_first_child (E_TREE_MODEL (ml->table_model), node); @@ -1303,6 +1339,7 @@ save_node_state(MessageList *ml, FILE *out, ETreePath *node) info = camel_folder_get_message_info(ml->folder, id_uid(data)); if (info) { fprintf(out, "%08x%08x\n", info->message_id.id.part.hi, info->message_id.id.part.lo); + camel_folder_free_message_info(ml->folder, info); } } else { fprintf(out, "%s\n", data); @@ -1888,7 +1925,24 @@ main_folder_changed (CamelObject *o, gpointer event_data, gpointer user_data) CamelFolderChangeInfo *changes = (CamelFolderChangeInfo *)event_data; printf("folder changed event, changes = %p\n", changes); + if (changes) { + printf("changed = %d added = %d removed = %d\n", + changes->uid_changed->len, changes->uid_added->len, changes->uid_removed->len); + if (changes->uid_added->len == 0 && changes->uid_removed->len == 0) { + int i; + + for (i=0;i<changes->uid_changed->len;i++) { + int row = GPOINTER_TO_INT (g_hash_table_lookup (ml->uid_rowmap, changes->uid_changed->pdata[i])); + if (row != -1) + e_table_model_row_changed(ml->table_model, row); + } + + camel_folder_change_info_free(changes); + return; + } + } + mail_do_regenerate_messagelist(ml, ml->search, NULL, changes); } @@ -2010,7 +2064,7 @@ static gint on_click (ETableScrolled *table, gint row, gint col, GdkEvent *event, MessageList *list) { int flag; - const CamelMessageInfo *info; + CamelMessageInfo *info; if (col == COL_MESSAGE_STATUS) flag = CAMEL_MESSAGE_SEEN; @@ -2019,17 +2073,13 @@ on_click (ETableScrolled *table, gint row, gint col, GdkEvent *event, MessageLis else return FALSE; - mail_tool_camel_lock_up(); - info = get_message_info(list, row); if (info == NULL) { - mail_tool_camel_lock_down(); return FALSE; } camel_folder_set_message_flags(list->folder, camel_message_info_uid(info), flag, ~info->flags); - - mail_tool_camel_lock_down(); + camel_folder_free_message_info(list->folder, info); if (flag == CAMEL_MESSAGE_SEEN && list->seen_id) { gtk_timeout_remove (list->seen_id); @@ -2118,12 +2168,14 @@ unsigned int message_list_length(MessageList *ml) */ void message_list_hide_add(MessageList *ml, const char *expr, unsigned int lower, unsigned int upper) { - mail_tool_camel_lock_up(); + MESSAGE_LIST_LOCK(ml, hide_lock); + if (lower != ML_HIDE_SAME) ml->hide_before = lower; if (upper != ML_HIDE_SAME) ml->hide_after = upper; - mail_tool_camel_lock_down(); + + MESSAGE_LIST_UNLOCK(ml, hide_lock); mail_do_regenerate_messagelist(ml, ml->search, expr, NULL); } @@ -2137,7 +2189,7 @@ void message_list_hide_uids(MessageList *ml, GPtrArray *uids) /* first see if we need to do any work, if so, then do it all at once */ for (i=0;i<uids->len;i++) { if (g_hash_table_lookup(ml->uid_rowmap, uids->pdata[i])) { - mail_tool_camel_lock_up(); + MESSAGE_LIST_LOCK(ml, hide_lock); if (ml->hidden == NULL) { ml->hidden = g_hash_table_new(g_str_hash, g_str_equal); ml->hidden_pool = e_mempool_new(512, 256, E_MEMPOOL_ALIGN_BYTE); @@ -2151,7 +2203,7 @@ void message_list_hide_uids(MessageList *ml, GPtrArray *uids) g_hash_table_insert(ml->hidden, uid, uid); } } - mail_tool_camel_lock_down(); + MESSAGE_LIST_UNLOCK(ml, hide_lock); mail_do_regenerate_messagelist(ml, ml->search, NULL, NULL); break; } @@ -2161,7 +2213,7 @@ void message_list_hide_uids(MessageList *ml, GPtrArray *uids) /* no longer hide any messages */ void message_list_hide_clear(MessageList *ml) { - mail_tool_camel_lock_up(); + MESSAGE_LIST_LOCK(ml, hide_lock); if (ml->hidden) { g_hash_table_destroy(ml->hidden); e_mempool_destroy(ml->hidden_pool); @@ -2170,7 +2222,7 @@ void message_list_hide_clear(MessageList *ml) } ml->hide_before = ML_HIDE_NONE_START; ml->hide_after = ML_HIDE_NONE_END; - mail_tool_camel_lock_down(); + MESSAGE_LIST_UNLOCK(ml, hide_lock); mail_do_regenerate_messagelist(ml, ml->search, NULL, NULL); } @@ -2195,7 +2247,7 @@ static void hide_load_state(MessageList *ml) if (in) { camel_folder_summary_decode_fixed_int32(in, &version); if (version == HIDE_STATE_VERSION) { - mail_tool_camel_lock_up(); + MESSAGE_LIST_LOCK(ml, hide_lock); if (ml->hidden == NULL) { ml->hidden = g_hash_table_new(g_str_hash, g_str_equal); ml->hidden_pool = e_mempool_new(512, 256, E_MEMPOOL_ALIGN_BYTE); @@ -2212,7 +2264,7 @@ static void hide_load_state(MessageList *ml) g_hash_table_insert(ml->hidden, uid, uid); } } - mail_tool_camel_lock_down(); + MESSAGE_LIST_UNLOCK(ml, hide_lock); } fclose(in); } @@ -2231,8 +2283,9 @@ static void hide_save_state(MessageList *ml) char *filename; FILE *out; + MESSAGE_LIST_LOCK(ml, hide_lock); + filename = mail_config_folder_to_cachename(ml->folder, "hidestate-"); - mail_tool_camel_lock_up(); if (ml->hidden == NULL && ml->hide_before == ML_HIDE_NONE_START && ml->hide_after == ML_HIDE_NONE_END) { unlink(filename); } else if ( (out = fopen(filename, "w")) ) { @@ -2243,11 +2296,11 @@ static void hide_save_state(MessageList *ml) g_hash_table_foreach(ml->hidden, (GHFunc)hide_save_1, out); fclose(out); } - mail_tool_camel_lock_down(); + + MESSAGE_LIST_UNLOCK(ml, hide_lock); } /* ** REGENERATE MESSAGELIST ********************************************** */ - typedef struct regenerate_messagelist_input_s { MessageList *ml; CamelFolder *folder; @@ -2297,8 +2350,6 @@ static void do_regenerate_messagelist (gpointer in_data, gpointer op_data, Camel int i; GPtrArray *uids, *uidnew; - mail_tool_camel_lock_up(); - if (input->search) { data->uids = camel_folder_search_by_expression(input->ml->folder, input->search, ex); } else { @@ -2306,7 +2357,6 @@ static void do_regenerate_messagelist (gpointer in_data, gpointer op_data, Camel } if (camel_exception_is_set (ex)) { - mail_tool_camel_lock_down(); return; } @@ -2317,6 +2367,8 @@ static void do_regenerate_messagelist (gpointer in_data, gpointer op_data, Camel camel_exception_clear(ex); if (uidnew) { + MESSAGE_LIST_LOCK(input->ml, hide_lock); + if (input->ml->hidden == NULL) { input->ml->hidden = g_hash_table_new(g_str_hash, g_str_equal); input->ml->hidden_pool = e_mempool_new(512, 256, E_MEMPOOL_ALIGN_BYTE); @@ -2328,10 +2380,15 @@ static void do_regenerate_messagelist (gpointer in_data, gpointer op_data, Camel g_hash_table_insert(input->ml->hidden, uid, uid); } } + + MESSAGE_LIST_UNLOCK(input->ml, hide_lock); + camel_folder_search_free(input->ml->folder, uidnew); } } + MESSAGE_LIST_LOCK(input->ml, hide_lock); + input->ml->hide_unhidden = data->uids->len; /* what semantics do we want from hide_before, hide_after? @@ -2379,12 +2436,12 @@ static void do_regenerate_messagelist (gpointer in_data, gpointer op_data, Camel data->realuids = NULL; } + MESSAGE_LIST_UNLOCK(input->ml, hide_lock); + if (input->dotree && data->uids) data->tree = camel_folder_thread_messages_new(input->ml->folder, data->uids); else data->tree = NULL; - - mail_tool_camel_lock_down(); } static void cleanup_regenerate_messagelist (gpointer in_data, gpointer op_data, CamelException *ex) @@ -2392,9 +2449,6 @@ static void cleanup_regenerate_messagelist (gpointer in_data, gpointer op_data, regenerate_messagelist_input_t *input = (regenerate_messagelist_input_t *) in_data; regenerate_messagelist_data_t *data = (regenerate_messagelist_data_t *) op_data; GPtrArray *uids; - ETreeModel *etm; - - etm = E_TREE_MODEL (input->ml->table_model); if (data->uids == NULL) { /*exception*/ gtk_object_unref (GTK_OBJECT (input->ml)); @@ -2470,5 +2524,7 @@ mail_do_regenerate_messagelist (MessageList *list, const gchar *search, const ch input->changes = changes; input->dotree = list->threaded; - mail_operation_queue (&op_regenerate_messagelist, input, TRUE); + /* just a quick hack, so dont unwarn yet, or die */ + mail_operation_run (&op_regenerate_messagelist, input, TRUE); + /*mail_operation_queue (&op_regenerate_messagelist, input, TRUE);*/ } diff --git a/mail/message-list.h b/mail/message-list.h index 8e150c8a3d..468f8cc3dc 100644 --- a/mail/message-list.h +++ b/mail/message-list.h @@ -2,7 +2,9 @@ #ifndef _MESSAGE_LIST_H_ #define _MESSAGE_LIST_H_ -#include <gnome.h> +/*#include <gnome.h>*/ +#include <gtk/gtk.h> + #include "mail-types.h" #include <gal/e-table/e-table-scrolled.h> #include <gal/e-table/e-table-simple.h> @@ -62,7 +64,7 @@ struct _MessageList { struct _EMemPool *uid_pool; /* UID's to hide. Keys in the mempool */ - /* IMPORTANT: You MUST have obtained the camel lock, to operate on these structures */ + /* IMPORTANT: You MUST have obtained the hide lock, to operate on this data */ GHashTable *hidden; struct _EMemPool *hidden_pool; int hide_unhidden, /* total length, before hiding */ @@ -80,6 +82,9 @@ struct _MessageList { /* Row-selection and seen-marking timers */ guint idle_id, seen_id; + + /* locks */ + GMutex *hide_lock; /* for any 'hide' info above */ }; typedef struct { @@ -123,4 +128,7 @@ void message_list_hide_clear(MessageList *ml); void message_list_set_threaded(MessageList *ml, gboolean threaded); void message_list_set_search(MessageList *ml, const char *search); +#define MESSAGE_LIST_LOCK(m, l) g_mutex_lock(((MessageList *)m)->l) +#define MESSAGE_LIST_UNLOCK(m, l) g_mutex_unlock(((MessageList *)m)->l) + #endif /* _MESSAGE_LIST_H_ */ |