aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2017-11-18 23:10:24 +0100
committerNeels Hofmeyr <neels@hofmeyr.de>2017-11-21 02:31:04 +0100
commit3f19ecfcbc6dfdbaa73c8552922361e812ff311a (patch)
tree554c28a0b2d50481872c8bbf15f77d3f3474972a
parent5365c34564a673a108fb85e6f58a4be6944033d9 (diff)
fsm_tmr_cb: don't set T=0, the fi may no longer existneels/sanitize
When calling the timer_cb, that may have effected an fi termination and deallocation, e.g. from dispatching events and/or complex choices made. Current timer_cb implementations expect T to reflect the fired timer number, so we can't actually set T=0 before calling the timer_cb. Instead, never reset T to zero, let it always reflect the timer that last fired. When a new timer starts, T will be set to its new value. Adding a T arg to the timer_cb() would have been the cleanest solution, so that fi->T can be set to zero before dispatching the timer_cb. But since we've already rolled out this FSM API, we should stay backwards compatible. In the case where the timer returned 1 to request termination, we can assume that the fi still exists, but to be consistent, don't set T = 0 in that code path either. Change-Id: I18626b55a1491098b3ed602df1b331f08d25625a
-rw-r--r--src/fsm.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/src/fsm.c b/src/fsm.c
index 827e8b37..0bdcd9d4 100644
--- a/src/fsm.c
+++ b/src/fsm.c
@@ -183,16 +183,17 @@ static void fsm_tmr_cb(void *data)
if (fsm->timer_cb) {
int rc = fsm->timer_cb(fi);
- if (rc != 1) {
- fi->T = 0;
+ if (rc != 1)
+ /* We don't actually know whether fi exists anymore.
+ * Make sure to not access it and return right away. */
return;
- }
+ /* The timer_cb told us to terminate, so we can safely assume
+ * that fi still exists. */
LOGPFSM(fi, "timer_cb requested termination\n");
} else
LOGPFSM(fi, "No timer_cb, automatic termination\n");
/* if timer_cb returns 1 or there is no timer_cb */
- fi->T = 0;
osmo_fsm_inst_term(fi, OSMO_FSM_TERM_TIMEOUT, &T);
}