From 317b1d33ffa3c088856b4e39d80f6feb82f101e2 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Wed, 28 Nov 2007 20:28:21 +0100 Subject: [PATCH] Added untested support for side effects to result object. --- src/lib-sieve/sieve-actions.h | 22 +++++++++ src/lib-sieve/sieve-common.h | 1 + src/lib-sieve/sieve-result.c | 93 +++++++++++++++++++++++++++++++++-- src/lib-sieve/sieve-result.h | 5 ++ 4 files changed, 116 insertions(+), 5 deletions(-) diff --git a/src/lib-sieve/sieve-actions.h b/src/lib-sieve/sieve-actions.h index f7dd0cde9..8371e8009 100644 --- a/src/lib-sieve/sieve-actions.h +++ b/src/lib-sieve/sieve-actions.h @@ -41,6 +41,28 @@ struct sieve_action { const struct sieve_action_exec_env *aenv, void *tr_context, bool success); }; +struct sieve_side_effect { + const char *name; + const struct sieve_action *to_action; + + bool (*pre_execute) + (const struct sieve_side_effect *seffect, const struct sieve_action *action, + const struct sieve_action_exec_env *aenv, void **se_context, + void *tr_context); + bool (*post_execute) + (const struct sieve_side_effect *seffect, const struct sieve_action *action, + const struct sieve_action_exec_env *aenv, void *se_context, + void *tr_context); + bool (*post_commit) + (const struct sieve_side_effect *seffect, const struct sieve_action *action, + const struct sieve_action_exec_env *aenv, void *se_context, + void *tr_context); + void (*rollback) + (const struct sieve_side_effect *seffect, const struct sieve_action *action, + const struct sieve_action_exec_env *aenv, void *se_context, + void *tr_context, bool success); +}; + /* Actions common to multiple commands */ const struct sieve_action act_store; diff --git a/src/lib-sieve/sieve-common.h b/src/lib-sieve/sieve-common.h index cd664b43c..92bba80e7 100644 --- a/src/lib-sieve/sieve-common.h +++ b/src/lib-sieve/sieve-common.h @@ -77,5 +77,6 @@ struct sieve_result; /* sieve-actions.h */ struct sieve_action_exec_env; struct sieve_action; +struct sieve_side_effect; #endif /* __SIEVE_COMMON_H */ diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c index 369cdc356..2e1dabadc 100644 --- a/src/lib-sieve/sieve-result.c +++ b/src/lib-sieve/sieve-result.c @@ -9,11 +9,21 @@ #include <stdio.h> struct sieve_result_action { + struct sieve_result *result; const struct sieve_action *action; void *context; void *tr_context; bool success; struct sieve_result_action *prev, *next; + + struct sieve_result_side_effect *first_effect; + struct sieve_result_side_effect *last_effect; +}; + +struct sieve_result_side_effect { + const struct sieve_side_effect *seffect; + void *context; + struct sieve_result_side_effect *prev, *next; }; struct sieve_result { @@ -104,6 +114,7 @@ bool sieve_result_add_action /* Create new action object */ raction = p_new(result->pool, struct sieve_result_action, 1); + raction->result = result; raction->action = action; raction->context = context; raction->tr_context = NULL; @@ -125,6 +136,33 @@ bool sieve_result_add_action return TRUE; } +bool sieve_result_add_side_effect +(struct sieve_result_action *raction, const struct sieve_side_effect *seffect, + void *context) +{ + struct sieve_result_side_effect *reffect; + + /* Create new action object */ + reffect = p_new(raction->result->pool, struct sieve_result_side_effect, 1); + reffect->seffect = seffect; + reffect->context = context; + + /* Add */ + if ( raction->first_effect == NULL ) { + raction->first_effect = reffect; + raction->last_effect = reffect; + reffect->prev = NULL; + reffect->next = NULL; + } else { + raction->last_effect->next = reffect; + reffect->prev = raction->last_effect; + raction->last_effect = reffect; + reffect->next = NULL; + } + + return TRUE; +} + bool sieve_result_print(struct sieve_result *result) { struct sieve_result_action *rac = result->first_action; @@ -154,7 +192,6 @@ bool sieve_result_execute struct sieve_result_action *rac; struct sieve_result_action *last_attempted; - result->action_env.msgdata = msgdata; result->action_env.mailenv = menv; @@ -182,14 +219,37 @@ bool sieve_result_execute rac = result->first_action; while ( success && rac != NULL ) { const struct sieve_action *act = rac->action; + struct sieve_result_side_effect *rsef; + const struct sieve_side_effect *sef; + void *context = rac->tr_context == NULL ? + rac->context : rac->tr_context; + + /* Execute pre-execute event of side effects */ + rsef = rac->first_effect; + while ( rsef != NULL ) { + sef = rsef->seffect; + if ( sef->pre_execute != NULL ) + sef->pre_execute + (sef, act, &result->action_env, &rsef->context, context); + rsef = rsef->next; + } + /* Execute the action itself */ if ( act->execute != NULL ) { - void *context = rac->tr_context == NULL ? - rac->context : rac->tr_context; - rac->success = act->execute(act, &result->action_env, context); success = success && rac->success; - } + } + + /* Execute pre-execute event of side effects */ + rsef = rac->first_effect; + while ( rsef != NULL ) { + sef = rsef->seffect; + if ( sef->post_execute != NULL ) + sef->post_execute + (sef, act, &result->action_env, rsef->context, context); + rsef = rsef->next; + } + rac = rac->next; } @@ -203,15 +263,38 @@ bool sieve_result_execute rac = result->first_action; while ( rac != NULL && rac != last_attempted ) { const struct sieve_action *act = rac->action; + struct sieve_result_side_effect *rsef; + const struct sieve_side_effect *sef; void *context = rac->tr_context == NULL ? rac->context : rac->tr_context; if ( success ) { if ( act->commit != NULL ) commit_ok = act->commit(act, &result->action_env, context) && commit_ok; + + /* Execute post_commit event of side effects */ + rsef = rac->first_effect; + while ( rsef != NULL ) { + sef = rsef->seffect; + if ( sef->post_commit != NULL ) + sef->post_commit + (sef, act, &result->action_env, rsef->context, context); + rsef = rsef->next; + } } else { if ( act->rollback != NULL ) act->rollback(act, &result->action_env, context, rac->success); + + /* Rollback side effects */ + rsef = rac->first_effect; + while ( rsef != NULL ) { + sef = rsef->seffect; + if ( sef->rollback != NULL ) + sef->rollback + (sef, act, &result->action_env, rsef->context, context, + rac->success); + rsef = rsef->next; + } } rac = rac->next; } diff --git a/src/lib-sieve/sieve-result.h b/src/lib-sieve/sieve-result.h index 46c01a04c..f32266846 100644 --- a/src/lib-sieve/sieve-result.h +++ b/src/lib-sieve/sieve-result.h @@ -5,6 +5,8 @@ struct sieve_result; +struct sieve_result_action; + struct sieve_result *sieve_result_create(void); void sieve_result_ref(struct sieve_result *result); void sieve_result_unref(struct sieve_result **result); @@ -13,6 +15,9 @@ inline pool_t sieve_result_pool(struct sieve_result *result); bool sieve_result_add_action (const struct sieve_runtime_env *renv, const struct sieve_action *action, void *context); +bool sieve_result_add_side_effect +(struct sieve_result_action *raction, const struct sieve_side_effect *seffect, + void *context); bool sieve_result_print(struct sieve_result *result); -- GitLab