Recylce a gsm_lchan when the refcount drops to zero
When a channel is allocated, start a timeout, when a lchan_use
is used the timer will be restarted, when the timeout fires
we will try to recycle or restart the timer.
diff --git a/src/chan_alloc.c b/src/chan_alloc.c
index 3ef8b4d..d76c929 100644
--- a/src/chan_alloc.c
+++ b/src/chan_alloc.c
@@ -1,6 +1,7 @@
/* GSM Channel allocation routines
*
* (C) 2008 by Harald Welte <laforge@gnumonks.org>
+ * (C) 2008 by Holger Hans Peter Freyther <zecke@selfish.org>
*
* All Rights Reserved
*
@@ -28,6 +29,9 @@
#include <openbsc/gsm_data.h>
#include <openbsc/chan_alloc.h>
#include <openbsc/abis_nm.h>
+#include <openbsc/debug.h>
+
+static void auto_release_channel(struct gsm_lchan* lchan);
struct gsm_bts_trx_ts *ts_c0_alloc(struct gsm_bts *bts,
enum gsm_phys_chan_config pchan)
@@ -164,8 +168,15 @@
fprintf(stderr, "Unknown gsm_chan_t %u\n", type);
}
- if (lchan)
+ if (lchan) {
lchan->type = type;
+ lchan->use_count = 0;
+
+ /* Configure the time and start it so it will be closed */
+ lchan->release_timer.cb = auto_release_channel;
+ lchan->release_timer.data = lchan;
+ schedule_timer(&lchan->release_timer, LCHAN_RELEASE_TIMEOUT);
+ }
return lchan;
}
@@ -174,6 +185,35 @@
void lchan_free(struct gsm_lchan *lchan)
{
lchan->type = GSM_LCHAN_NONE;
+
+ /* stop the timer */
+ del_timer(&lchan->release_timer);
+
/* FIXME: ts_free() the timeslot, if we're the last logical
* channel using it */
}
+
+/*
+ * Auto release the channel when the use count is zero
+ */
+static void auto_release_channel(struct gsm_lchan* lchan)
+{
+ /*
+ * Busy...
+ */
+ if (lchan->use_count > 0) {
+ schedule_timer(&lchan->release_timer, LCHAN_RELEASE_TIMEOUT);
+ return;
+ }
+
+ /*
+ * spoofed? message
+ */
+ if (lchan->use_count < 0) {
+ DEBUGP(DRLL, "Channel count is negative: %d\n", lchan->use_count);
+ }
+
+ DEBUGP(DRLL, "Recylcing the channel with: %d (%x)\n", lchan->nr, lchan->nr);
+ rsl_chan_release(lchan);
+}
+