[svn-commits] qwell: trunk r597 - /trunk/channels/chan_mobile.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri May 9 16:46:00 CDT 2008


Author: qwell
Date: Fri May  9 16:45:59 2008
New Revision: 597

URL: http://svn.digium.com/view/asterisk-addons?view=rev&rev=597
Log:
Add locking (also switch to rw, because they are awesome) to adapters and devices lists.

(related to issue #11566)
Reported by: non-poster
Patches:
      chan_mobile-rwlocks.diff uploaded by qwell (license 4)
Tested by: qwell

Modified:
    trunk/channels/chan_mobile.c

Modified: trunk/channels/chan_mobile.c
URL: http://svn.digium.com/view/asterisk-addons/trunk/channels/chan_mobile.c?view=diff&rev=597&r1=596&r2=597
==============================================================================
--- trunk/channels/chan_mobile.c (original)
+++ trunk/channels/chan_mobile.c Fri May  9 16:45:59 2008
@@ -123,7 +123,7 @@
 	AST_LIST_ENTRY(adapter_pvt) entry;
 };
 
-static AST_LIST_HEAD_STATIC(adapters, adapter_pvt);
+static AST_RWLIST_HEAD_STATIC(adapters, adapter_pvt);
 
 struct mbl_pvt {
 	struct ast_channel *owner;			/* Channel we belong to, possibly NULL */
@@ -171,7 +171,7 @@
 	AST_LIST_ENTRY(mbl_pvt) entry;
 };
 
-static AST_LIST_HEAD_STATIC(devices, mbl_pvt);
+static AST_RWLIST_HEAD_STATIC(devices, mbl_pvt);
 
 /* CLI stuff */
 static char *handle_cli_mobile_show_devices(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
@@ -267,13 +267,15 @@
 		return CLI_SHOWUSAGE;
 
 	ast_cli(a->fd, FORMAT1, "ID", "Address", "Group", "Adapter", "Connected", "State", "SMS");
-	AST_LIST_TRAVERSE(&devices, pvt, entry) {
+	AST_RWLIST_RDLOCK(&devices);
+	AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
 		ba2str(&pvt->addr, bdaddr);
 		snprintf(group, 5, "%d", pvt->group);
 		ast_cli(a->fd, FORMAT1, pvt->id, bdaddr, group, pvt->adapter->id, pvt->connected ? "Yes" : "No",
 			(pvt->state == MBL_STATE_IDLE) ? "Free" : (pvt->state < MBL_STATE_IDLE) ? "Init" : "Busy",
 			(pvt->has_sms) ? "Yes" : "No");
 	}
+	AST_RWLIST_UNLOCK(&devices);
 
 #undef FORMAT1
 
@@ -308,10 +310,12 @@
 		return CLI_SHOWUSAGE;
 
 	/* find a free adapter */
-	AST_LIST_TRAVERSE(&adapters, adapter, entry) {
+	AST_RWLIST_RDLOCK(&adapters);
+	AST_RWLIST_TRAVERSE(&adapters, adapter, entry) {
 		if (!adapter->inuse)
 			break;
 	}
+	AST_RWLIST_UNLOCK(&adapters);
 
 	if (!adapter) {
 		ast_cli(a->fd, "All Bluetooth adapters are in use at this time.\n");
@@ -368,10 +372,12 @@
 	if (a->argc != 4)
 		return CLI_SHOWUSAGE;
 
-	AST_LIST_TRAVERSE(&devices, pvt, entry) {
+	AST_RWLIST_RDLOCK(&devices);
+	AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
 		if (!strcmp(pvt->id, a->argv[2]))
 			break;
 	}
+	AST_RWLIST_UNLOCK(&devices);
 
 	if (!pvt || !pvt->connected) {
 		ast_cli(a->fd, "Device %s not found.\n", a->argv[2]);
@@ -415,10 +421,12 @@
 
 	stat = 1;
 
-	AST_LIST_TRAVERSE(&devices, pvt, entry) {
+	AST_RWLIST_RDLOCK(&devices);
+	AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
 		if (!strcmp(pvt->id, args.device))
 			break;
 	}
+	AST_RWLIST_UNLOCK(&devices);
 
 	if (pvt) {
 		if (pvt->connected)
@@ -468,10 +476,12 @@
 		return -1;
 	}
 
-	AST_LIST_TRAVERSE(&devices, pvt, entry) {
+	AST_RWLIST_RDLOCK(&devices);
+	AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
 		if (!strcmp(pvt->id, args.device))
 			break;
 	}
+	AST_RWLIST_UNLOCK(&devices);
 
 	if (!pvt) {
 		ast_log(LOG_ERROR,"Bluetooth device %s wasn't found in the list -- SMS will not be sent.\n", args.device);
@@ -581,7 +591,8 @@
 		*dest_num++ = 0x00;
 
 	/* Find requested device and make sure its connected. */
-	AST_LIST_TRAVERSE(&devices, pvt, entry) {
+	AST_RWLIST_RDLOCK(&devices);
+	AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
 		if (((dest_dev[0] == 'g') || (dest_dev[0] == 'G')) && ((dest_dev[1] >= '0') && (dest_dev[1] <= '9'))) {
 			group = atoi(dest_dev+1);
 			if (pvt->group == group)
@@ -590,6 +601,7 @@
 			break;
 		}
 	}
+	AST_RWLIST_UNLOCK(&devices);
 	if (!pvt || !pvt->connected || pvt->owner) {
 		ast_log(LOG_WARNING, "Request to call on device %s which is not connected / already in use.\n", dest_dev);
 		*cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
@@ -869,10 +881,12 @@
 
 	ast_debug(1, "Checking device state for device %s\n", device);
 
-	AST_LIST_TRAVERSE(&devices, pvt, entry) {
+	AST_RWLIST_RDLOCK(&devices);
+	AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
 		if (!strcmp(pvt->id, device))
 			break;
 	}
+	AST_RWLIST_UNLOCK(&devices);
 
 	if (pvt) {
 		if (pvt->connected) {
@@ -1771,9 +1785,11 @@
 	struct mbl_pvt *pvt;
 
 	for (;;) {
-		AST_LIST_TRAVERSE(&adapters, adapter, entry) {
+		AST_RWLIST_RDLOCK(&adapters);
+		AST_RWLIST_TRAVERSE(&adapters, adapter, entry) {
 			if (!adapter->inuse) {
-				AST_LIST_TRAVERSE(&devices, pvt, entry) {
+				AST_RWLIST_RDLOCK(&devices);
+				AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
 					if (!adapter->inuse && !pvt->connected && !strcmp(adapter->id, pvt->adapter->id)) {
 						if ((pvt->rfcomm_socket = rfcomm_connect(adapter->addr, pvt->addr, pvt->rfcomm_port)) > -1) {
 							pvt->state = 0;
@@ -1787,8 +1803,10 @@
 						}
 					}
 				}
+				AST_RWLIST_UNLOCK(&devices);
 			}
 		}
+		AST_RWLIST_UNLOCK(&adapters);
 		/* Go to sleep */
 		sleep(discovery_interval);
 	}
@@ -1843,10 +1861,12 @@
 			ast_debug(1, "Incoming Audio Connection from device %s MTU is %d\n", saddr, so.mtu);
 
 			pvt = NULL;
-			AST_LIST_TRAVERSE(&devices, pvt, entry) {
+			AST_RWLIST_RDLOCK(&devices);
+			AST_RWLIST_TRAVERSE(&devices, pvt, entry) {
 				if (!bacmp(&pvt->addr, &addr.sco_bdaddr)) 
 					break;
 			}
+			AST_RWLIST_UNLOCK(&devices);
 			if (pvt) {
 				if (pvt->sco_socket != -1)
 					close(pvt->sco_socket);
@@ -1929,7 +1949,9 @@
 							hci_close_dev(adapter->hci_socket);
 							ast_free(adapter);
 						} else {
-							AST_LIST_INSERT_HEAD(&adapters, adapter, entry);
+							AST_RWLIST_WRLOCK(&adapters);
+							AST_RWLIST_INSERT_HEAD(&adapters, adapter, entry);
+							AST_RWLIST_UNLOCK(&adapters);
 							nadapters++;
 						}
 					}
@@ -1961,10 +1983,12 @@
 			nocallsetup = ast_variable_retrieve(cfg, cat, "nocallsetup");
 			if (!ast_strlen_zero(address) && !ast_strlen_zero(port) && !ast_strlen_zero(useadapter)) {
 				/* find the adapter */
-				AST_LIST_TRAVERSE(&adapters, adapter, entry) {
+				AST_RWLIST_RDLOCK(&adapters);
+				AST_RWLIST_TRAVERSE(&adapters, adapter, entry) {
 					if (!strcmp(adapter->id, useadapter))
 						break;
 				}
+				AST_RWLIST_UNLOCK(&adapters);
 				if (!adapter) {
 					ast_log(LOG_ERROR, "Device %s configured to use unknown adapter %s. It won't be enabled.\n", cat, useadapter);
 					break;
@@ -2000,7 +2024,9 @@
 					ast_dsp_set_features(pvt->dsp, DSP_FEATURE_DIGIT_DETECT);
 					ast_dsp_set_digitmode(pvt->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
 					pvt->adapter = adapter;
-					AST_LIST_INSERT_HEAD(&devices, pvt, entry);
+					AST_RWLIST_WRLOCK(&devices);
+					AST_RWLIST_INSERT_HEAD(&devices, pvt, entry);
+					AST_RWLIST_UNLOCK(&devices);
 				}
 			} else {
 				ast_log(LOG_ERROR, "Device %s has no address/port/adapter configured. It won't be enabled.\n", cat);
@@ -2031,7 +2057,8 @@
 	}
 
 	/* Destroy the device list */
-	while ((pvt = AST_LIST_REMOVE_HEAD(&devices, entry))) {
+	AST_RWLIST_WRLOCK(&devices);
+	while ((pvt = AST_RWLIST_REMOVE_HEAD(&devices, entry))) {
 		if (pvt->monitor_thread != AST_PTHREADT_NULL) {
 			pthread_cancel(pvt->monitor_thread);
 			pthread_join(pvt->monitor_thread, NULL);
@@ -2052,12 +2079,15 @@
 		ast_dsp_free(pvt->dsp);
 		ast_free(pvt);
 	}
+	AST_RWLIST_UNLOCK(&devices);
 
 	/* Destroy the adapter list */
-	while ((adapter = AST_LIST_REMOVE_HEAD(&adapters, entry))) {
+	AST_RWLIST_WRLOCK(&adapters);
+	while ((adapter = AST_RWLIST_REMOVE_HEAD(&adapters, entry))) {
 		hci_close_dev(adapter->hci_socket);
 		ast_free(adapter);
 	}
+	AST_RWLIST_UNLOCK(&adapters);
 
 	if (sdp_session)
 		sdp_close(sdp_session);




More information about the svn-commits mailing list