From d38776333944dc2aa07443fb2e73e433e8271e64 Mon Sep 17 00:00:00 2001 From: alexhudson Date: Sat, 8 Mar 2008 14:24:09 +0000 Subject: [PATCH] Allow the progress system to flush the client socket occasionally, so IMAP clients get more regular reports on work done. Tbird should now be stable for large amounts of mail. --- src/agents/imap/imapd.c | 26 ++++++++++++++++++-------- src/agents/imap/progress.c | 10 ++++++---- src/agents/imap/store.c | 4 ++-- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/agents/imap/imapd.c b/src/agents/imap/imapd.c index 8610eea..9ed9dc5 100644 --- a/src/agents/imap/imapd.c +++ b/src/agents/imap/imapd.c @@ -2355,25 +2355,28 @@ ImapCommandCheck(void *param) } __inline static long -PurgeDeletedMessages(Connection *storeConn, Connection *clientConn, MessageInformation *message, unsigned long messageCount) +PurgeDeletedMessages(ImapSession *session, BOOL client_response, MessageInformation *message, unsigned long messageCount) { long ccode = 0; long count; + Connection *store = session->store.conn; + Connection *client = session->client.conn; count = messageCount; while (count > 0) { + ProgressUpdate(session); if (!(message->flags & STORE_MSG_FLAG_DELETED) || (message->flags & STORE_MSG_FLAG_PURGED)) { message--; count--; continue; } - if (NMAPSendCommandF(storeConn, "PURGE %llx\r\n", message->guid) != -1) { - ccode = NMAPReadResponse(storeConn, NULL, 0, 0); + if (NMAPSendCommandF(store, "PURGE %llx\r\n", message->guid) != -1) { + ccode = NMAPReadResponse(store, NULL, 0, 0); if (ccode == 1000) { - if (clientConn) { - if (ConnWriteF(clientConn, "* %lu EXPUNGE\r\n", count) != -1) { + if (client_response) { + if (ConnWriteF(client, "* %lu EXPUNGE\r\n", count) != -1) { message--; count--; continue; @@ -2395,21 +2398,24 @@ ImapCommandClose(void *param) ImapSession *session = (ImapSession *)param; long ccode; + StartProgressUpdate(session, "Purging deleted messsages"); if ((ccode = CheckState(session, STATE_SELECTED)) == STATUS_CONTINUE) { if (session->folder.selected.readOnly) { FolderDeselect(session); + StopProgressUpdate(session); return(SendOk(session, "CLOSE")); } - ccode = PurgeDeletedMessages(session->store.conn, 0, &(session->folder.selected.message[session->folder.selected.messageCount - 1]), session->folder.selected.messageCount); + ccode = PurgeDeletedMessages(session, FALSE, &(session->folder.selected.message[session->folder.selected.messageCount - 1]), session->folder.selected.messageCount); FolderDeselect(session); if (ccode == STATUS_CONTINUE) { + StopProgressUpdate(session); return(SendOk(session, "CLOSE")); } } + StopProgressUpdate(session); return(SendError(session->client.conn, session->command.tag, "CLOSE", ccode)); - } int @@ -2418,19 +2424,23 @@ ImapCommandExpunge(void *param) ImapSession *session = (ImapSession *)param; OpenedFolder *selected = &session->folder.selected; long ccode; + + StartProgressUpdate(session, NULL); if ((ccode = CheckState(session, STATE_SELECTED)) == STATUS_CONTINUE) { if ((ccode = EventsSend(session, STORE_EVENT_ALL)) == STATUS_CONTINUE) { ccode = STATUS_READ_ONLY_FOLDER; if (!(selected->readOnly)) { - if ((ccode = PurgeDeletedMessages(session->store.conn, session->client.conn, &(selected->message[selected->messageCount - 1]), selected->messageCount)) == STATUS_CONTINUE) { + if ((ccode = PurgeDeletedMessages(session, TRUE, &(selected->message[selected->messageCount - 1]), selected->messageCount)) == STATUS_CONTINUE) { if ((ccode = MessageListLoad(session->store.conn, selected)) == STATUS_CONTINUE) { + StopProgressUpdate(session); return(SendOk(session, "EXPUNGE")); } } } } } + StopProgressUpdate(session); return(SendError(session->client.conn, session->command.tag, "EXPUNGE", ccode)); } diff --git a/src/agents/imap/progress.c b/src/agents/imap/progress.c index f7eea5a..1cc8324 100644 --- a/src/agents/imap/progress.c +++ b/src/agents/imap/progress.c @@ -12,10 +12,12 @@ DoProgressUpdate(ImapSession *session) if (status == NULL) return; status->messages_processed++; if ((now - status->last_update) > 10) { - // update the client - ConnWriteF(session->client.conn, - "* OK - %s (processed %d since last update)\n", - status->message, status->messages_processed); + // update the client - if we have no message, just Flush the output + if (status->message) { + ConnWriteF(session->client.conn, + "* OK - %s (processed %d since last update)\n", + status->message, status->messages_processed); + } ConnFlush(session->client.conn); status->last_update = now; status->messages_processed = 0; diff --git a/src/agents/imap/store.c b/src/agents/imap/store.c index 7b87365..c78fafa 100644 --- a/src/agents/imap/store.c +++ b/src/agents/imap/store.c @@ -215,7 +215,7 @@ ImapCommandStore(void *param) ImapSession *session = (ImapSession *)param; BOOL purgedMessage = FALSE; - StartProgressUpdate(session, "Store"); + StartProgressUpdate(session, NULL); if ((ccode = HandleStore(session, FALSE, &purgedMessage)) == STATUS_CONTINUE) { if (!purgedMessage) { @@ -235,7 +235,7 @@ ImapCommandUidStore(void *param) ImapSession *session = (ImapSession *)param; BOOL purgedMessage = FALSE; - StartProgressUpdate(session, "UID Store"); + StartProgressUpdate(session, NULL); memmove(session->command.buffer, session->command.buffer + strlen("UID "), strlen(session->command.buffer + strlen("UID ")) + 1); if ((ccode = HandleStore(session, TRUE, &purgedMessage)) == STATUS_CONTINUE) {