From d4b79c877291e58bf7fafcfd3c771c9e66fa3f5b Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Wed, 6 Mar 2019 05:43:23 +0100 Subject: fsm: add osmo_fsm_inst_state_chg_keep_or_start_timer() During FSM design for osmo-msc, I noticed that the current behavior that keep_timer=true doesn't guarantee a running timer can make FSM design a bit complex, especially when using osmo_tdef for timeout definitions. A desirable keep_timer=true behavior is one that keeps the previous timer running, but starts a timer if no timer is running yet. The simplest example is: a given state repeatedly transitions back to itself, but wants to set a timeout only on first entering, avoiding to restart the timeout on re-entering. Another example is a repeated transition between two or more states, where the first time we enter this group a timeout should start, but it should not restart from scratch on every transition. When using osmo_tdef timeout definitions for this, so far separate meaningless states have to be introduced that merely set a fixed timeout. To simplify, add osmo_fsm_inst_state_chg_keep_or_start_timer(), and use this in osmo_tdef_fsm_inst_state_chg() when both keep_timer == true *and* T != 0. In tdef_test.ok, the changes show that on first entering state L, the previous T=1 is now kept with a large remaining timeout. When entering state L from O, where no timer was running, this time L's T123 is started. Change-Id: Id647511a4b18e0c4de0e66fb1f35dc9adb9177db --- include/osmocom/core/fsm.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include/osmocom/core/fsm.h') diff --git a/include/osmocom/core/fsm.h b/include/osmocom/core/fsm.h index 13bfb331..c40d7f3c 100644 --- a/include/osmocom/core/fsm.h +++ b/include/osmocom/core/fsm.h @@ -254,6 +254,21 @@ int _osmo_fsm_inst_state_chg(struct osmo_fsm_inst *fi, uint32_t new_state, int _osmo_fsm_inst_state_chg_keep_timer(struct osmo_fsm_inst *fi, uint32_t new_state, const char *file, int line); +/*! perform a state change while keeping the current timer if running, or starting a timer otherwise. + * + * This is useful to keep a timeout across several states, but to make sure that some timeout is actually running. + * + * This is a macro that calls _osmo_fsm_inst_state_chg_keep_or_start_timer() with the given + * parameters as well as the caller's source file and line number for logging + * purposes. See there for documentation. + */ +#define osmo_fsm_inst_state_chg_keep_or_start_timer(fi, new_state, timeout_secs, T) \ + _osmo_fsm_inst_state_chg_keep_or_start_timer(fi, new_state, timeout_secs, T, \ + __FILE__, __LINE__) +int _osmo_fsm_inst_state_chg_keep_or_start_timer(struct osmo_fsm_inst *fi, uint32_t new_state, + unsigned long timeout_secs, int T, + const char *file, int line); + /*! dispatch an event to an osmocom finite state machine instance * * This is a macro that calls _osmo_fsm_inst_dispatch() with the given -- cgit v1.2.3