[asterisk-commits] branch group/sip-threading r26530 - in /team/group/sip-threading: channels/ c...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Wed May 10 08:39:02 MST 2006


Author: file
Date: Wed May 10 10:39:02 2006
New Revision: 26530

URL: http://svn.digium.com/view/asterisk?rev=26530&view=rev
Log:
Some more optimizations, plus allow the thread count to be configured in sip.conf

Modified:
    team/group/sip-threading/channels/chan_sip.c
    team/group/sip-threading/configs/sip.conf.sample

Modified: team/group/sip-threading/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/group/sip-threading/channels/chan_sip.c?rev=26530&r1=26529&r2=26530&view=diff
==============================================================================
--- team/group/sip-threading/channels/chan_sip.c (original)
+++ team/group/sip-threading/channels/chan_sip.c Wed May 10 10:39:02 2006
@@ -837,7 +837,7 @@
 	struct sip_registry *registry;		/*!< If this is a REGISTER dialog, to which registry */
 	struct ast_rtp *rtp;			/*!< RTP Session */
 	struct ast_rtp *vrtp;			/*!< Video RTP session */
-	struct sip_pkt *packets;		/*!< Packets scheduled for re-transmission */
+	AST_LIST_HEAD_NOLOCK(, sip_pkt) packets;/*!< Packets scheduled for re-transmission */
 	struct sip_history_head *history;	/*!< History of this SIP dialog */
 	struct ast_variable *chanvars;		/*!< Channel variables to set for inbound call */
 	AST_LIST_ENTRY(sip_pvt) entry;			/*!< Next dialog in chain */
@@ -851,7 +851,6 @@
 
 /*! \brief sip packet - raw format for outbound packets that are sent or scheduled for transmission */
 struct sip_pkt {
-	struct sip_pkt *next;			/*!< Next packet in linked list */
 	int retrans;				/*!< Retransmission number */
 	int method;				/*!< SIP method for this packet */
 	int seqno;				/*!< Sequence number */
@@ -861,6 +860,7 @@
 	int timer_a;				/*!< SIP timer A, retransmission timer */
 	int timer_t1;				/*!< SIP Timer T1, estimated RTT or 500 ms */
 	int packetlen;				/*!< Length of packet */
+	AST_LIST_ENTRY(sip_pkt) list;
 	char data[0];
 };	
 
@@ -881,6 +881,7 @@
 
 /* Maximum thread count */
 static int sipmaxthreads = 10;
+static int sipthreadsstarted = 0;
 
 /*! \brief Structure for SIP user data. User's place calls to us */
 struct sip_user {
@@ -1403,7 +1404,7 @@
 /*! \brief Retransmit SIP message if no answer */
 static int retrans_pkt(void *data)
 {
-	struct sip_pkt *pkt = data, *prev, *cur = NULL;
+	struct sip_pkt *pkt = data;
 	char iabuf[INET_ADDRSTRLEN];
 	int reschedule = DEFAULT_RETRANS;
 
@@ -1476,23 +1477,13 @@
 			ast_set_flag(&pkt->owner->flags[0], SIP_NEEDDESTROY);	
 		}
 	}
-	/* In any case, go ahead and remove the packet */
-	for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) {
-		if (cur == pkt)
-			break;
-	}
-	if (cur) {
-		if (prev)
-			prev->next = cur->next;
-		else
-			pkt->owner->packets = cur->next;
-		ast_mutex_unlock(&pkt->owner->lock);
-		free(cur);
-		pkt = NULL;
-	} else
-		ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n");
-	if (pkt)
-		ast_mutex_unlock(&pkt->owner->lock);
+
+	/* Remove it from the list */
+	AST_LIST_REMOVE(&pkt->owner->packets, pkt, list);
+
+	ast_mutex_unlock(&pkt->owner->lock);
+	free(pkt);
+
 	return 0;
 }
 
@@ -1501,7 +1492,7 @@
 */
 static int __sip_reliable_xmit(struct sip_pvt *p, int seqno, int resp, char *data, int len, int fatal, int sipmethod)
 {
-	struct sip_pkt *pkt;
+	struct sip_pkt *pkt = NULL;
 	int siptimer_a = DEFAULT_RETRANS;
 
 	if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1)))
@@ -1509,7 +1500,6 @@
 	memcpy(pkt->data, data, len);
 	pkt->method = sipmethod;
 	pkt->packetlen = len;
-	pkt->next = p->packets;
 	pkt->owner = p;
 	pkt->seqno = seqno;
 	pkt->flags = resp;
@@ -1524,8 +1514,8 @@
 	pkt->retransid = ast_sched_add_variable(sched, siptimer_a, retrans_pkt, pkt, 1);
 	if (option_debug > 3 && sipdebug)
 		ast_log(LOG_DEBUG, "*** SIP TIMER: Initalizing retransmit timer on packet: Id  #%d\n", pkt->retransid);
-	pkt->next = p->packets;
-	p->packets = pkt;
+
+	AST_LIST_INSERT_HEAD(&p->packets, pkt, list);
 
 	__sip_xmit(pkt->owner, pkt->data, pkt->packetlen);	/* Send packet */
 	if (sipmethod == SIP_INVITE) {
@@ -1594,7 +1584,7 @@
 /*! \brief Acknowledges receipt of a packet and stops retransmission */
 static int __sip_ack(struct sip_pvt *p, int seqno, int resp, int sipmethod, int reset)
 {
-	struct sip_pkt *cur, *prev = NULL;
+	struct sip_pkt *cur = NULL;
 	int res = -1;
 
 	/* Just in case... */
@@ -1603,7 +1593,7 @@
 	msg = sip_methods[sipmethod].text;
 
 	ast_mutex_lock(&p->lock);
-	for (cur = p->packets; cur; prev = cur, cur = cur->next) {
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&p->packets, cur, list) {
 		if ((cur->seqno == seqno) && ((ast_test_flag(cur, FLAG_RESPONSE)) == resp) &&
 			((ast_test_flag(cur, FLAG_RESPONSE)) || 
 			 (!strncasecmp(msg, cur->data, strlen(msg)) && (cur->data[strlen(msg)] < 33)))) {
@@ -1611,11 +1601,7 @@
 				ast_log(LOG_DEBUG, "Acked pending invite %d\n", p->pendinginvite);
 				p->pendinginvite = 0;
 			}
-			/* this is our baby */
-			if (prev)
-				prev->next = cur->next;
-			else
-				p->packets = cur->next;
+			AST_LIST_REMOVE_CURRENT(&p->packets, list);
 			if (cur->retransid > -1) {
 				if (sipdebug && option_debug > 3)
 					ast_log(LOG_DEBUG, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
@@ -1627,8 +1613,11 @@
 			break;
 		}
 	}
+	AST_LIST_TRAVERSE_SAFE_END
 	ast_mutex_unlock(&p->lock);
+
 	if (option_debug)
+
 		ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found");
 	return res;
 }
@@ -1638,22 +1627,22 @@
 {
 	struct sip_pkt *cur = NULL;
 
-	while (p->packets) {
-		if (cur == p->packets) {
+	while (!AST_LIST_EMPTY(&p->packets)) {
+		if (cur == AST_LIST_FIRST(&p->packets)) {
 			ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
 			return -1;
 		}
-		cur = p->packets;
+		cur = AST_LIST_FIRST(&p->packets);
 		if (cur->method)
-			__sip_ack(p, p->packets->seqno, (ast_test_flag(p->packets, FLAG_RESPONSE)), cur->method, FALSE);
+			__sip_ack(p, cur->seqno, (ast_test_flag(cur, FLAG_RESPONSE)), cur->method, FALSE);
 		else {	/* Unknown packet type */
 			char *c;
 			char method[128];
 
-			ast_copy_string(method, p->packets->data, sizeof(method));
+			ast_copy_string(method, cur->data, sizeof(method));
 			c = ast_skip_blanks(method); /* XXX what ? */
 			*c = '\0';
-			__sip_ack(p, p->packets->seqno, (ast_test_flag(p->packets, FLAG_RESPONSE)), find_sip_method(method), FALSE);
+			__sip_ack(p, cur->seqno, (ast_test_flag(cur, FLAG_RESPONSE)), find_sip_method(method), FALSE);
 		}
 	}
 	return 0;
@@ -1662,10 +1651,10 @@
 /*! \brief Acks receipt of packet, keep it around (used for provisional responses) */
 static int __sip_semi_ack(struct sip_pvt *p, int seqno, int resp, int sipmethod)
 {
-	struct sip_pkt *cur;
+	struct sip_pkt *cur = NULL;
 	int res = -1;
 
-	for (cur = p->packets; cur; cur = cur->next) {
+	AST_LIST_TRAVERSE(&p->packets, cur, list) {
 		if (cur->seqno == seqno && ast_test_flag(cur, FLAG_RESPONSE) == resp &&
 			(ast_test_flag(cur, FLAG_RESPONSE) || method_match(sipmethod, cur->data))) {
 			/* this is our baby */
@@ -1679,8 +1668,10 @@
 			break;
 		}
 	}
+
 	if (option_debug)
 		ast_log(LOG_DEBUG, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found");
+
 	return res;
 }
 
@@ -2395,12 +2386,12 @@
 		ast_sched_del(sched, p->initid);
 
 	/* remove all current packets in this dialog */
-	while((cp = p->packets)) {
-		p->packets = p->packets->next;
+	while ((cp = AST_LIST_REMOVE_HEAD(&p->packets, list))) {
 		if (cp->retransid > -1)
 			ast_sched_del(sched, cp->retransid);
 		free(cp);
 	}
+
 	if (p->chanvars) {
 		ast_variables_destroy(p->chanvars);
 		p->chanvars = NULL;
@@ -3369,6 +3360,9 @@
 	p->subscribed = NONE;
 	p->stateid = -1;
 	p->prefs = default_prefs;		/* Set default codecs for this call */
+
+	/* Initialize our list of packets */
+	AST_LIST_HEAD_INIT_NOLOCK(&p->packets);
 
 	if (intended_method != SIP_OPTIONS)	/* Peerpoke has it's own system */
 		p->timer_t1 = 500;	/* Default SIP retransmission timer T1 (RFC 3261) */
@@ -12156,7 +12150,7 @@
 				}
 			}
 			/* If we have sessions that needs to be destroyed, do it now */
-			if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && !sip->packets && !sip->owner) {
+			if (ast_test_flag(&sip->flags[0], SIP_NEEDDESTROY) && AST_LIST_EMPTY(&sip->packets) && !sip->owner) {
 				ast_mutex_unlock(&sip->lock);
 				__sip_destroy(sip, 1);
 				goto restartsearch;
@@ -13458,6 +13452,18 @@
 			default_maxcallbitrate = atoi(v->value);
 			if (default_maxcallbitrate < 0)
 				default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
+		} else if (!strcasecmp(v->name, "maxthreads")) {
+			if (atoi(v->value) != sipmaxthreads) {
+				if (sipthreadsstarted) {
+					ast_log(LOG_WARNING, "You must unload and load chan_sip for the thread count to be modified.\n");
+				} else {
+					sipmaxthreads = atoi(v->value);
+					if (sipmaxthreads < 0)
+						sipmaxthreads = 1;
+					else if (sipmaxthreads > 256)
+						sipmaxthreads = 256;
+				}
+			}
 		}
 	}
 
@@ -13467,8 +13473,7 @@
 	}
 	
 	/* Spawn SIP threads if possible */
-	if (sipmaxthreads > 0 && AST_LIST_EMPTY(&idle_list) && AST_LIST_EMPTY(&active_list)) {
-		ast_log(LOG_NOTICE, "Spawning threads\n");
+	if (!sipthreadsstarted && sipmaxthreads > 0) {
 		while (sipmaxthreads > threadcount) {
 			/* Allocate memory for this thread, and set it up */
 			thread = ast_calloc(1, sizeof(*thread));
@@ -13493,6 +13498,7 @@
 				ast_mutex_unlock(&thread->lock);
 			}
 		}
+		sipthreadsstarted = 1;
 	}
 
 	/* Build list of authentication to various SIP realms, i.e. service providers */

Modified: team/group/sip-threading/configs/sip.conf.sample
URL: http://svn.digium.com/view/asterisk/team/group/sip-threading/configs/sip.conf.sample?rev=26530&r1=26529&r2=26530&view=diff
==============================================================================
--- team/group/sip-threading/configs/sip.conf.sample (original)
+++ team/group/sip-threading/configs/sip.conf.sample Wed May 10 10:39:02 2006
@@ -120,6 +120,8 @@
 ;maxcallbitrate=384		; Maximum bitrate for video calls (default 384 kb/s)
 				; Videosupport and maxcallbitrate is settable
 				; for peers and users as well
+;maxthreads=10                  ; Maximum number of threads to spawn at startup to
+                                ; handle multithreaded capable actions. Default: 10
 ;callevents=no			; generate manager events when sip ua 
 				; performs events (e.g. hold)
 



More information about the asterisk-commits mailing list