Browse Source

Lib: SMF: fix stuck handled bit when transitioning

If both `smf_set_state()` and `smf_set_handled()` are called in
a run action, the `internal->handled` bit would not be reset.

This could cause an issue on the next run action by not
propagating events to parents.

Signed-off-by: Glenn Andrews <glenn.andrews.42@gmail.com>
pull/74908/head
Glenn Andrews 1 year ago committed by Anas Nashif
parent
commit
87db81e5cd
  1. 24
      lib/smf/smf.c

24
lib/smf/smf.c

@ -139,19 +139,14 @@ static bool smf_execute_ancestor_run_actions(struct smf_ctx *ctx) @@ -139,19 +139,14 @@ static bool smf_execute_ancestor_run_actions(struct smf_ctx *ctx)
struct internal_ctx *const internal = (void *)&ctx->internal;
/* Execute all run actions in reverse order */
/* Return if the current state switched states */
if (internal->new_state) {
internal->new_state = false;
return false;
}
/* Return if the current state terminated */
if (internal->terminate) {
return true;
}
if (internal->handled) {
/* Event was handled by this state. Stop propagating */
/* The child state either transitioned or handled it. Either way, stop propagating. */
if (internal->new_state || internal->handled) {
internal->new_state = false;
internal->handled = false;
return false;
}
@ -169,19 +164,16 @@ static bool smf_execute_ancestor_run_actions(struct smf_ctx *ctx) @@ -169,19 +164,16 @@ static bool smf_execute_ancestor_run_actions(struct smf_ctx *ctx)
return true;
}
if (internal->new_state) {
break;
}
if (internal->handled) {
/* Event was handled by this state. Stop propagating */
internal->handled = false;
/* This state dealt with it. Stop propagating. */
if (internal->new_state || internal->handled) {
break;
}
}
}
internal->new_state = false;
internal->handled = false;
/* All done executing the run actions */
return false;
@ -231,6 +223,8 @@ void smf_set_initial(struct smf_ctx *ctx, const struct smf_state *init_state) @@ -231,6 +223,8 @@ void smf_set_initial(struct smf_ctx *ctx, const struct smf_state *init_state)
internal->is_exit = false;
internal->terminate = false;
internal->handled = false;
internal->new_state = false;
ctx->current = init_state;
ctx->previous = NULL;
ctx->terminate_val = 0;

Loading…
Cancel
Save