[asterisk-addons-commits] tilghman: trunk r910 - /trunk/res/res_config_mysql.c
SVN commits to the Asterisk addons project
asterisk-addons-commits at lists.digium.com
Thu May 14 14:16:58 CDT 2009
Author: tilghman
Date: Thu May 14 14:16:53 2009
New Revision: 910
URL: http://svn.asterisk.org/svn-view/asterisk-addons?view=rev&rev=910
Log:
Change database list to be rwlist locks, to avoid a potential deadlock between 2 readers.
(closes issue #15023, related to issue #15090)
Reported by: cristiandimache
Patches:
20090514__issue15090.diff.txt uploaded by tilghman (license 14)
Tested by: cristiandimache
Modified:
trunk/res/res_config_mysql.c
Modified: trunk/res/res_config_mysql.c
URL: http://svn.asterisk.org/svn-view/asterisk-addons/trunk/res/res_config_mysql.c?view=diff&rev=910&r1=909&r2=910
==============================================================================
--- trunk/res/res_config_mysql.c (original)
+++ trunk/res/res_config_mysql.c Thu May 14 14:16:53 2009
@@ -87,7 +87,7 @@
enum requirements { RQ_WARN, RQ_CREATECLOSE, RQ_CREATECHAR };
struct mysql_conn {
- AST_LIST_ENTRY(mysql_conn) list;
+ AST_RWLIST_ENTRY(mysql_conn) list;
ast_mutex_t lock;
MYSQL handle;
char host[50];
@@ -120,7 +120,7 @@
};
static AST_LIST_HEAD_STATIC(mysql_tables, tables);
-static AST_LIST_HEAD_STATIC(databases, mysql_conn);
+static AST_RWLIST_HEAD_STATIC(databases, mysql_conn);
static int parse_config(int reload);
static int mysql_reconnect(struct mysql_conn *conn);
@@ -154,14 +154,14 @@
whichdb = ast_strdupa(database);
}
- AST_LIST_LOCK(&databases);
- AST_LIST_TRAVERSE(&databases, cur, list) {
+ AST_RWLIST_RDLOCK(&databases);
+ AST_RWLIST_TRAVERSE(&databases, cur, list) {
if (!strcmp(cur->unique_name, whichdb)) {
ast_mutex_lock(&cur->lock);
break;
}
}
- AST_LIST_UNLOCK(&databases);
+ AST_RWLIST_UNLOCK(&databases);
return cur;
}
@@ -1393,12 +1393,13 @@
ast_module_user_hangup_all();
usleep(1);
- AST_LIST_LOCK(&databases);
- while ((cur = AST_LIST_REMOVE_HEAD(&databases, list))) {
+ AST_RWLIST_WRLOCK(&databases);
+ while ((cur = AST_RWLIST_REMOVE_HEAD(&databases, list))) {
mysql_close(&cur->handle);
ast_mutex_destroy(&cur->lock);
ast_free(cur);
}
+ AST_RWLIST_UNLOCK(&databases);
/* Destroy cached table info */
AST_LIST_LOCK(&mysql_tables);
@@ -1436,10 +1437,10 @@
ast_log(LOG_ERROR, "Not %sloading " RES_CONFIG_MYSQL_CONF "\n", reload ? "re" : "");
}
- AST_LIST_LOCK(&databases);
+ AST_RWLIST_WRLOCK(&databases);
for (catg = ast_category_browse(config, NULL); catg; catg = ast_category_browse(config, catg)) {
/* Does this category already exist? */
- AST_LIST_TRAVERSE(&databases, cur, list) {
+ AST_RWLIST_TRAVERSE(&databases, cur, list) {
if (!strcmp(cur->unique_name, catg)) {
break;
}
@@ -1453,12 +1454,12 @@
strcpy(cur->unique_name, catg); /* SAFE */
ast_mutex_init(&cur->lock);
- AST_LIST_INSERT_TAIL(&databases, cur, list);
+ AST_RWLIST_INSERT_TAIL(&databases, cur, list);
}
load_mysql_config(config, catg, cur);
}
- AST_LIST_UNLOCK(&databases);
+ AST_RWLIST_UNLOCK(&databases);
ast_config_destroy(config);
@@ -1628,14 +1629,14 @@
AST_LIST_UNLOCK(&mysql_tables);
} else {
struct mysql_conn *cur;
- AST_LIST_LOCK(&databases);
- AST_LIST_TRAVERSE(&databases, cur, list) {
+ AST_RWLIST_RDLOCK(&databases);
+ AST_RWLIST_TRAVERSE(&databases, cur, list) {
if (!strncasecmp(a->word, cur->unique_name, l) && ++which > a->n) {
ret = ast_strdup(cur->unique_name);
break;
}
}
- AST_LIST_UNLOCK(&databases);
+ AST_RWLIST_UNLOCK(&databases);
}
return ret;
}
@@ -1695,14 +1696,14 @@
return NULL;
case CLI_GENERATE:
if (a->argc == 4) {
- AST_LIST_LOCK(&databases);
- AST_LIST_TRAVERSE(&databases, cur, list) {
+ AST_RWLIST_RDLOCK(&databases);
+ AST_RWLIST_TRAVERSE(&databases, cur, list) {
if (!strncasecmp(a->word, cur->unique_name, l) && ++which > a->n) {
ret = ast_strdup(cur->unique_name);
break;
}
}
- AST_LIST_UNLOCK(&databases);
+ AST_RWLIST_UNLOCK(&databases);
}
return ret;
}
@@ -1710,8 +1711,8 @@
if (a->argc != 3)
return CLI_SHOWUSAGE;
- AST_LIST_LOCK(&databases);
- AST_LIST_TRAVERSE(&databases, cur, list) {
+ AST_RWLIST_RDLOCK(&databases);
+ AST_RWLIST_TRAVERSE(&databases, cur, list) {
if (a->argc == 3 || (a->argc == 4 && !strcasecmp(a->argv[3], cur->unique_name))) {
found = 1;
@@ -1752,7 +1753,7 @@
}
}
}
- AST_LIST_UNLOCK(&databases);
+ AST_RWLIST_UNLOCK(&databases);
if (!found) {
ast_cli(a->fd, "No connections configured.\n");
More information about the asterisk-addons-commits
mailing list