fsm_dealloc_test: no need for ST_DESTROYING

A separate ST_DESTROYING state originally helped with certain deallocation
scenarios. But now that fsm.c avoids re-entering osmo_fsm_inst_term() twice and
gracefully handles FSM instance deallocations for termination cascades, it is
actually just as safe without a separate ST_DESTROYING state. ST_DESTROYING was
used to flag deallocation and prevent entering osmo_fsm_inst_term() twice,
which works only in a very limited range of scenarios.

Remove ST_DESTROYING from fsm_dealloc_test.c to show that all tested scenarios
still clean up gracefully.

Change-Id: I05354e6cad9b82ba474fa50ffd41d481b3c697b4
This commit is contained in:
Neels Hofmeyr 2019-03-24 05:43:04 +01:00 committed by Neels Hofmeyr
parent 1f9cc01861
commit d28aa0c2f1
2 changed files with 1522 additions and 1801 deletions

View File

@ -22,7 +22,6 @@ static const struct value_string test_fsm_event_names[] = {
enum state {
ST_ALIVE,
ST_DESTROYING,
};
enum objname {
@ -148,52 +147,19 @@ void alive(struct osmo_fsm_inst *fi, uint32_t event, void *data)
case EV_OTHER_GONE:
if (other_gone(obj, data)) {
/* Something this object depends on is gone, trigger deallocation */
osmo_fsm_inst_state_chg(fi, ST_DESTROYING, 0, 0);
osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, 0);
}
break;
case EV_CHILD_GONE:
if (!child_gone(obj, data)) {
/* All children are gone. Deallocate. */
osmo_fsm_inst_state_chg(fi, ST_DESTROYING, 0, 0);
osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, 0);
}
break;
case EV_DESTROY:
osmo_fsm_inst_state_chg(fi, ST_DESTROYING, 0, 0);
break;
default:
OSMO_ASSERT(false);
}
PUT();
}
void destroying_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
struct obj *obj = fi->priv;
GET();
LOGPFSML(fi, LOGL_DEBUG, "%s() from %s\n", __func__, osmo_fsm_state_name(fi->fsm, prev_state));
osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, 0);
PUT();
}
void destroying(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
struct obj *obj = fi->priv;
GET();
LOGPFSML(fi, LOGL_DEBUG, "%s(%s)\n", __func__, osmo_fsm_event_name(fi->fsm, event));
switch (event) {
case EV_OTHER_GONE:
other_gone(obj, data);
break;
case EV_CHILD_GONE:
child_gone(obj, data);
break;
case EV_DESTROY:
LOGPFSML(fi, LOGL_DEBUG, "already destroying\n");
osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, 0);
break;
default:
@ -214,24 +180,10 @@ static const struct osmo_fsm_state test_fsm_states[] = {
,
.out_state_mask = 0
| S(ST_ALIVE)
| S(ST_DESTROYING)
,
.onenter = alive_onenter,
.action = alive,
},
[ST_DESTROYING] = {
.name = "destroying",
.in_event_mask = 0
| S(EV_CHILD_GONE)
| S(EV_OTHER_GONE)
| S(EV_DESTROY)
,
.out_state_mask = 0
| S(ST_DESTROYING)
,
.onenter = destroying_onenter,
.action = destroying,
},
};
void cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)

File diff suppressed because it is too large Load Diff