[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