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