From f898a54a43ad7b2c0507d13649fc96cee7959fd8 Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan@rename-it.nl>
Date: Thu, 20 Nov 2014 01:04:00 +0100
Subject: [PATCH] lib-sieve: Flush duplicate database during start phase of
 result execution rather than commit phase. This will release the duplicate
 database lock earlier, even before a mail storage transation is started.

---
 src/lib-sieve/sieve-result.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c
index feb93478f..1efd9a63b 100644
--- a/src/lib-sieve/sieve-result.c
+++ b/src/lib-sieve/sieve-result.c
@@ -1106,8 +1106,10 @@ static int sieve_result_transaction_start
 (struct sieve_result *result, struct sieve_result_action *first,
 	struct sieve_result_action **last_r)
 {
+	const struct sieve_script_env *senv = result->action_env.scriptenv;
 	struct sieve_result_action *rac = first;
 	int status = SIEVE_EXEC_OK;
+	bool dup_flushed = FALSE;
 
 	while ( status == SIEVE_EXEC_OK && rac != NULL ) {
 		struct sieve_action *act = &rac->action;
@@ -1118,6 +1120,12 @@ static int sieve_result_transaction_start
 			continue;
 		}
 
+		if ((act->def->flags & SIEVE_ACTFLAG_MAIL_STORAGE) != 0 &&
+			!dup_flushed) {
+			sieve_action_duplicate_flush(senv);
+			dup_flushed = TRUE;
+		}
+
 		if ( act->def->start != NULL ) {
 			status = act->def->start
 				(act, &result->action_env, &rac->tr_context);
@@ -1283,10 +1291,8 @@ static int sieve_result_transaction_commit_or_rollback
 	struct sieve_result_action *last,
 	bool *implicit_keep, bool *keep)
 {
-	const struct sieve_script_env *senv = result->action_env.scriptenv;
 	struct sieve_result_action *rac;
 	int commit_status = status;
-	bool dup_flushed = FALSE;
 
 	/* First commit/rollback all storage actions */
 	rac = first;
@@ -1299,11 +1305,6 @@ static int sieve_result_transaction_commit_or_rollback
 			continue;
 		}
 
-		if (!dup_flushed) {
-			sieve_action_duplicate_flush(senv);
-			dup_flushed = TRUE;
-		}
-
 		status = sieve_result_action_commit_or_rollback
 			(result, rac, status, implicit_keep, keep, &commit_status);
 
-- 
GitLab