From 6d7d7f2cd317b9c337f675da74c4bc8411cdfced Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 4 Apr 2016 12:36:31 +0200 Subject: [PATCH] mncc: Have all release go through a local method Have all release go through a local method first. This way we can make sure to stop the timer. I have seen something odd (a busy loop in the RB tree of the timer code) and we can easily avoid having a timer run on a page of memory that has been "freed". --- src/mncc.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/mncc.c b/src/mncc.c index 02cda9c..9a6c483 100644 --- a/src/mncc.c +++ b/src/mncc.c @@ -39,6 +39,12 @@ extern void *tall_mncc_ctx; static void close_connection(struct mncc_connection *conn); +static void mncc_leg_release(struct mncc_call_leg *leg) +{ + osmo_timer_del(&leg->cmd_timeout); + call_leg_release(&leg->base); +} + static void cmd_timeout(void *data) { struct mncc_call_leg *leg = data; @@ -50,7 +56,7 @@ static void cmd_timeout(void *data) other_leg = call_leg_other(&leg->base); if (other_leg) other_leg->release_call(other_leg); - call_leg_release(&leg->base); + mncc_leg_release(leg); } static void start_cmd_timer(struct mncc_call_leg *leg, uint32_t expected_next) @@ -197,7 +203,7 @@ static void mncc_call_leg_release(struct call_leg *_leg) if (leg->conn->state != MNCC_READY) { LOGP(DMNCC, LOGL_DEBUG, "MNCC not connected releasing leg leg(%u)\n", leg->callref); - return call_leg_release(_leg); + return mncc_leg_release(leg); } switch (leg->state) { @@ -207,7 +213,7 @@ static void mncc_call_leg_release(struct call_leg *_leg) if (leg->dir == MNCC_DIR_MO) { mncc_send(leg->conn, MNCC_REJ_REQ, leg->callref); osmo_timer_del(&leg->cmd_timeout); - call_leg_release(_leg); + mncc_leg_release(leg); } else { leg->base.in_release = true; start_cmd_timer(leg, MNCC_REL_CNF); @@ -482,7 +488,7 @@ static void check_rel_ind(struct mncc_connection *conn, char *buf, int rc) other_leg->release_call(other_leg); } LOGP(DMNCC, LOGL_DEBUG, "leg(%u) was released.\n", data->callref); - call_leg_release(&leg->base); + mncc_leg_release(leg); } static void check_rel_cnf(struct mncc_connection *conn, char *buf, int rc) @@ -496,7 +502,7 @@ static void check_rel_cnf(struct mncc_connection *conn, char *buf, int rc) stop_cmd_timer(leg, MNCC_REL_CNF); LOGP(DMNCC, LOGL_DEBUG, "leg(%u) was cnf released.\n", data->callref); - call_leg_release(&leg->base); + mncc_leg_release(leg); } static void check_stp_cmpl_ind(struct mncc_connection *conn, char *buf, int rc) @@ -527,7 +533,7 @@ static void check_rej_ind(struct mncc_connection *conn, char *buf, int rc) if (other_leg) other_leg->release_call(other_leg); LOGP(DMNCC, LOGL_DEBUG, "leg(%u) was rejected.\n", data->callref); - call_leg_release(&leg->base); + mncc_leg_release(leg); } static void check_cnf_ind(struct mncc_connection *conn, char *buf, int rc)