From e005619dc6cbfcbd260cab6b2535d10eb0e75c6d Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sun, 19 Jun 2016 18:06:02 +0200 Subject: Introduce subscriber_connection ref-counting This introduces a reference count for gsm_subscriber_connection. Every user of the connection needs to hold a reference until done. Once the reference count dorps to zero, the connection is cleared towards the BSC (which subsequently will clear any logical channels associated with it). Related: OS#1592 Change-Id: I8c05e6c81f246ff8b5bf91312f80410b1a85f15e --- openbsc/src/libmsc/osmo_msc.c | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) (limited to 'openbsc/src/libmsc/osmo_msc.c') diff --git a/openbsc/src/libmsc/osmo_msc.c b/openbsc/src/libmsc/osmo_msc.c index 2389980d3..92bc84650 100644 --- a/openbsc/src/libmsc/osmo_msc.c +++ b/openbsc/src/libmsc/osmo_msc.c @@ -144,22 +144,21 @@ struct bsc_api *msc_bsc_api() { } /* lchan release handling */ -void msc_release_connection(struct gsm_subscriber_connection *conn) +static void msc_release_connection(struct gsm_subscriber_connection *conn) { /* skip when we are in release, e.g. due an error */ if (conn->in_release) return; - /* skip releasing of silent calls as they have no transaction */ if (conn->silent_call) - return; + LOGP(DMSC, LOGL_ERROR, "release_connection() but silent_call active?!?\n"); /* check if there is a pending operation */ if (conn->loc_operation || conn->sec_operation || conn->anch_operation) - return; + LOGP(DMSC, LOGL_ERROR, "relase_connection() but {loc,sec,anch}_operation alive?!?\n"); if (trans_has_conn(conn)) - return; + LOGP(DMSC, LOGL_ERROR, "release_conncetion() but transactions alive?!?\n"); /* no more connections, asking to release the channel */ @@ -175,3 +174,35 @@ void msc_release_connection(struct gsm_subscriber_connection *conn) gsm0808_clear(conn); msc_subscr_con_free(conn); } + +/* increment the ref-count. Needs to be called by every user */ +struct gsm_subscriber_connection *subscr_con_get(struct gsm_subscriber_connection *conn) +{ + OSMO_ASSERT(conn); + + if (conn->in_release) + return NULL; + + conn->use_count++; + DEBUGP(DMSC, "increased subscr_con use_count to %u\n", conn->use_count); + + return conn; +} + +/* decrement the ref-count. Once it reaches zero, we release */ +void subscr_con_put(struct gsm_subscriber_connection *conn) +{ + OSMO_ASSERT(conn); + + if (conn->use_count == 0) { + LOGP(DMSC, LOGL_ERROR, "tryin to decrement conn use count, but is alrady 0\n"); + return; + } + + conn->use_count--; + DEBUGP(DMSC, "decreased subscr_con use_count to %u\n", conn->use_count); + + if (conn->use_count == 0) { + msc_release_connection(conn); + } +} -- cgit v1.2.3