dovecot-2.2-pigeonhole: lib-sieve: Restructured result execution...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Fri Oct 17 18:50:14 UTC 2014


details:   http://hg.rename-it.nl/dovecot-2.2-pigeonhole/rev/a856f89b54ca
changeset: 1924:a856f89b54ca
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Fri Oct 17 20:49:57 2014 +0200
description:
lib-sieve: Restructured result execution, so that all actions which involve mail storage are always committed before all others.

diffstat:

 src/lib-sieve/sieve-actions.c |    4 +-
 src/lib-sieve/sieve-actions.h |    3 +-
 src/lib-sieve/sieve-result.c  |  338 ++++++++++++++++++++++++++---------------
 3 files changed, 221 insertions(+), 124 deletions(-)

diffs (truncated from 425 to 300 lines):

diff -r aaf7f0f48b99 -r a856f89b54ca src/lib-sieve/sieve-actions.c
--- a/src/lib-sieve/sieve-actions.c	Wed Oct 15 00:23:55 2014 +0200
+++ b/src/lib-sieve/sieve-actions.c	Fri Oct 17 20:49:57 2014 +0200
@@ -207,7 +207,9 @@
 
 const struct sieve_action_def act_store = {
 	.name = "store",
-	.flags = SIEVE_ACTFLAG_TRIES_DELIVER,
+	.flags =
+		SIEVE_ACTFLAG_TRIES_DELIVER | 
+		SIEVE_ACTFLAG_MAIL_STORAGE,
 	.equals = act_store_equals,
 	.check_duplicate = act_store_check_duplicate,
 	.print = act_store_print,
diff -r aaf7f0f48b99 -r a856f89b54ca src/lib-sieve/sieve-actions.h
--- a/src/lib-sieve/sieve-actions.h	Wed Oct 15 00:23:55 2014 +0200
+++ b/src/lib-sieve/sieve-actions.h	Fri Oct 17 20:49:57 2014 +0200
@@ -36,7 +36,8 @@
 
 enum sieve_action_flags {
 	SIEVE_ACTFLAG_TRIES_DELIVER = (1 << 0),
-	SIEVE_ACTFLAG_SENDS_RESPONSE = (1 << 1)
+	SIEVE_ACTFLAG_SENDS_RESPONSE = (1 << 1),
+	SIEVE_ACTFLAG_MAIL_STORAGE = (1 << 2)
 };
 
 /*
diff -r aaf7f0f48b99 -r a856f89b54ca src/lib-sieve/sieve-result.c
--- a/src/lib-sieve/sieve-result.c	Wed Oct 15 00:23:55 2014 +0200
+++ b/src/lib-sieve/sieve-result.c	Fri Oct 17 20:49:57 2014 +0200
@@ -1067,32 +1067,13 @@
 	return result->executed;
 }
 
-int sieve_result_execute
-(struct sieve_result *result, bool *keep)
+static int sieve_result_transaction_start
+(struct sieve_result *result, struct sieve_result_action *first,
+	struct sieve_result_action **last_r)
 {
-	bool implicit_keep = TRUE, executed = result->executed;
-	int status = SIEVE_EXEC_OK, commit_status, result_status;
-	struct sieve_result_action *rac, *first_action;
-	struct sieve_result_action *last_attempted;
-	int ret;
+	struct sieve_result_action *rac = first;
+	int status = SIEVE_EXEC_OK;
 
-	if ( keep != NULL ) *keep = FALSE;
-
-	/* Prepare environment */
-
-	_sieve_result_prepare_execution(result);
-
-	/* Make notice of this attempt */
-
-	first_action = ( result->last_attempted_action == NULL ?
-		result->first_action : result->last_attempted_action->next );
-	result->last_attempted_action = result->last_action;
-
-	/*
-	 * Transaction start
-	 */
-
-	rac = first_action;
 	while ( status == SIEVE_EXEC_OK && rac != NULL ) {
 		struct sieve_action *act = &rac->action;
 
@@ -1111,12 +1092,16 @@
 		rac = rac->next;
 	}
 
-	/*
-	 * Transaction execute
-	 */
+	*last_r = rac;
+	return status;
+}
 
-	last_attempted = rac;
-	rac = first_action;
+static int sieve_result_transaction_execute
+(struct sieve_result *result, struct sieve_result_action *first)
+{
+	struct sieve_result_action *rac = first;
+	int status = SIEVE_EXEC_OK;
+
 	while ( status == SIEVE_EXEC_OK && rac != NULL ) {
 		struct sieve_action *act = &rac->action;
 		struct sieve_result_side_effect *rsef;
@@ -1159,118 +1144,158 @@
 		rac = rac->next;
 	}
 
-	/*
-	 * Transaction commit/rollback
-	 */
+	return status;
+}
 
-	commit_status = status;
-	rac = first_action;
-	while ( rac != NULL && rac != last_attempted ) {
-		struct sieve_action *act = &rac->action;
-		struct sieve_result_side_effect *rsef;
-		struct sieve_side_effect *sef;
+static int sieve_result_action_commit
+(struct sieve_result *result, struct sieve_result_action *rac,
+	bool *impl_keep)
+{
+	struct sieve_action *act = &rac->action;
+	struct sieve_result_side_effect *rsef;
+	int cstatus = SIEVE_EXEC_OK;
 
-		if ( status == SIEVE_EXEC_OK ) {
-			bool impl_keep = TRUE;
-			int cstatus = SIEVE_EXEC_OK;
+	if ( act->def->commit != NULL ) {
+		cstatus = act->def->commit
+			(act, &result->action_env, rac->tr_context, impl_keep);
+		if ( cstatus == SIEVE_EXEC_OK ) {
+			act->executed = TRUE;
+			result->executed = TRUE;
+		}
+	}
 
-			if ( rac->keep && keep != NULL ) *keep = TRUE;
+	if ( cstatus == SIEVE_EXEC_OK ) {
+		/* Execute post_commit event of side effects */
+		rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL;
+		while ( rsef != NULL ) {
+			struct sieve_side_effect *sef = &rsef->seffect;
+			if ( sef->def->post_commit != NULL )
+				sef->def->post_commit
+					(sef, act, &result->action_env, rac->tr_context, impl_keep);
+			rsef = rsef->next;
+		}
+	}
 
-			/* Skip non-actions (inactive keep) and executed ones */
-			if ( act->def == NULL || act->executed ) {
-				rac = rac->next;
-				continue;
-			}
+	return cstatus;
+}
 
-			if ( act->def->commit != NULL ) {
-				cstatus = act->def->commit
-					(act, &result->action_env, rac->tr_context, &impl_keep);
-				if ( cstatus == SIEVE_EXEC_OK ) {
-					act->executed = TRUE;
-					result->executed = TRUE;
-					executed = TRUE;
-				} else {
-					/* This is bad; try to salvage as much as possible */
-					if (commit_status == SIEVE_EXEC_OK) {
-						commit_status = cstatus;
-						if (!executed) {
-							/* We haven't executed anything yet; continue as rollback */
-							status = cstatus;
-						}
-					}
-					impl_keep = TRUE;
+static void sieve_result_action_rollback
+(struct sieve_result *result, struct sieve_result_action *rac)
+{
+	struct sieve_action *act = &rac->action;
+	struct sieve_result_side_effect *rsef;
+
+	if ( act->def->rollback != NULL ) {
+		act->def->rollback
+			(act, &result->action_env, rac->tr_context, rac->success);
+	}
+
+	/* Rollback side effects */
+	rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL;
+	while ( rsef != NULL ) {
+		struct sieve_side_effect *sef = &rsef->seffect;
+		if ( sef->def && sef->def->rollback != NULL )
+			sef->def->rollback
+				(sef, act, &result->action_env, rac->tr_context, rac->success);
+		rsef = rsef->next;
+	}
+}
+
+static int sieve_result_action_commit_or_rollback
+(struct sieve_result *result, struct sieve_result_action *rac,
+	int status, bool *implicit_keep, bool *keep, int *commit_status)
+{
+	struct sieve_action *act = &rac->action;
+
+	if ( status == SIEVE_EXEC_OK ) {
+		bool impl_keep = TRUE;
+		int cstatus = SIEVE_EXEC_OK;
+
+		if ( rac->keep && keep != NULL ) *keep = TRUE;
+
+		/* Skip non-actions (inactive keep) and executed ones */
+		if ( act->def == NULL || act->executed )
+			return status;
+
+		cstatus = sieve_result_action_commit(result, rac, &impl_keep);
+		if (cstatus != SIEVE_EXEC_OK) {
+			/* This is bad; try to salvage as much as possible */
+			if (*commit_status == SIEVE_EXEC_OK) {
+				*commit_status = cstatus;
+				if (!result->executed) {
+					/* We haven't executed anything yet; continue as rollback */
+					status = cstatus;
 				}
 			}
+			impl_keep = TRUE;
+		}
 
-			if ( cstatus == SIEVE_EXEC_OK ) {
-				/* Execute post_commit event of side effects */
-				rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL;
-				while ( rsef != NULL ) {
-					sef = &rsef->seffect;
-					if ( sef->def->post_commit != NULL )
-						sef->def->post_commit
-							(sef, act, &result->action_env, rac->tr_context, &impl_keep);
-					rsef = rsef->next;
-				}
-			}
+		*implicit_keep = *implicit_keep && impl_keep;
+	} else {
+		/* Skip non-actions (inactive keep) and executed ones */
+		if ( act->def == NULL || act->executed )
+			return status;
 
-			implicit_keep = implicit_keep && impl_keep;
-		} else {
-			/* Skip non-actions (inactive keep) and executed ones */
-			if ( act->def == NULL || act->executed ) {
-				rac = rac->next;
-				continue;
-			}
+		sieve_result_action_rollback(result, rac);
+	}
 
-			if ( act->def->rollback != NULL ) {
-				act->def->rollback
-					(act, &result->action_env, rac->tr_context, rac->success);
-			}
+	return status;
+}
 
-			/* Rollback side effects */
-			rsef = rac->seffects != NULL ? rac->seffects->first_effect : NULL;
-			while ( rsef != NULL ) {
-				sef = &rsef->seffect;
-				if ( sef->def && sef->def->rollback != NULL )
-					sef->def->rollback
-						(sef, act, &result->action_env, rac->tr_context, rac->success);
-				rsef = rsef->next;
-			}
+static int sieve_result_transaction_commit_or_rollback
+(struct sieve_result *result, int status,
+	struct sieve_result_action *first,
+	struct sieve_result_action *last,
+	bool *implicit_keep, bool *keep)
+{
+	struct sieve_result_action *rac;
+	int commit_status = status;
+
+	/* First commit/rollback all storage actions */
+	rac = first;
+	while ( rac != NULL && rac != last ) {
+		struct sieve_action *act = &rac->action;
+
+		if (act->def == NULL ||
+			(act->def->flags & SIEVE_ACTFLAG_MAIL_STORAGE) == 0) {
+			rac = rac->next;
+			continue;
 		}
 
+		status = sieve_result_action_commit_or_rollback
+			(result, rac, status, implicit_keep, keep, &commit_status);
+
 		rac = rac->next;
 	}
 
-	if ( implicit_keep && keep != NULL ) *keep = TRUE;
+	/* Then commit/rollback all other actions */
+	rac = first;
+	while ( rac != NULL && rac != last ) {
+		struct sieve_action *act = &rac->action;
 
-	/* Perform implicit keep if necessary */
+		if (act->def != NULL &&
+			(act->def->flags & SIEVE_ACTFLAG_MAIL_STORAGE) != 0) {
+			rac = rac->next;
+			continue;
+		}
 
-	result_status = commit_status;
-	if ( executed || commit_status != SIEVE_EXEC_TEMP_FAILURE ) {
-		/* Execute implicit keep if the transaction failed or when the implicit


More information about the dovecot-cvs mailing list