[svn-commits] russell: branch group/issue_11972 r105737 - /team/group/issue_11972/channels/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Mar 4 14:54:44 CST 2008


Author: russell
Date: Tue Mar  4 14:54:44 2008
New Revision: 105737

URL: http://svn.digium.com/view/asterisk?view=rev&rev=105737
Log:
This patch changes the socket mutex to a rwlock, instead. For a TCP/TLS socket, 
we know there will only be one thread reading from the socket at a time. But, 
we have to be careful to ensure that only one thread will write to it at a time. 
That's what the lock was for.

By using a rwlock, the socket read thread will only use a read lock. 
Then, other threads writing to it will use a write-lock. Then, a thread trying 
to send something won't be blocked by the socket reading thread while it's 
sleeping and waiting for data to arrive on the socket.

(related to issue #11972, patch by me)

Modified:
    team/group/issue_11972/channels/chan_sip.c

Modified: team/group/issue_11972/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/group/issue_11972/channels/chan_sip.c?view=diff&rev=105737&r1=105736&r2=105737
==============================================================================
--- team/group/issue_11972/channels/chan_sip.c (original)
+++ team/group/issue_11972/channels/chan_sip.c Tue Mar  4 14:54:44 2008
@@ -773,7 +773,7 @@
 
 /*!< The SIP socket definition */
 struct sip_socket {
-	ast_mutex_t *lock;
+	ast_rwlock_t *lock;
 	enum sip_transport type;
 	int fd;
 	uint16_t port;
@@ -2175,7 +2175,7 @@
 	if (!req.socket.lock)
 		goto cleanup;
 
-	ast_mutex_init(req.socket.lock);
+	ast_rwlock_init(req.socket.lock);
 
 	for (;;) {
 		memset(req.data, 0, sizeof(req.data));
@@ -2199,13 +2199,14 @@
 		/* Read in headers one line at a time */
 		while (req.len < 4 || strncmp((char *)&req.data + req.len - 4, "\r\n\r\n", 4)) {
 			if (req.socket.lock) 
-				ast_mutex_lock(req.socket.lock);
+				ast_rwlock_rdlock(req.socket.lock);
 			if (!fgets(buf, sizeof(buf), ser->f)) {
-				ast_mutex_unlock(req.socket.lock);
+				if (req.socket.lock)
+					ast_rwlock_unlock(req.socket.lock);
 				goto cleanup;
 			}
 			if (req.socket.lock) 
-				ast_mutex_unlock(req.socket.lock);
+				ast_rwlock_unlock(req.socket.lock);
 			if (me->stop) 
 				 goto cleanup;
 			strncat(req.data, buf, sizeof(req.data) - req.len);
@@ -2214,12 +2215,12 @@
 		parse_copy(&reqcpy, &req);
 		if (sscanf(get_header(&reqcpy, "Content-Length"), "%d", &cl)) {
 			while (cl > 0) {
-				if (req.socket.lock) 
-					ast_mutex_lock(req.socket.lock);
-				if (!fread(buf, (cl < sizeof(buf)) ? cl : sizeof(buf), 1, ser->f))
+				ast_rwlock_rdlock(req.socket.lock);
+				if (!fread(buf, (cl < sizeof(buf)) ? cl : sizeof(buf), 1, ser->f)) {
+					ast_rwlock_unlock(req.socket.lock);
 					goto cleanup;
-				if (req.socket.lock) 
-					ast_mutex_unlock(req.socket.lock);
+				}
+				ast_rwlock_unlock(req.socket.lock);
 				if (me->stop)
 					goto cleanup;
 				cl -= strlen(buf);
@@ -2241,7 +2242,7 @@
 	ast_free(ser);
 
 	if (req.socket.lock) {
-		ast_mutex_destroy(req.socket.lock);
+		ast_rwlock_destroy(req.socket.lock);
 		ast_free(req.socket.lock);
 		req.socket.lock = NULL;
 	}
@@ -2520,7 +2521,7 @@
 		return XMIT_ERROR;
 
 	if (p->socket.lock)
-		ast_mutex_lock(p->socket.lock);
+		ast_rwlock_wrlock(p->socket.lock);
 
 	if (p->socket.type & SIP_TRANSPORT_UDP) 
 		res = sendto(p->socket.fd, data, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in));
@@ -2532,7 +2533,7 @@
 	} 
 
 	if (p->socket.lock)
-		ast_mutex_unlock(p->socket.lock);
+		ast_rwlock_unlock(p->socket.lock);
 
 	if (res == -1) {
 		switch (errno) {




More information about the svn-commits mailing list