[Asterisk-cvs] asterisk/channels chan_sip.c,1.288,1.289

markster at lists.digium.com markster at lists.digium.com
Mon Feb 2 17:12:55 CST 2004


Update of /usr/cvsroot/asterisk/channels
In directory mongoose.digium.com:/tmp/cvs-serv22110/channels

Modified Files:
	chan_sip.c 
Log Message:
Centralize all sip registration around a single lock


Index: chan_sip.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v
retrieving revision 1.288
retrieving revision 1.289
diff -u -d -r1.288 -r1.289
--- chan_sip.c	2 Feb 2004 22:35:33 -0000	1.288
+++ chan_sip.c	2 Feb 2004 23:21:36 -0000	1.289
@@ -371,7 +371,6 @@
 #define REG_STATE_NOAUTH	   6
 
 struct sip_registry {
-	ast_mutex_t lock;				/* Channel private lock */
 	struct sockaddr_in addr;		/* Who we connect to for registration purposes */
 	char username[80];				/* Who we are registering as */
 	char authuser[80];				/* Who we *authenticate* as */
@@ -383,6 +382,7 @@
 	int expire;					/* Sched ID of expiration */
 	int timeout; 					/* sched id of sip_reg_timeout */
 	int refresh;					/* How often to refresh */
+	int delme;					/* Need to be deleted? */
 	struct sip_pvt *call;				/* create a sip_pvt structure for each outbound "registration call" in progress */
 	int regstate;
 	int callid_valid;		/* 0 means we haven't chosen callid for this registry yet. */
@@ -405,13 +405,14 @@
 static struct ast_register_list {
 	struct sip_registry *registrations;
 	ast_mutex_t lock;
+	int recheck;
 } regl = { NULL, AST_MUTEX_INITIALIZER };
 
 
 #define REINVITE_INVITE		1
 #define REINVITE_UPDATE		2
 
-static int sip_do_register(struct sip_registry *r);
+static int __sip_do_register(struct sip_registry *r);
 
 static int sipsock  = -1;
 static int globalnat = 0;
@@ -441,6 +442,7 @@
 static int build_reply_digest(struct sip_pvt *p, char *orig_header, char *digest, int digest_len);
 static int find_user(struct sip_pvt *fup, int event);
 static void prune_peers(void);
+static void prune_regs(void);
 
 static int __sip_xmit(struct sip_pvt *p, char *data, int len)
 {
@@ -3113,18 +3115,18 @@
 {
 	/* if we are here, we know that we need to reregister. */
 	struct sip_registry *r=(struct sip_registry *)data;
+	ast_mutex_lock(&regl.lock);
 	r->expire = -1;
-	sip_do_register(r);
+	__sip_do_register(r);
+	ast_mutex_unlock(&regl.lock);
 	return 0;
 }
 
 
-static int sip_do_register(struct sip_registry *r)
+static int __sip_do_register(struct sip_registry *r)
 {
 	int res;
-	ast_mutex_lock(&r->lock);
 	res=transmit_register(r, "REGISTER", NULL, NULL);
-	ast_mutex_unlock(&r->lock);
 	return res;
 }
 
@@ -3134,7 +3136,7 @@
 	struct sip_registry *r=data;
 	struct sip_pvt *p;
 	int res;
-	ast_mutex_lock(&r->lock);
+	ast_mutex_lock(&regl.lock);
 	ast_log(LOG_NOTICE, "Registration for '%s@%s' timed out, trying again\n", r->username, inet_ntoa(r->addr.sin_addr)); 
 	if (r->call) {
 		/* Unlink us, destroy old call.  Locking is not relevent here because all this happens
@@ -3147,7 +3149,7 @@
 	r->regstate=REG_STATE_UNREGISTERED;
 	r->timeout = -1;
 	res=transmit_register(r, "REGISTER", NULL, NULL);
-	ast_mutex_unlock(&r->lock);
+	ast_mutex_unlock(&regl.lock);
 	return 0;
 }
 
@@ -5710,6 +5712,7 @@
 	   (and thus do not have a separate thread) indefinitely */
 	/* From here on out, we die whenever asked */
 	for(;;) {
+		prune_regs();
 		/* Check for interfaces needing to be killed */
 		ast_mutex_lock(&iflock);
 restartsearch:		
@@ -6627,11 +6630,41 @@
 	get_codec: sip_get_codec,
 };
 
+static void prune_regs(void)
+{
+	struct sip_registry *reg, *next, *prev = NULL;
+	ast_mutex_lock(&regl.lock);
+	if (!regl.recheck) {
+		ast_mutex_unlock(&regl.lock);
+		return;
+	}
+	for (reg = regl.registrations;reg;) {
+		next = reg->next;
+		if (reg->delme) {
+			/* Really delete */
+			if (reg->call) {
+				/* Clear registry before destroying to ensure
+				   we don't get reentered trying to grab the registry lock */
+				reg->call->registry = NULL;
+				sip_destroy(reg->call);
+			}
+			if (reg->expire > -1)
+				ast_sched_del(sched, reg->expire);
+			if (reg->timeout > -1)
+				ast_sched_del(sched, reg->timeout);
+			free(reg);
+		} else 
+			prev = reg;
+		reg = next;
+	}
+	ast_mutex_unlock(&regl.lock);
+}
+
 static void delete_users(void)
 {
 	struct sip_user *user, *userlast;
 	struct sip_peer *peer;
-	struct sip_registry *reg, *reglast;
+	struct sip_registry *reg;
 
 	/* Delete all users */
 	ast_mutex_lock(&userl.lock);
@@ -6646,17 +6679,8 @@
 
 	ast_mutex_lock(&regl.lock);
 	for (reg = regl.registrations;reg;) {
-		reglast = reg;
+		reg->delme = 1;
 		reg = reg->next;
-		if (reglast->call) {
-			/* Clear registry before destroying to ensure
-			   we don't get reentered trying to grab the registry lock */
-			reglast->call->registry = NULL;
-			sip_destroy(reglast->call);
-		}
-		if (reglast->expire > -1)
-			ast_sched_del(sched, reglast->expire);
-		free(reglast);
 	}
 	regl.registrations = NULL;
 	ast_mutex_unlock(&regl.lock);
@@ -6715,7 +6739,7 @@
 	restart_monitor();
 	ast_mutex_lock(&regl.lock);
 	for (reg = regl.registrations; reg; reg = reg->next) 
-		sip_do_register(reg);
+		__sip_do_register(reg);
 	ast_mutex_unlock(&regl.lock);
 	ast_mutex_lock(&peerl.lock);
 	for (peer = peerl.peers; peer; peer = peer->next)




More information about the svn-commits mailing list