From: Markus Valentin Date: Tue, 18 Jan 2022 08:22:24 +0000 (+0100) Subject: imapc: Add imapc_sync_handle_untagged_fetches() X-Git-Tag: 2.3.19~42 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6d505f1b39aaba35229a9725a052be3116186011;p=thirdparty%2Fdovecot%2Fcore.git imapc: Add imapc_sync_handle_untagged_fetches() --- diff --git a/src/lib-storage/index/imapc/imapc-mailbox.c b/src/lib-storage/index/imapc/imapc-mailbox.c index 61052922c9..cb2dc9dc74 100644 --- a/src/lib-storage/index/imapc/imapc-mailbox.c +++ b/src/lib-storage/index/imapc/imapc-mailbox.c @@ -40,7 +40,7 @@ void imapc_mailbox_set_corrupted(struct imapc_mailbox *mbox, imapc_client_mailbox_reconnect(mbox->client_box, errmsg); } -static struct mail_index_view * +struct mail_index_view * imapc_mailbox_get_sync_view(struct imapc_mailbox *mbox) { if (mbox->sync_view == NULL) @@ -487,7 +487,7 @@ imapc_untagged_fetch_ctx_create(void) return ctx; } -static void imapc_untagged_fetch_ctx_free(struct imapc_untagged_fetch_ctx **_ctx) +void imapc_untagged_fetch_ctx_free(struct imapc_untagged_fetch_ctx **_ctx) { struct imapc_untagged_fetch_ctx *ctx = *_ctx; @@ -497,10 +497,10 @@ static void imapc_untagged_fetch_ctx_free(struct imapc_untagged_fetch_ctx **_ctx pool_unref(&ctx->pool); } -static void -imapc_untagged_fetch_update_flags(struct imapc_mailbox *mbox, - struct imapc_untagged_fetch_ctx *ctx, - uint32_t lseq) +void imapc_untagged_fetch_update_flags(struct imapc_mailbox *mbox, + struct imapc_untagged_fetch_ctx *ctx, + struct mail_index_view *view, + uint32_t lseq) { ARRAY_TYPE(keyword_indexes) old_kws; struct mail_keywords *kw; @@ -510,14 +510,14 @@ imapc_untagged_fetch_update_flags(struct imapc_mailbox *mbox, if (!ctx->have_flags) return; - rec = mail_index_lookup(mbox->delayed_sync_view, lseq); + rec = mail_index_lookup(view, lseq); if (rec->flags != ctx->flags) { mail_index_update_flags(mbox->delayed_sync_trans, lseq, MODIFY_REPLACE, ctx->flags); } t_array_init(&old_kws, 8); - mail_index_lookup_keywords(mbox->delayed_sync_view, lseq, &old_kws); + mail_index_lookup_keywords(view, lseq, &old_kws); if (ctx->have_gmail_labels) { /* add keyword for mails that have GMail labels. @@ -582,7 +582,11 @@ static bool imapc_untagged_fetch_handle(struct imapc_mailbox *mbox, mbox->sync_next_lseq++; } - imapc_untagged_fetch_update_flags(mbox, ctx, lseq); + if (!new_message) { + /* Only update flags immediately for existing messages */ + imapc_untagged_fetch_update_flags(mbox, ctx, + mbox->delayed_sync_view, lseq); + } if (ctx->modseq != 0) { if (mail_index_modseq_lookup(mbox->delayed_sync_view, lseq) < ctx->modseq) diff --git a/src/lib-storage/index/imapc/imapc-storage.c b/src/lib-storage/index/imapc/imapc-storage.c index 49bf78f7e4..0db89092f3 100644 --- a/src/lib-storage/index/imapc/imapc-storage.c +++ b/src/lib-storage/index/imapc/imapc-storage.c @@ -538,6 +538,7 @@ imapc_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list, p_array_init(&mbox->untagged_callbacks, pool, 16); p_array_init(&mbox->resp_text_callbacks, pool, 16); p_array_init(&mbox->fetch_requests, pool, 16); + p_array_init(&mbox->untagged_fetch_contexts, pool, 16); p_array_init(&mbox->delayed_expunged_uids, pool, 16); mbox->pending_fetch_cmd = str_new(pool, 128); mbox->prev_mail_cache.fd = -1; diff --git a/src/lib-storage/index/imapc/imapc-storage.h b/src/lib-storage/index/imapc/imapc-storage.h index 6d2e3e871a..6040c3389a 100644 --- a/src/lib-storage/index/imapc/imapc-storage.h +++ b/src/lib-storage/index/imapc/imapc-storage.h @@ -126,6 +126,7 @@ struct imapc_mailbox { struct timeout *to_idle_check, *to_idle_delay; ARRAY(struct imapc_fetch_request *) fetch_requests; + ARRAY(struct imapc_untagged_fetch_ctx *) untagged_fetch_contexts; /* if non-empty, contains the latest FETCH command we're going to be sending soon (but still waiting to see if we can increase its UID range) */ @@ -240,4 +241,13 @@ void imapc_mailbox_register_resp_text(struct imapc_mailbox *mbox, void imapc_mailbox_register_callbacks(struct imapc_mailbox *mbox); +struct mail_index_view * +imapc_mailbox_get_sync_view(struct imapc_mailbox *mbox); + +void imapc_untagged_fetch_ctx_free(struct imapc_untagged_fetch_ctx **_ctx); +void imapc_untagged_fetch_update_flags(struct imapc_mailbox *mbox, + struct imapc_untagged_fetch_ctx *ctx, + struct mail_index_view *view, + uint32_t lseq); + #endif diff --git a/src/lib-storage/index/imapc/imapc-sync.c b/src/lib-storage/index/imapc/imapc-sync.c index 68de93b8ca..afd8c67497 100644 --- a/src/lib-storage/index/imapc/imapc-sync.c +++ b/src/lib-storage/index/imapc/imapc-sync.c @@ -524,6 +524,68 @@ static int imapc_sync_finish(struct imapc_sync_context **_ctx) return ret; } +static int imapc_untagged_fetch_uid_cmp(struct imapc_untagged_fetch_ctx *const *ctx1, + struct imapc_untagged_fetch_ctx *const *ctx2) +{ + return (*ctx1)->uid < (*ctx2)->uid ? -1 : + (*ctx1)->uid > (*ctx2)->uid ? 1 : 0; +} + +static void imapc_sync_handle_untagged_fetches(struct imapc_mailbox *mbox) +{ + struct imapc_untagged_fetch_ctx *untagged_fetch_context; + struct mail_index_view *updated_view; + uint32_t lseq; + + i_assert(array_count(&mbox->untagged_fetch_contexts) > 0); + i_assert(mbox->delayed_sync_trans == NULL); + + array_sort(&mbox->untagged_fetch_contexts, imapc_untagged_fetch_uid_cmp); + + mbox->delayed_sync_trans = + mail_index_transaction_begin(imapc_mailbox_get_sync_view(mbox), + MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL); + + array_foreach_elem(&mbox->untagged_fetch_contexts, untagged_fetch_context) { + if (untagged_fetch_context->uid < mbox->min_append_uid || + untagged_fetch_context->uid < mail_index_get_header(mbox->sync_view)->next_uid) { + /* The message was already added */ + continue; + } + + mail_index_append(mbox->delayed_sync_trans, + untagged_fetch_context->uid, + &lseq); + mbox->min_append_uid = untagged_fetch_context->uid + 1; + } + + updated_view = mail_index_transaction_open_updated_view(mbox->delayed_sync_trans); + + array_foreach_elem(&mbox->untagged_fetch_contexts, untagged_fetch_context) { + if (!untagged_fetch_context->have_flags) { + imapc_untagged_fetch_ctx_free(&untagged_fetch_context); + continue; + } + + /* Lookup the mail belonging to this context using the + context->uid */ + if (!mail_index_lookup_seq(updated_view, + untagged_fetch_context->uid, + &lseq)) { + /* mail is expunged already */ + imapc_untagged_fetch_ctx_free(&untagged_fetch_context); + continue; + } + + imapc_untagged_fetch_update_flags(mbox, untagged_fetch_context, + updated_view, lseq); + imapc_untagged_fetch_ctx_free(&untagged_fetch_context); + } + + mail_index_view_close(&updated_view); + array_clear(&mbox->untagged_fetch_contexts); +} + static int imapc_sync(struct imapc_mailbox *mbox) { struct imapc_sync_context *sync_ctx; @@ -536,6 +598,10 @@ static int imapc_sync(struct imapc_mailbox *mbox) if (imapc_sync_begin(mbox, &sync_ctx, force) < 0) return -1; + + if (!array_is_empty(&mbox->untagged_fetch_contexts)) + imapc_sync_handle_untagged_fetches(mbox); + if (sync_ctx == NULL) return 0; if (imapc_sync_finish(&sync_ctx) < 0)