]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-index: Refresh caching decisions from cache file once per transaction
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 26 Mar 2020 14:54:03 +0000 (16:54 +0200)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 15 Apr 2020 09:41:42 +0000 (12:41 +0300)
If another process had updated the decisions, mail_cache_field_want_add()
and mail_cache_field_can_add() may have returned obsolete values.

src/lib-index/mail-cache-transaction.c

index 7912f63901533df29ef84ca468d1b1ac9b981898..c48fa3a100284e8176b2f9cefaaad63bc184ef0e 100644 (file)
@@ -48,6 +48,7 @@ struct mail_cache_transaction_ctx {
        unsigned int records_written;
 
        bool tried_compression:1;
+       bool decisions_refreshed:1;
        bool changes:1;
 };
 
@@ -741,6 +742,21 @@ static int mail_cache_header_rewrite_fields(struct mail_cache *cache)
        return ret;
 }
 
+static void
+mail_cache_transaction_refresh_decisions(struct mail_cache_transaction_ctx *ctx)
+{
+       if (ctx->decisions_refreshed)
+               return;
+
+       /* Read latest caching decisions from the cache file's header once
+          per transaction. */
+       if (!ctx->cache->opened)
+               (void)mail_cache_open_and_verify(ctx->cache);
+       else
+               (void)mail_cache_header_fields_read(ctx->cache);
+       ctx->decisions_refreshed = TRUE;
+}
+
 void mail_cache_add(struct mail_cache_transaction_ctx *ctx, uint32_t seq,
                    unsigned int field_idx, const void *data, size_t data_size)
 {
@@ -757,7 +773,7 @@ void mail_cache_add(struct mail_cache_transaction_ctx *ctx, uint32_t seq,
 
        /* If the cache file exists, make sure the caching decisions have been
           read. */
-       mail_cache_transaction_open_if_needed(ctx);
+       mail_cache_transaction_refresh_decisions(ctx);
 
        mail_cache_decision_add(ctx->view, seq, field_idx);
 
@@ -838,7 +854,7 @@ bool mail_cache_field_want_add(struct mail_cache_transaction_ctx *ctx,
 {
        enum mail_cache_decision_type decision;
 
-       mail_cache_transaction_open_if_needed(ctx);
+       mail_cache_transaction_refresh_decisions(ctx);
 
        decision = mail_cache_field_get_decision(ctx->view->cache, field_idx);
        decision &= ~MAIL_CACHE_DECISION_FORCED;
@@ -867,7 +883,7 @@ bool mail_cache_field_can_add(struct mail_cache_transaction_ctx *ctx,
 {
        enum mail_cache_decision_type decision;
 
-       mail_cache_transaction_open_if_needed(ctx);
+       mail_cache_transaction_refresh_decisions(ctx);
 
        decision = mail_cache_field_get_decision(ctx->view->cache, field_idx);
        if (decision == (MAIL_CACHE_DECISION_FORCED | MAIL_CACHE_DECISION_NO))