[balsa/gtk4] mailbox-imap: Handle expunged messages in idle
- From: Peter Bloomfield <peterb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [balsa/gtk4] mailbox-imap: Handle expunged messages in idle
- Date: Sat, 13 Mar 2021 22:03:17 +0000 (UTC)
commit c549edb82e1b0b5059a838034641cb8a0063d156
Author: Peter Bloomfield <peterbloomfield bellsouth net>
Date: Fri Mar 12 10:12:19 2021 +0000
mailbox-imap: Handle expunged messages in idle
Handle expunged IMAP messages in an idle callback
* libbalsa/mailbox_imap.c: add an array of expunged messages and
an idle id to LibBalsaMailboxImap;
(libbalsa_mailbox_imap_init): initialize them;
(libbalsa_mailbox_imap_dispose): remove any outstanding idle source;
(libbalsa_mailbox_imap_finalize): free the array;
(imap_expunge_cb): populate the array, and if necessary schedule the idle callback;
(imap_expunge_idle): handle the expunged messages.
ChangeLog | 32 +++++++++++++++
libbalsa/mailbox_imap.c | 107 ++++++++++++++++++++++++++++++++++--------------
2 files changed, 109 insertions(+), 30 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index a7949b077..0c6433952 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2021-03-09 Peter Bloomfield <pbloomfield bellsouth net>
+
+ Try to avoid critical messages
+
+ * libbalsa/mailbox_imap.c
+ (imap_expunge_idle): handle expunged messages in the order
+ they are expunged;
+ (libbalsa_mailbox_imap_fetch_headers): avoid a critical message.
+
+2021-03-08 Peter Bloomfield <pbloomfield bellsouth net>
+
+ Remove a scheduled idle callback at close time instead of at
+ dispose time.
+
+ * libbalsa/mailbox_imap.c
+ (libbalsa_mailbox_imap_close): remove expunged idle source, if any;
+ (libbalsa_mailbox_imap_dispose): comment that it should have
+ been removed at close time.
+
+2021-03-08 Peter Bloomfield <pbloomfield bellsouth net>
+
+ Handle expunged IMAP messages in an idle callback
+
+ * libbalsa/mailbox_imap.c: add an array of expunged messages and
+ an idle id to LibBalsaMailboxImap;
+ (libbalsa_mailbox_imap_init): initialize them;
+ (libbalsa_mailbox_imap_dispose): remove any outstanding idle source;
+ (libbalsa_mailbox_imap_finalize): free the array;
+ (imap_expunge_cb): populate the array, and if necessary schedule the idle
+ callback;
+ (imap_expunge_idle): handle the expunged messages.
+
2020-12-21 Pawel Salek <pawsa0 gmail com>
* NEWS, configure.ac, meson.build: release balsa-2.6.2
diff --git a/libbalsa/mailbox_imap.c b/libbalsa/mailbox_imap.c
index dbe4091d8..ce50379fc 100644
--- a/libbalsa/mailbox_imap.c
+++ b/libbalsa/mailbox_imap.c
@@ -86,6 +86,9 @@ struct _LibBalsaMailboxImap {
gboolean disconnected;
struct ImapCacheManager *icm;
+
+ GArray *expunged_seqnos;
+ guint expunged_idle_id;
};
struct message_info {
@@ -275,6 +278,9 @@ libbalsa_mailbox_imap_init(LibBalsaMailboxImap * mailbox)
mailbox->sort_ranks = g_array_new(FALSE, FALSE, sizeof(guint));
mailbox->sort_field = -1; /* Initially invalid. */
mailbox->disconnected = FALSE;
+
+ mailbox->expunged_seqnos = g_array_new(FALSE, FALSE, sizeof(guint));
+ mailbox->expunged_idle_id = 0;
}
static void
@@ -297,6 +303,13 @@ libbalsa_mailbox_imap_dispose(GObject * object)
mimap->unread_update_id = 0;
}
+ if (mimap->expunged_idle_id != 0) {
+ /* Should have been removed at close time, but to be on the safe
+ * side: */
+ g_source_remove(mimap->expunged_idle_id);
+ mimap->expunged_idle_id = 0;
+ }
+
G_OBJECT_CLASS(libbalsa_mailbox_imap_parent_class)->dispose(object);
}
@@ -307,6 +320,7 @@ libbalsa_mailbox_imap_finalize(GObject * object)
g_free(mimap->path);
g_array_free(mimap->sort_ranks, TRUE);
+ g_array_free(mimap->expunged_seqnos, TRUE);
g_list_free_full(mimap->acls, (GDestroyNotify) imap_user_acl_free);
if (mimap->icm != NULL)
imap_cache_manager_free(mimap->icm);
@@ -884,22 +898,67 @@ imap_exists_cb(ImapMboxHandle *handle, LibBalsaMailboxImap *mimap)
g_idle_add(imap_exists_idle, g_object_ref(mimap));
}
+static gboolean
+imap_expunge_idle(gpointer user_data)
+{
+ LibBalsaMailboxImap *mimap = user_data;
+ guint j;
+
+ LibBalsaMailbox *mailbox = LIBBALSA_MAILBOX(mimap);
+
+ libbalsa_lock_mailbox(mailbox);
+
+ for (j = 0; j < mimap->expunged_seqnos->len; j++) {
+ guint seqno = g_array_index(mimap->expunged_seqnos, guint, j);
+ struct message_info *msg_info;
+ guint i;
+
+ libbalsa_mailbox_msgno_removed(mailbox, seqno);
+
+ msg_info = message_info_from_msgno(mimap, seqno);
+ if (msg_info != NULL) {
+ if (msg_info->message != NULL)
+ g_object_unref(msg_info->message);
+ g_array_remove_index(mimap->messages_info, seqno - 1);
+ }
+
+ if (seqno <= mimap->msgids->len) {
+ gchar *msgid;
+
+ msgid = g_ptr_array_index(mimap->msgids, seqno - 1);
+ g_free(msgid);
+ g_ptr_array_remove_index(mimap->msgids, seqno - 1);
+ }
+
+ for (i = seqno - 1; i < mimap->messages_info->len; i++) {
+ struct message_info *info =
+ &g_array_index(mimap->messages_info, struct message_info, i);
+
+ g_assert(info != NULL);
+ if (info->message != NULL)
+ libbalsa_message_set_msgno(info->message, i + 1);
+ }
+ }
+
+ ++mimap->search_stamp;
+ mimap->sort_field = -1; /* Invalidate. */
+
+ mimap->expunged_idle_id = 0;
+ g_array_set_size(mimap->expunged_seqnos, 0);
+ libbalsa_unlock_mailbox(mailbox);
+
+ return G_SOURCE_REMOVE;
+}
+
static void
imap_expunge_cb(ImapMboxHandle *handle, unsigned seqno,
LibBalsaMailboxImap *mimap)
{
ImapMessage *imsg;
- guint i;
-
LibBalsaMailbox *mailbox = LIBBALSA_MAILBOX(mimap);
- struct message_info *msg_info;
libbalsa_lock_mailbox(mailbox);
- libbalsa_mailbox_msgno_removed(mailbox, seqno);
- ++mimap->search_stamp;
- mimap->sort_field = -1; /* Invalidate. */
-
/* Use imap_mbox_handle_get_msg(mimap->handle, seqno)->uid, not
* IMAP_MESSAGE_UID(msg_info->message), as the latter may try to
* fetch the message from the server. */
@@ -912,29 +971,9 @@ imap_expunge_cb(ImapMboxHandle *handle, unsigned seqno,
g_strfreev(pair);
}
- msg_info = message_info_from_msgno(mimap, seqno);
- if (msg_info) {
- if (msg_info->message)
- g_object_unref(msg_info->message);
- g_array_remove_index(mimap->messages_info, seqno-1);
- }
-
- if (seqno <= mimap->msgids->len) {
- gchar *msgid;
-
- msgid = g_ptr_array_index(mimap->msgids, seqno - 1);
- g_free(msgid);
- g_ptr_array_remove_index(mimap->msgids, seqno - 1);
- }
-
- for (i = seqno - 1; i < mimap->messages_info->len; i++) {
- struct message_info *info =
- &g_array_index(mimap->messages_info, struct message_info, i);
-
- g_assert(info != NULL);
- if (info->message != NULL)
- libbalsa_message_set_msgno(info->message, i + 1);
- }
+ g_array_append_val(mimap->expunged_seqnos, seqno);
+ if (mimap->expunged_idle_id == 0)
+ mimap->expunged_idle_id = g_idle_add(imap_expunge_idle, mimap);
libbalsa_unlock_mailbox(mailbox);
}
@@ -1167,6 +1206,10 @@ libbalsa_mailbox_imap_close(LibBalsaMailbox * mailbox, gboolean expunge)
}
clean_cache(mailbox);
+ if (mimap->expunged_idle_id != 0) {
+ g_source_remove(mimap->expunged_idle_id);
+ mimap->expunged_idle_id = 0;
+ }
free_messages_info(mimap);
libbalsa_mailbox_imap_release_handle(mimap);
@@ -2285,6 +2328,10 @@ libbalsa_mailbox_imap_fetch_headers(LibBalsaMailbox *mailbox,
glong msgno;
msgno = libbalsa_message_get_msgno(message);
+ /* If message numbers are out of sync with the mail store,
+ * just skip the message: */
+ if (msgno > imap_mbox_handle_get_exists(mimap->handle))
+ return;
II(rc,mimap->handle,
imap_mbox_handle_fetch_range(mimap->handle, msgno, msgno,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]