[svn-commits] branch group/sip-threading r26530 - in
/team/group/sip-threading: channels/ c...
svn-commits at lists.digium.com
svn-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 svn-commits
mailing list