[asterisk-commits] qwell: branch qwell/skinny-linkedlists r52460 - /team/qwell/skinny-linkedlist...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Fri Jan 26 21:51:41 MST 2007


Author: qwell
Date: Fri Jan 26 22:51:40 2007
New Revision: 52460

URL: http://svn.digium.com/view/asterisk?view=rev&rev=52460
Log:
rwlist-ification.

This branch is still thoroughly untested - but it compiles.  Don't use it. :)

Modified:
    team/qwell/skinny-linkedlists/channels/chan_skinny.c

Modified: team/qwell/skinny-linkedlists/channels/chan_skinny.c
URL: http://svn.digium.com/view/asterisk/team/qwell/skinny-linkedlists/channels/chan_skinny.c?view=diff&rev=52460&r1=52459&r2=52460
==============================================================================
--- team/qwell/skinny-linkedlists/channels/chan_skinny.c (original)
+++ team/qwell/skinny-linkedlists/channels/chan_skinny.c Fri Jan 26 22:51:40 2007
@@ -872,9 +872,9 @@
 
 /* Protect the monitoring thread, so only one process can kill or start it, and not
    when it's doing something critical. */
-AST_MUTEX_DEFINE_STATIC(monlock);
+AST_RWLOCK_DEFINE_STATIC(monlock);
 /* Protect the network socket */
-AST_MUTEX_DEFINE_STATIC(netlock);
+AST_RWLOCK_DEFINE_STATIC(netlock);
 
 /* This is the thread for the monitor which checks for input on the channels
    which are not currently in use. */
@@ -890,7 +890,7 @@
 static int matchdigittimeout = 3000;
 
 struct skinny_subchannel {
-	ast_mutex_t lock;
+	ast_rwlock_t lock;
 	struct ast_channel *owner;
 	struct ast_rtp *rtp;
 	struct ast_rtp *vrtp;
@@ -905,12 +905,12 @@
 	int outgoing;
 	int alreadygone;
 
-	AST_LIST_ENTRY(skinny_subchannel) list;
+	AST_RWLIST_ENTRY(skinny_subchannel) list;
 	struct skinny_line *parent;
 };
 
 struct skinny_line {
-	ast_mutex_t lock;
+	ast_rwlock_t lock;
 	char name[80];
 	char label[42];					/* Label that shows next to the line buttons */
 	char accountcode[AST_MAX_ACCOUNT_CODE];
@@ -951,26 +951,26 @@
 	int nat;
 
 	struct ast_codec_pref prefs;
-	AST_LIST_HEAD(, skinny_subchannel) sub;
-	AST_LIST_ENTRY(skinny_line) list;
+	AST_RWLIST_HEAD(, skinny_subchannel) subs;
+	AST_RWLIST_ENTRY(skinny_line) list;
 	struct skinny_device *parent;
 };
 
 struct skinny_speeddial {
-	ast_mutex_t lock;
+	ast_rwlock_t lock;
 	char label[42];
 	char exten[AST_MAX_EXTENSION];
 	int instance;
 
-	AST_LIST_ENTRY(skinny_speeddial) list;
+	AST_RWLIST_ENTRY(skinny_speeddial) list;
 	struct skinny_device *parent;
 };
 
 struct skinny_addon {
-	ast_mutex_t lock;
+	ast_rwlock_t lock;
 	char type[10];
 
-	AST_LIST_ENTRY(skinny_addon) list;
+	AST_RWLIST_ENTRY(skinny_addon) list;
 	struct skinny_device *parent;
 };
 
@@ -986,36 +986,36 @@
 	int capability;
 	struct sockaddr_in addr;
 	struct in_addr ourip;
-	AST_LIST_HEAD(, skinny_line) lines;
-	AST_LIST_HEAD(, skinny_speeddial) speeddials;
-	AST_LIST_HEAD(, skinny_addon) addons;
+	AST_RWLIST_HEAD(, skinny_line) lines;
+	AST_RWLIST_HEAD(, skinny_speeddial) speeddials;
+	AST_RWLIST_HEAD(, skinny_addon) addons;
 	struct ast_codec_pref prefs;
 	struct ast_ha *ha;
 	struct skinnysession *session;
-	AST_LIST_ENTRY(skinny_device) list;
-};
-
-static AST_LIST_HEAD_STATIC(devices, skinny_device);
+	AST_RWLIST_ENTRY(skinny_device) list;
+};
+
+static AST_RWLIST_HEAD_STATIC(devices, skinny_device);
 
 struct skinny_paging_device {
 	char name[80];
 	char id[16];
 	struct skinny_device ** devices;
-	AST_LIST_ENTRY(skinny_paging_device) list;
+	AST_RWLIST_ENTRY(skinny_paging_device) list;
 };
 
 struct skinnysession {
 	pthread_t t;
-	ast_mutex_t lock;
+	ast_rwlock_t lock;
 	struct sockaddr_in sin;
 	int fd;
 	char inbuf[SKINNY_MAX_PACKET];
 	char outbuf[SKINNY_MAX_PACKET];
 	struct skinny_device *device;
-	AST_LIST_ENTRY(skinnysession) list;
-};
-
-static AST_LIST_HEAD_STATIC(sessions, skinnysession);
+	AST_RWLIST_ENTRY(skinnysession) list;
+};
+
+static AST_RWLIST_HEAD_STATIC(sessions, skinnysession);
 
 static struct ast_channel *skinny_request(const char *type, int format, void *data, int *cause);
 static int skinny_call(struct ast_channel *ast, char *dest, int timeout);
@@ -1150,8 +1150,8 @@
 			break;
 	}
 
-	AST_LIST_LOCK(&d->addons);
-	AST_LIST_TRAVERSE(&d->addons, a, list) {
+	AST_RWLIST_RDLOCK(&d->addons);
+	AST_RWLIST_TRAVERSE(&d->addons, a, list) {
 		if (!strcasecmp(a->type, "7914")) {
 			for (i = 0; i < 14; i++)
 				(btn++)->buttonDefinition = BT_CUST_LINESPEEDDIAL;
@@ -1159,7 +1159,7 @@
 			ast_log(LOG_WARNING, "Unknown addon type '%s' found.  Skipping.\n", a->type);
 		}
 	}
-	AST_LIST_UNLOCK(&d->addons);
+	AST_RWLIST_UNLOCK(&d->addons);
 
 	return btn;
 }
@@ -1181,7 +1181,7 @@
 {
 	struct skinny_line *l;
 
-	AST_LIST_TRAVERSE(&d->lines, l, list) {
+	AST_RWLIST_TRAVERSE(&d->lines, l, list) {
 		if (l->instance == instance)
 			break;
 	}
@@ -1208,23 +1208,23 @@
 	}
 	*at++ = '\0';
 	device = at;
-	AST_LIST_LOCK(&devices);
-	AST_LIST_TRAVERSE(&devices, d, list) {
+	AST_RWLIST_RDLOCK(&devices);
+	AST_RWLIST_TRAVERSE(&devices, d, list) {
 		if (!strcasecmp(d->name, device)) {
 			if (skinnydebug)
 				ast_verbose("Found device: %s\n", d->name);
 			/* Found the device */
-			AST_LIST_TRAVERSE(&d->lines, l, list) {
+			AST_RWLIST_TRAVERSE(&d->lines, l, list) {
 				/* Search for the right line */
 				if (!strcasecmp(l->name, line)) {
-					AST_LIST_UNLOCK(&devices);
+					AST_RWLIST_UNLOCK(&devices);
 					return l;
 				}
 			}
 		}
 	}
 	/* Device not found */
-	AST_LIST_UNLOCK(&devices);
+	AST_RWLIST_UNLOCK(&devices);
 	return NULL;
 }
 
@@ -1238,7 +1238,7 @@
 		return NULL;
 	}
 
-	AST_LIST_TRAVERSE(&l->sub, sub, list) {
+	AST_RWLIST_TRAVERSE(&l->subs, sub, list) {
 		if (sub->callid == reference)
 			break;
 	}
@@ -1255,8 +1255,8 @@
 	struct skinny_line *l;
 	struct skinny_subchannel *sub = NULL;
 
-	AST_LIST_TRAVERSE(&d->lines, l, list) {
-		AST_LIST_TRAVERSE(&l->sub, sub, list) {
+	AST_RWLIST_TRAVERSE(&d->lines, l, list) {
+		AST_RWLIST_TRAVERSE(&l->subs, sub, list) {
 			if (sub->callid == reference)
 				break;
 		}
@@ -1278,7 +1278,7 @@
 {
 	struct skinny_speeddial *sd;
 
-	AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
+	AST_RWLIST_TRAVERSE(&d->speeddials, sd, list) {
 		if (sd->instance == instance)
 			break;
 	}
@@ -1340,8 +1340,8 @@
 	struct sockaddr_in sin;
 	socklen_t slen;
 
-	AST_LIST_LOCK(&devices);
-	AST_LIST_TRAVERSE(&devices, d, list) {
+	AST_RWLIST_RDLOCK(&devices);
+	AST_RWLIST_TRAVERSE(&devices, d, list) {
 		if (!strcasecmp(req->data.reg.name, d->id)
 				&& ast_apply_ha(d->ha, &(s->sin))) {
 			s->device = d;
@@ -1361,7 +1361,7 @@
 			break;
 		}
 	}
-	AST_LIST_UNLOCK(&devices);
+	AST_RWLIST_UNLOCK(&devices);
 	if (!d) {
 		return 0;
 	}
@@ -1385,7 +1385,7 @@
 static int transmit_response(struct skinnysession *s, struct skinny_req *req)
 {
 	int res = 0;
-	ast_mutex_lock(&s->lock);
+	ast_rwlock_wrlock(&s->lock);
 
 	if (skinnydebug)
 		ast_log(LOG_VERBOSE, "writing packet type %04X (%d bytes) to socket %d\n", letohl(req->e), letohl(req->len)+8, s->fd);
@@ -1395,7 +1395,7 @@
 		return -1;
 	}
 
-	memset(s->outbuf,0,sizeof(s->outbuf));
+	memset(s->outbuf, 0, sizeof(s->outbuf));
 	memcpy(s->outbuf, req, skinny_header_size);
 	memcpy(s->outbuf+skinny_header_size, &req->data, letohl(req->len));
 
@@ -1411,7 +1411,7 @@
 		
 	}
 	
-	ast_mutex_unlock(&s->lock);
+	ast_rwlock_unlock(&s->lock);
 	return 1;
 }
 
@@ -1689,7 +1689,7 @@
 	transmit_displaymessage(s, NULL);
 
 /*
-	AST_LIST_TRAVERSE(&d->lines, l, list) {
+	AST_RWLIST_TRAVERSE(&d->lines, l, list) {
 		if (has_voicemail(l)) {
 			if (skinnydebug)
 				ast_verbose("Checking for voicemail Skinny %s@%s\n", l->name, d->name);
@@ -1778,7 +1778,7 @@
 	int which = 0;
 
 	if (pos == 2) {
-		AST_LIST_TRAVERSE(&devices, d, list) {
+		AST_RWLIST_TRAVERSE(&devices, d, list) {
 			if (result)
 				break;
 			if (!strncasecmp(word, d->id, wordlen) && ++which > state)
@@ -1798,8 +1798,8 @@
 		return RESULT_SHOWUSAGE;
 	}
 
-	AST_LIST_LOCK(&devices);
-	AST_LIST_TRAVERSE(&devices, d, list) {
+	AST_RWLIST_RDLOCK(&devices);
+	AST_RWLIST_TRAVERSE(&devices, d, list) {
 		int fullrestart = 0;
 		if (!strcasecmp(argv[2], d->id) || !strcasecmp(argv[2], "all")) {
 			if (!(d->session))
@@ -1821,7 +1821,7 @@
 			transmit_response(d->session, req);
 		}
 	}
-	AST_LIST_UNLOCK(&devices);
+	AST_RWLIST_UNLOCK(&devices);
 	return RESULT_SUCCESS;
 }
 
@@ -1904,12 +1904,12 @@
 		return RESULT_SHOWUSAGE;
 	}
 
-	AST_LIST_LOCK(&devices);
+	AST_RWLIST_RDLOCK(&devices);
 	ast_cli(fd, "Name                 DeviceId         IP              Type            R NL\n");
 	ast_cli(fd, "-------------------- ---------------- --------------- --------------- - --\n");
-	AST_LIST_TRAVERSE(&devices, d, list) {
+	AST_RWLIST_TRAVERSE(&devices, d, list) {
 		numlines = 0;
-		AST_LIST_TRAVERSE(&d->lines, l, list) {
+		AST_RWLIST_TRAVERSE(&d->lines, l, list) {
 			numlines++;
 		}
 
@@ -1921,7 +1921,7 @@
 				d->registered?'Y':'N',
 				numlines);
 	}
-	AST_LIST_UNLOCK(&devices);
+	AST_RWLIST_UNLOCK(&devices);
 	return RESULT_SUCCESS;
 }
 
@@ -1934,11 +1934,11 @@
 		return RESULT_SHOWUSAGE;
 	}
 
-	AST_LIST_LOCK(&devices);
+	AST_RWLIST_RDLOCK(&devices);
 	ast_cli(fd, "Device Name          Instance Name                 Label               \n");
 	ast_cli(fd, "-------------------- -------- -------------------- --------------------\n");
-	AST_LIST_TRAVERSE(&devices, d, list) {
-		AST_LIST_TRAVERSE(&d->lines, l, list) {
+	AST_RWLIST_TRAVERSE(&devices, d, list) {
+		AST_RWLIST_TRAVERSE(&d->lines, l, list) {
 			ast_cli(fd, "%-20s %8d %-20s %-20s\n",
 				d->name,
 				l->instance,
@@ -1947,7 +1947,7 @@
 		}
 	}
 
-	AST_LIST_UNLOCK(&devices);
+	AST_RWLIST_UNLOCK(&devices);
 	return RESULT_SUCCESS;
 }
 
@@ -2091,7 +2091,7 @@
 					stringp = v->value;
 					exten = strsep(&stringp, ",");
 					label = strsep(&stringp, ",");
-					ast_mutex_init(&sd->lock);
+					ast_rwlock_init(&sd->lock);
 					ast_copy_string(sd->exten, exten, sizeof(sd->exten));
 					if (label)
 						ast_copy_string(sd->label, label, sizeof(sd->label));
@@ -2099,22 +2099,22 @@
 						ast_copy_string(sd->label, exten, sizeof(sd->label));
 					sd->instance = speeddialInstance++;
 
-					AST_LIST_INSERT_HEAD(&d->speeddials, sd, list);
+					AST_RWLIST_INSERT_HEAD(&d->speeddials, sd, list);
 				}
 			} else if (!strcasecmp(v->name, "addon")) {
 				if (!(a = ast_calloc(1, sizeof(struct skinny_addon)))) {
 					return NULL;
 				} else {
-					ast_mutex_init(&a->lock);
+					ast_rwlock_init(&a->lock);
 					ast_copy_string(a->type, v->value, sizeof(a->type));
 
-					AST_LIST_INSERT_HEAD(&d->addons, a, list);
+					AST_RWLIST_INSERT_HEAD(&d->addons, a, list);
 				}
 			} else if (!strcasecmp(v->name, "trunk") || !strcasecmp(v->name, "line")) {
 				if (!(l = ast_calloc(1, sizeof(struct skinny_line)))) {
 					return NULL;
 				} else {
-					ast_mutex_init(&l->lock);
+					ast_rwlock_init(&l->lock);
 					ast_copy_string(l->name, v->value, sizeof(l->name));
 
 					/* XXX Should we check for uniqueness?? XXX */
@@ -2155,14 +2155,14 @@
 					l->hookstate = SKINNY_ONHOOK;
 					l->nat = nat;
 
-					AST_LIST_INSERT_HEAD(&d->lines, l, list);
+					AST_RWLIST_INSERT_HEAD(&d->lines, l, list);
 				}
 			} else {
 				ast_log(LOG_WARNING, "Don't know keyword '%s' at line %d\n", v->name, v->lineno);
 			}
 		}
 
-		if (!AST_LIST_FIRST(&d->lines)) {
+		if (!AST_RWLIST_FIRST(&d->lines)) {
 			ast_log(LOG_ERROR, "A Skinny device must have at least one line!\n");
 			return NULL;
 		}
@@ -2190,7 +2190,7 @@
 	struct skinny_device *d = l->parent;
 	int hasvideo = 0;
 
-	ast_mutex_lock(&sub->lock);
+	ast_rwlock_wrlock(&sub->lock);
 	/* Allocate the RTP */
 	sub->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
 	if (hasvideo)
@@ -2216,7 +2216,7 @@
 
 	/* Create the RTP connection */
 	transmit_connect(d->session, sub);
- 	ast_mutex_unlock(&sub->lock);
+ 	ast_rwlock_unlock(&sub->lock);
 }
 
 static void *skinny_newcall(void *data)
@@ -2418,7 +2418,7 @@
 			do_housekeeping(s);
 		}
 	}
-	ast_mutex_lock(&sub->lock);
+	ast_rwlock_wrlock(&sub->lock);
 	sub->owner = NULL;
 	ast->tech_pvt = NULL;
 	sub->alreadygone = 0;
@@ -2427,7 +2427,7 @@
 		ast_rtp_destroy(sub->rtp);
 		sub->rtp = NULL;
 	}
-	ast_mutex_unlock(&sub->lock);
+	ast_rwlock_unlock(&sub->lock);
 	return 0;
 }
 
@@ -2512,9 +2512,9 @@
 {
 	struct ast_frame *fr;
 	struct skinny_subchannel *sub = ast->tech_pvt;
-	ast_mutex_lock(&sub->lock);
+	ast_rwlock_rdlock(&sub->lock);
 	fr = skinny_rtp_read(sub);
-	ast_mutex_unlock(&sub->lock);
+	ast_rwlock_unlock(&sub->lock);
 	return fr;
 }
 
@@ -2537,11 +2537,11 @@
 		}
 	}
 	if (sub) {
-		ast_mutex_lock(&sub->lock);
+		ast_rwlock_rdlock(&sub->lock);
 		if (sub->rtp) {
 			res = ast_rtp_write(sub->rtp, frame);
 		}
-		ast_mutex_unlock(&sub->lock);
+		ast_rwlock_unlock(&sub->lock);
 	}
 	return res;
 }
@@ -2712,7 +2712,7 @@
 			ast_log(LOG_WARNING, "Unable to allocate Skinny subchannel\n");
 			return NULL;
 		} else {
-			ast_mutex_init(&sub->lock);
+			ast_rwlock_init(&sub->lock);
 
 			sub->owner = tmp;
 			sub->callid = callnums++;
@@ -2723,7 +2723,7 @@
 			sub->parent = l;
 			sub->onhold = 0;
 
-			AST_LIST_INSERT_HEAD(&l->sub, sub, list);
+			AST_RWLIST_INSERT_HEAD(&l->subs, sub, list);
 		}
 		tmp->tech = &skinny_tech;
 		tmp->tech_pvt = sub;
@@ -2958,13 +2958,13 @@
 		f.frametype = AST_FRAME_DTMF_END;
 		ast_queue_frame(sub->owner, &f);
 		/* XXX This seriously needs to be fixed */
-		if (AST_LIST_NEXT(sub, list) && AST_LIST_NEXT(sub, list)->owner) {
+		if (AST_RWLIST_NEXT(sub, list) && AST_RWLIST_NEXT(sub, list)->owner) {
 			if (sub->owner->_state == 0) {
 				f.frametype = AST_FRAME_DTMF_BEGIN;
-				ast_queue_frame(AST_LIST_NEXT(sub, list)->owner, &f);
+				ast_queue_frame(AST_RWLIST_NEXT(sub, list)->owner, &f);
 			}
 			f.frametype = AST_FRAME_DTMF_END;
-			ast_queue_frame(AST_LIST_NEXT(sub, list)->owner, &f);
+			ast_queue_frame(AST_RWLIST_NEXT(sub, list)->owner, &f);
 		}
 	} else {
 		if (skinnydebug)
@@ -3301,7 +3301,7 @@
 	transmit_callstate(s, l->instance, l->hookstate, sub->callid);
 	if (skinnydebug)
 		ast_verbose("Skinny %s@%s went on hook\n", l->name, d->name);
-	if (l->transfer && (sub->owner && AST_LIST_NEXT(sub, list) && AST_LIST_NEXT(sub, list)->owner) && ((!sub->outgoing) || (AST_LIST_NEXT(sub, list) && !AST_LIST_NEXT(sub, list)->outgoing))) {
+	if (l->transfer && (sub->owner && AST_RWLIST_NEXT(sub, list) && AST_RWLIST_NEXT(sub, list)->owner) && ((!sub->outgoing) || (AST_RWLIST_NEXT(sub, list) && !AST_RWLIST_NEXT(sub, list)->outgoing))) {
 		/* We're allowed to transfer, we have two active calls and
 		   we made at least one of the calls.  Let's try and transfer */
 
@@ -3327,7 +3327,7 @@
 				l->name, d->name, sub->callid);
 		}
 	}
-	if ((l->hookstate == SKINNY_ONHOOK) && (AST_LIST_NEXT(sub, list) && !AST_LIST_NEXT(sub, list)->rtp)) {
+	if ((l->hookstate == SKINNY_ONHOOK) && (AST_RWLIST_NEXT(sub, list) && !AST_RWLIST_NEXT(sub, list)->rtp)) {
 		do_housekeeping(s);
 	}
 	return 1;
@@ -3355,10 +3355,10 @@
 
 	d->capability &= codecs;
 	ast_verbose("Device capability set to '%d'\n", d->capability);
-	AST_LIST_TRAVERSE(&d->lines, l, list) {
-		ast_mutex_lock(&l->lock);
+	AST_RWLIST_TRAVERSE(&d->lines, l, list) {
+		ast_rwlock_wrlock(&l->lock);
 		l->capability = d->capability;
-		ast_mutex_unlock(&l->lock);
+		ast_rwlock_unlock(&l->lock);
 	}
 
 	return 1;
@@ -3397,7 +3397,7 @@
 
 	instance = letohl(req->data.line.lineNumber);
 
-	AST_LIST_LOCK(&devices);
+	AST_RWLIST_RDLOCK(&devices);
 
 	l = find_line_by_instance(d, instance);
 
@@ -3405,7 +3405,7 @@
 		return 0;
 	}
 
-	AST_LIST_UNLOCK(&devices);
+	AST_RWLIST_UNLOCK(&devices);
 
 	if (!(req = req_alloc(sizeof(struct line_stat_res_message), LINE_STAT_RES_MESSAGE)))
 		return -1;
@@ -3467,7 +3467,7 @@
 				req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE;
 				req->data.buttontemplate.definition[i].instanceNumber = htolel(0);
 
-				AST_LIST_TRAVERSE(&d->lines, l, list) {
+				AST_RWLIST_TRAVERSE(&d->lines, l, list) {
 					if (l->instance == lineInstance) {
 						ast_verbose("Adding button: %d, %d\n", BT_LINE, lineInstance);
 						req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE;
@@ -3480,7 +3480,7 @@
 				}
 
 				if (!btnSet) {
-					AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
+					AST_RWLIST_TRAVERSE(&d->speeddials, sd, list) {
 						if (sd->instance == speeddialInstance) {
 							ast_verbose("Adding button: %d, %d\n", BT_SPEEDDIAL, speeddialInstance);
 							req->data.buttontemplate.definition[i].buttonDefinition = BT_SPEEDDIAL;
@@ -3497,7 +3497,7 @@
 				req->data.buttontemplate.definition[i].buttonDefinition = htolel(BT_NONE);
 				req->data.buttontemplate.definition[i].instanceNumber = htolel(0);
 
-				AST_LIST_TRAVERSE(&d->lines, l, list) {
+				AST_RWLIST_TRAVERSE(&d->lines, l, list) {
 					if (l->instance == lineInstance) {
 						ast_verbose("Adding button: %d, %d\n", BT_LINE, lineInstance);
 						req->data.buttontemplate.definition[i].buttonDefinition = BT_LINE;
@@ -3513,7 +3513,7 @@
 				req->data.buttontemplate.definition[i].buttonDefinition = BT_NONE;
 				req->data.buttontemplate.definition[i].instanceNumber = 0;
 
-				AST_LIST_TRAVERSE(&d->speeddials, sd, list) {
+				AST_RWLIST_TRAVERSE(&d->speeddials, sd, list) {
 					if (sd->instance == speeddialInstance) {
 						ast_verbose("Adding button: %d, %d\n", BT_SPEEDDIAL, speeddialInstance);
 						req->data.buttontemplate.definition[i].buttonDefinition = BT_SPEEDDIAL;
@@ -3852,7 +3852,7 @@
 			transmit_callstate(s, l->instance, l->hookstate, sub->callid);
 			if (skinnydebug)
 				ast_verbose("Skinny %s@%s went on hook\n", l->name, d->name);
-			if (l->transfer && (sub->owner && AST_LIST_NEXT(sub, list) && AST_LIST_NEXT(sub, list)->owner) && ((!sub->outgoing) || (AST_LIST_NEXT(sub, list) && !AST_LIST_NEXT(sub, list)->outgoing))) {
+			if (l->transfer && (sub->owner && AST_RWLIST_NEXT(sub, list) && AST_RWLIST_NEXT(sub, list)->owner) && ((!sub->outgoing) || (AST_RWLIST_NEXT(sub, list) && !AST_RWLIST_NEXT(sub, list)->outgoing))) {
 				/* We're allowed to transfer, we have two active calls and
 				   we made at least one of the calls.  Let's try and transfer */
 
@@ -3878,7 +3878,7 @@
 						l->name, d->name, sub->callid);
 	 			}
 			}
-			if ((l->hookstate == SKINNY_ONHOOK) && (AST_LIST_NEXT(sub, list) && !AST_LIST_NEXT(sub, list)->rtp)) {
+			if ((l->hookstate == SKINNY_ONHOOK) && (AST_RWLIST_NEXT(sub, list) && !AST_RWLIST_NEXT(sub, list)->rtp)) {
 				do_housekeeping(s);
 			}
 		}
@@ -4105,20 +4105,20 @@
 static void destroy_session(struct skinnysession *s)
 {
 	struct skinnysession *cur;
-	AST_LIST_LOCK(&sessions);
-	AST_LIST_TRAVERSE(&sessions, cur, list) {
+	AST_RWLIST_WRLOCK(&sessions);
+	AST_RWLIST_TRAVERSE(&sessions, cur, list) {
 		if (cur == s) {
-			AST_LIST_REMOVE(&sessions, s, list);
+			AST_RWLIST_REMOVE(&sessions, s, list);
 			if (s->fd > -1) {
 				close(s->fd);
 			}
-			ast_mutex_destroy(&s->lock);
+			ast_rwlock_destroy(&s->lock);
 			free(s);
 		} else {
 			ast_log(LOG_WARNING, "Trying to delete nonexistent session %p?\n", s);
 		}
 	}
-	AST_LIST_UNLOCK(&sessions);
+	AST_RWLIST_UNLOCK(&sessions);
 }
 
 static int get_input(struct skinnysession *s)
@@ -4140,8 +4140,8 @@
 		}
  	}
 	if (fds[0].revents) {
-		ast_mutex_lock(&s->lock);
-		memset(s->inbuf,0,sizeof(s->inbuf));
+		ast_rwlock_wrlock(&s->lock);
+		memset(s->inbuf, 0, sizeof(s->inbuf));
 		res = read(s->fd, s->inbuf, 4);
 		if (res < 0) {
 			ast_log(LOG_WARNING, "read() returned error: %s\n", strerror(errno));
@@ -4149,12 +4149,11 @@
 			if (skinnydebug)
 				ast_verbose("Skinny Client was lost, unregistering\n");
 	      
-			skinny_unregister(NULL,s);
-			ast_mutex_unlock(&s->lock);
+			skinny_unregister(NULL, s);
+			ast_rwlock_unlock(&s->lock);
 			return res;
 		} else if (res != 4) {
 			ast_log(LOG_WARNING, "Skinny Client sent less data than expected.  Expected 4 but got %d.\n", res);
-			ast_mutex_unlock(&s->lock);
 			
 			if (res == 0) {
 				if (skinnydebug)
@@ -4162,13 +4161,14 @@
 				skinny_unregister(NULL, s);
 			}
 		     
+			ast_rwlock_unlock(&s->lock);
 			return -1;
 		}
 		
 		dlen = letohl(*(int *)s->inbuf);
 		if (dlen < 0) {
 			ast_log(LOG_WARNING, "Skinny Client sent invalid data.\n");
-			ast_mutex_unlock(&s->lock);
+			ast_rwlock_unlock(&s->lock);
 			return -1;
 		}
 		if (dlen+8 > sizeof(s->inbuf)) {
@@ -4177,7 +4177,7 @@
 		*(int *)s->inbuf = htolel(dlen);
 
 		res = read(s->fd, s->inbuf+4, dlen+4);
-		ast_mutex_unlock(&s->lock);
+		ast_rwlock_unlock(&s->lock);
 		if (res < 0) {
 			ast_log(LOG_WARNING, "read() returned error: %s\n", strerror(errno));
 			return res;
@@ -4197,11 +4197,11 @@
 	if (!(req = ast_calloc(1, SKINNY_MAX_PACKET)))
 		return NULL;
 
-	ast_mutex_lock(&s->lock);
+	ast_rwlock_rdlock(&s->lock);
 	memcpy(req, s->inbuf, skinny_header_size);
 	memcpy(&req->data, s->inbuf+skinny_header_size, letohl(*(int*)(s->inbuf))-4);
 
-	ast_mutex_unlock(&s->lock);
+	ast_rwlock_unlock(&s->lock);
 
 	if (letohl(req->e) < 0) {
 		ast_log(LOG_ERROR, "Event Message is NULL from socket %d, This is bad\n", s->fd);
@@ -4280,11 +4280,11 @@
 			continue;
 
 		memcpy(&s->sin, &sin, sizeof(sin));
-		ast_mutex_init(&s->lock);
+		ast_rwlock_init(&s->lock);
 		s->fd = as;
-		AST_LIST_LOCK(&sessions);
-		AST_LIST_INSERT_HEAD(&sessions, s, list);
-		AST_LIST_UNLOCK(&sessions);
+		AST_RWLIST_WRLOCK(&sessions);
+		AST_RWLIST_INSERT_HEAD(&sessions, s, list);
+		AST_RWLIST_UNLOCK(&sessions);
 
 		if (ast_pthread_create(&tcp_thread, &attr, skinny_session, s)) {
 			destroy_session(s);
@@ -4311,11 +4311,11 @@
 			res = 1000;
 		}
 		res = ast_io_wait(io, res);
-		ast_mutex_lock(&monlock);
+		ast_rwlock_wrlock(&monlock);
 		if (res >= 0) {
 			ast_sched_runq(sched);
 		}
-		ast_mutex_unlock(&monlock);
+		ast_rwlock_unlock(&monlock);
 	}
 	/* Never reached */
 	return NULL;
@@ -4328,9 +4328,9 @@
 	if (monitor_thread == AST_PTHREADT_STOP)
 		return 0;
 
-	ast_mutex_lock(&monlock);
+	ast_rwlock_wrlock(&monlock);
 	if (monitor_thread == pthread_self()) {
-		ast_mutex_unlock(&monlock);
+		ast_rwlock_unlock(&monlock);
 		ast_log(LOG_WARNING, "Cannot kill myself\n");
 		return -1;
 	}
@@ -4340,12 +4340,12 @@
 	} else {
 		/* Start a new monitor */
 		if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
-			ast_mutex_unlock(&monlock);
+			ast_rwlock_unlock(&monlock);
 			ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
 			return -1;
 		}
 	}
-	ast_mutex_unlock(&monlock);
+	ast_rwlock_unlock(&monlock);
 	return 0;
 }
 
@@ -4475,14 +4475,14 @@
 			if (d) {
 				if (option_verbose > 2)
 					ast_verbose(VERBOSE_PREFIX_3 "Added device '%s'\n", d->name);
-				AST_LIST_LOCK(&devices);
-				AST_LIST_INSERT_HEAD(&devices, d, list);
-				AST_LIST_UNLOCK(&devices);
+				AST_RWLIST_WRLOCK(&devices);
+				AST_RWLIST_INSERT_HEAD(&devices, d, list);
+				AST_RWLIST_UNLOCK(&devices);
 			}
 		}
 		cat = ast_category_browse(cfg, cat);
 	}
-	ast_mutex_lock(&netlock);
+	ast_rwlock_wrlock(&netlock);
 	if ((skinnysock > -1) && (ntohs(bindaddr.sin_port) != oldport)) {
 		close(skinnysock);
 		skinnysock = -1;
@@ -4521,7 +4521,7 @@
 			ast_pthread_create_background(&accept_t,NULL, accept_thread, NULL);
 		}
 	}
-	ast_mutex_unlock(&netlock);
+	ast_rwlock_unlock(&netlock);
 	ast_config_destroy(cfg);
 	return 1;
 }
@@ -4533,24 +4533,24 @@
 	struct skinny_speeddial *sd;
 	struct skinny_addon *a;
 
-	AST_LIST_LOCK(&devices);
+	AST_RWLIST_WRLOCK(&devices);
 	/* Delete all devices */
-	while ((d = AST_LIST_REMOVE_HEAD(&devices, list))) {
+	while ((d = AST_RWLIST_REMOVE_HEAD(&devices, list))) {
 		/* Delete all lines for this device */
-		while ((l = AST_LIST_REMOVE_HEAD(&d->lines, list))) {
+		while ((l = AST_RWLIST_REMOVE_HEAD(&d->lines, list))) {
 			free(l);
 		}
 		/* Delete all speeddials for this device */
-		while ((sd = AST_LIST_REMOVE_HEAD(&d->speeddials, list))) {
+		while ((sd = AST_RWLIST_REMOVE_HEAD(&d->speeddials, list))) {
 			free(sd);
 		}
 		/* Delete all addons for this device */
-		while ((a = AST_LIST_REMOVE_HEAD(&d->addons, list))) {
+		while ((a = AST_RWLIST_REMOVE_HEAD(&d->addons, list))) {
 			free(a);
 		}
 		free(d);
 	}
-	AST_LIST_UNLOCK(&devices);
+	AST_RWLIST_UNLOCK(&devices);
 }
 
 #if 0
@@ -4609,48 +4609,50 @@
 	struct skinny_line *l;
 	struct skinny_subchannel *sub;
 
-	AST_LIST_LOCK(&sessions);
+	AST_RWLIST_WRLOCK(&sessions);
 	/* Destroy all the interfaces and free their memory */
-	s = AST_LIST_FIRST(&sessions);
-	while ((s = AST_LIST_REMOVE_HEAD(&sessions, list))) {
+	s = AST_RWLIST_FIRST(&sessions);
+	while ((s = AST_RWLIST_REMOVE_HEAD(&sessions, list))) {
 		d = s->device;
-		AST_LIST_TRAVERSE(&d->lines, l, list) {
-			ast_mutex_lock(&l->lock);
-			AST_LIST_TRAVERSE(&l->sub, sub, list) {
-				ast_mutex_lock(&sub->lock);
+		AST_RWLIST_RDLOCK(&d->lines);
+		AST_RWLIST_TRAVERSE(&d->lines, l, list) {
+			AST_RWLIST_RDLOCK(&l->subs);
+			AST_RWLIST_TRAVERSE(&l->subs, sub, list) {
+				ast_rwlock_wrlock(&sub->lock);
 				if (sub->owner) {
 					sub->alreadygone = 1;
 					ast_softhangup(sub->owner, AST_SOFTHANGUP_APPUNLOAD);
 				}
-				ast_mutex_unlock(&sub->lock);
+				ast_rwlock_unlock(&sub->lock);
 			}
-			ast_mutex_unlock(&l->lock);
-		}
+			AST_RWLIST_UNLOCK(&l->subs);
+		}
+		AST_RWLIST_UNLOCK(&d->lines);
 		if (s->fd > -1)
 			close(s->fd);
 		free(s);
 	}
-	AST_LIST_UNLOCK(&sessions);
+	AST_RWLIST_UNLOCK(&sessions);
 
 	delete_devices();
 
-	ast_mutex_lock(&monlock);
+	ast_rwlock_wrlock(&monlock);
 	if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP)) {
 		pthread_cancel(monitor_thread);
 		pthread_kill(monitor_thread, SIGURG);
 		pthread_join(monitor_thread, NULL);
 	}
 	monitor_thread = AST_PTHREADT_STOP;
-	ast_mutex_unlock(&monlock);
-
-	ast_mutex_lock(&netlock);
+	ast_rwlock_unlock(&monlock);
+
+	ast_rwlock_wrlock(&netlock);
 	if (accept_t && (accept_t != AST_PTHREADT_STOP)) {
 		pthread_cancel(accept_t);
 		pthread_kill(accept_t, SIGURG);
 		pthread_join(accept_t, NULL);
 	}
 	accept_t = AST_PTHREADT_STOP;
-	ast_mutex_unlock(&netlock);
+	ast_rwlock_unlock(&netlock);
 
 	ast_rtp_proto_unregister(&skinny_rtp);
 	ast_channel_unregister(&skinny_tech);



More information about the asterisk-commits mailing list