aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmsc/osmo_msc.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2016-06-19 18:06:02 +0200
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2017-03-16 15:32:29 +0100
commite005619dc6cbfcbd260cab6b2535d10eb0e75c6d (patch)
tree07075bb26ade2ef8e866ed2b2b818014b363cd81 /openbsc/src/libmsc/osmo_msc.c
parent7564acac242e6112b70b493b314a74baaca1f6e8 (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.c41
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);
+ }
+}