diff options
author | Harald Welte <laforge@gnumonks.org> | 2016-06-19 18:06:02 +0200 |
---|---|---|
committer | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2017-03-16 15:32:29 +0100 |
commit | e005619dc6cbfcbd260cab6b2535d10eb0e75c6d (patch) | |
tree | 07075bb26ade2ef8e866ed2b2b818014b363cd81 /openbsc/src/libmsc/osmo_msc.c | |
parent | 7564acac242e6112b70b493b314a74baaca1f6e8 (diff) |
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
Diffstat (limited to 'openbsc/src/libmsc/osmo_msc.c')
-rw-r--r-- | openbsc/src/libmsc/osmo_msc.c | 41 |
1 files changed, 36 insertions, 5 deletions
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); + } +} |