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".
This commit is contained in:
parent
c313ab0f6b
commit
6d7d7f2cd3
18
src/mncc.c
18
src/mncc.c
|
@ -39,6 +39,12 @@ extern void *tall_mncc_ctx;
|
||||||
|
|
||||||
static void close_connection(struct mncc_connection *conn);
|
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)
|
static void cmd_timeout(void *data)
|
||||||
{
|
{
|
||||||
struct mncc_call_leg *leg = data;
|
struct mncc_call_leg *leg = data;
|
||||||
|
@ -50,7 +56,7 @@ static void cmd_timeout(void *data)
|
||||||
other_leg = call_leg_other(&leg->base);
|
other_leg = call_leg_other(&leg->base);
|
||||||
if (other_leg)
|
if (other_leg)
|
||||||
other_leg->release_call(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)
|
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) {
|
if (leg->conn->state != MNCC_READY) {
|
||||||
LOGP(DMNCC, LOGL_DEBUG,
|
LOGP(DMNCC, LOGL_DEBUG,
|
||||||
"MNCC not connected releasing leg leg(%u)\n", leg->callref);
|
"MNCC not connected releasing leg leg(%u)\n", leg->callref);
|
||||||
return call_leg_release(_leg);
|
return mncc_leg_release(leg);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (leg->state) {
|
switch (leg->state) {
|
||||||
|
@ -207,7 +213,7 @@ static void mncc_call_leg_release(struct call_leg *_leg)
|
||||||
if (leg->dir == MNCC_DIR_MO) {
|
if (leg->dir == MNCC_DIR_MO) {
|
||||||
mncc_send(leg->conn, MNCC_REJ_REQ, leg->callref);
|
mncc_send(leg->conn, MNCC_REJ_REQ, leg->callref);
|
||||||
osmo_timer_del(&leg->cmd_timeout);
|
osmo_timer_del(&leg->cmd_timeout);
|
||||||
call_leg_release(_leg);
|
mncc_leg_release(leg);
|
||||||
} else {
|
} else {
|
||||||
leg->base.in_release = true;
|
leg->base.in_release = true;
|
||||||
start_cmd_timer(leg, MNCC_REL_CNF);
|
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);
|
other_leg->release_call(other_leg);
|
||||||
}
|
}
|
||||||
LOGP(DMNCC, LOGL_DEBUG, "leg(%u) was released.\n", data->callref);
|
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)
|
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);
|
stop_cmd_timer(leg, MNCC_REL_CNF);
|
||||||
LOGP(DMNCC, LOGL_DEBUG, "leg(%u) was cnf released.\n", data->callref);
|
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)
|
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)
|
if (other_leg)
|
||||||
other_leg->release_call(other_leg);
|
other_leg->release_call(other_leg);
|
||||||
LOGP(DMNCC, LOGL_DEBUG, "leg(%u) was rejected.\n", data->callref);
|
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)
|
static void check_cnf_ind(struct mncc_connection *conn, char *buf, int rc)
|
||||||
|
|
Loading…
Reference in New Issue