From d1bdfae6fb5a2c9db99a1b8af25f51ad2b9bca5e Mon Sep 17 00:00:00 2001
From: Anthony Minessale <anthony.minessale@gmail.com>
Date: Wed, 24 Jun 2009 16:18:41 +0000
Subject: [PATCH] make the in_use count be a function instead of a constant to
 fix race

git-svn-id: http://svn.openzap.org/svn/openzap/trunk@750 a93c3328-9c30-0410-af19-c9cd2b2d52af
---
 libs/openzap/src/include/openzap.h            |  2 +-
 .../ozmod/ozmod_ss7_boost/ozmod_ss7_boost.c   |  5 ++-
 libs/openzap/src/zap_io.c                     | 33 ++++++++++++++-----
 3 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/libs/openzap/src/include/openzap.h b/libs/openzap/src/include/openzap.h
index 4c14ef845d..fd71e876e1 100644
--- a/libs/openzap/src/include/openzap.h
+++ b/libs/openzap/src/include/openzap.h
@@ -536,7 +536,6 @@ struct zap_span {
 	char *name;
 	uint32_t span_id;
 	uint32_t chan_count;
-	uint32_t active_count;
 	zap_span_flag_t flags;
 	struct zap_io_interface *zio;
 	zio_event_cb_t event_callback;
@@ -639,6 +638,7 @@ OZ_DECLARE(zap_status_t) zap_span_set_event_callback(zap_span_t *span, zio_event
 OZ_DECLARE(zap_status_t) zap_channel_set_event_callback(zap_channel_t *zchan, zio_event_cb_t event_callback);
 OZ_DECLARE(zap_status_t) zap_channel_open(uint32_t span_id, uint32_t chan_id, zap_channel_t **zchan);
 OZ_DECLARE(zap_status_t) zap_channel_open_chan(zap_channel_t *zchan);
+OZ_DECLARE(zap_status_t) zap_span_channel_use_count(zap_span_t *span, uint32_t *count);
 OZ_DECLARE(zap_status_t) zap_channel_open_any(uint32_t span_id, zap_direction_t direction, zap_caller_data_t *caller_data, zap_channel_t **zchan);
 OZ_DECLARE(zap_status_t) zap_channel_close(zap_channel_t **zchan);
 OZ_DECLARE(zap_status_t) zap_channel_done(zap_channel_t *zchan);
diff --git a/libs/openzap/src/ozmod/ozmod_ss7_boost/ozmod_ss7_boost.c b/libs/openzap/src/ozmod/ozmod_ss7_boost/ozmod_ss7_boost.c
index 7d141804bc..462615f74c 100644
--- a/libs/openzap/src/ozmod/ozmod_ss7_boost/ozmod_ss7_boost.c
+++ b/libs/openzap/src/ozmod/ozmod_ss7_boost/ozmod_ss7_boost.c
@@ -240,6 +240,7 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(ss7_boost_channel_request)
 	ss7_boost_request_status_t st;
 	char ani[128] = "";
 	char *gr = NULL;
+	uint32_t count = 0;
 
 	if (zap_test_flag(span, ZAP_SPAN_SUSPENDED)) {
 		zap_log(ZAP_LOG_CRIT, "SPAN is not online.\n");
@@ -247,7 +248,9 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(ss7_boost_channel_request)
 		return ZAP_FAIL;
 	}
 
-	if (span->active_count >= span->chan_count) {
+	zap_span_channel_use_count(span, &count);
+
+	if (count >= span->chan_count) {
 		zap_log(ZAP_LOG_CRIT, "All circuits are busy.\n");
 		*zchan = NULL;
 		return ZAP_FAIL;
diff --git a/libs/openzap/src/zap_io.c b/libs/openzap/src/zap_io.c
index aea2ae3e42..8e5b9381c6 100644
--- a/libs/openzap/src/zap_io.c
+++ b/libs/openzap/src/zap_io.c
@@ -887,12 +887,6 @@ OZ_DECLARE(zap_status_t) zap_channel_set_state(zap_channel_t *zchan, zap_channel
 	
 
 	if (ok) {
-		if (zchan->state == ZAP_CHANNEL_STATE_DOWN) {
-			zchan->span->active_count++;
-		} else if (state == ZAP_CHANNEL_STATE_DOWN) {
-			zchan->span->active_count--;
-		}
-
 		zap_set_flag(zchan, ZAP_CHANNEL_STATE_CHANGE);	
 		zap_set_flag_locked(zchan->span, ZAP_SPAN_STATE_CHANGE);	
 		zchan->last_state = zchan->state; 
@@ -906,11 +900,32 @@ OZ_DECLARE(zap_status_t) zap_channel_set_state(zap_channel_t *zchan, zap_channel
 	return ok ? ZAP_SUCCESS : ZAP_FAIL;
 }
 
+OZ_DECLARE(zap_status_t) zap_span_channel_use_count(zap_span_t *span, uint32_t *count)
+{
+	uint32_t j;
+
+	*count = 0;
+	
+	if (!span || !zap_test_flag(span, ZAP_SPAN_CONFIGURED)) {
+		return ZAP_FAIL;
+	}
+	
+	for(j = 1; j <= span->chan_count && span->channels[j]; j++) {
+		if (span->channels[j]) {
+			if (zap_test_flag(span->channels[j], ZAP_CHANNEL_INUSE)) {
+				(*count)++;
+			}
+		}
+	}
+	
+	return ZAP_SUCCESS;
+}
+
 OZ_DECLARE(zap_status_t) zap_channel_open_any(uint32_t span_id, zap_direction_t direction, zap_caller_data_t *caller_data, zap_channel_t **zchan)
 {
 	zap_status_t status = ZAP_FAIL;
 	zap_channel_t *check;
-	uint32_t i,j;
+	uint32_t i, j, count;
 	zap_span_t *span = NULL;
 	uint32_t span_max;
 
@@ -923,7 +938,9 @@ OZ_DECLARE(zap_status_t) zap_channel_open_any(uint32_t span_id, zap_direction_t
             return ZAP_FAIL;
 		}
 
-		if (span->active_count >= span->chan_count) {
+		zap_span_channel_use_count(span, &count);
+
+		if (count >= span->chan_count) {
 			zap_log(ZAP_LOG_CRIT, "All circuits are busy.\n");
 			*zchan = NULL;
 			return ZAP_FAIL;