[asterisk-commits] jrose: branch 1.8 r323730 - /branches/1.8/res/res_config_pgsql.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jun 15 12:42:48 CDT 2011


Author: jrose
Date: Wed Jun 15 12:42:42 2011
New Revision: 323730

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=323730
Log:
Adds locking to find_table in res_configure_pgsql to prevent a crash.

Bryonclark described the problem as occuring during this function because of multiple
simultaneous database operations causing corruption against a pgsqlConn object.

(closes issue ASTERISK-17811)
Reported by: byronclark
Patches: 
      pgsql_find_table_locking.patch uploaded by byronclark (license 1200)


Modified:
    branches/1.8/res/res_config_pgsql.c

Modified: branches/1.8/res/res_config_pgsql.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/res/res_config_pgsql.c?view=diff&rev=323730&r1=323729&r2=323730
==============================================================================
--- branches/1.8/res/res_config_pgsql.c (original)
+++ branches/1.8/res/res_config_pgsql.c Wed Jun 15 12:42:42 2011
@@ -125,7 +125,7 @@
 	ast_free(table);
 }
 
-static struct tables *find_table(const char *orig_tablename)
+static struct tables *find_table(const char *database, const char *orig_tablename)
 {
 	struct columns *column;
 	struct tables *table;
@@ -209,6 +209,13 @@
 		ast_str_set(&sql, 0, "SELECT a.attname, t.typname, a.attlen, a.attnotnull, d.adsrc, a.atttypmod FROM pg_class c, pg_type t, pg_attribute a LEFT OUTER JOIN pg_attrdef d ON a.atthasdef AND d.adrelid = a.attrelid AND d.adnum = a.attnum WHERE c.oid = a.attrelid AND a.atttypid = t.oid AND (a.attnum > 0) AND c.relname = '%s' ORDER BY c.relname, attnum", orig_tablename);
 	}
 
+	ast_mutex_lock(&pgsql_lock);
+	if (!pgsql_reconnect(database)) {
+		AST_LIST_UNLOCK(&psql_tables);
+		ast_mutex_unlock(&pgsql_lock);
+		return NULL;
+	}
+
 	result = PQexec(pgsqlConn, ast_str_buffer(sql));
 	ast_debug(1, "Query of table structure complete.  Now retrieving results.\n");
 	if (PQresultStatus(result) != PGRES_TUPLES_OK) {
@@ -216,6 +223,7 @@
 		ast_log(LOG_ERROR, "Failed to query database columns: %s\n", pgerror);
 		PQclear(result);
 		AST_LIST_UNLOCK(&psql_tables);
+		ast_mutex_unlock(&pgsql_lock);
 		return NULL;
 	}
 
@@ -223,6 +231,7 @@
 		ast_log(LOG_ERROR, "Unable to allocate memory for new table structure\n");
 		PQclear(result);
 		AST_LIST_UNLOCK(&psql_tables);
+		ast_mutex_unlock(&pgsql_lock);
 		return NULL;
 	}
 	strcpy(table->name, orig_tablename); /* SAFE */
@@ -243,6 +252,7 @@
 			PQclear(result);
 			destroy_table(table);
 			AST_LIST_UNLOCK(&psql_tables);
+			ast_mutex_unlock(&pgsql_lock);
 			return NULL;
 		}
 
@@ -275,6 +285,7 @@
 	AST_LIST_INSERT_TAIL(&psql_tables, table, list);
 	ast_rwlock_rdlock(&table->lock);
 	AST_LIST_UNLOCK(&psql_tables);
+	ast_mutex_unlock(&pgsql_lock);
 	return table;
 }
 
@@ -603,7 +614,7 @@
 		return -1;
 	}
 
-	if (!(table = find_table(tablename))) {
+	if (!(table = find_table(database, tablename))) {
 		ast_log(LOG_ERROR, "Table '%s' does not exist!!\n", tablename);
 		return -1;
 	}
@@ -746,7 +757,7 @@
 		return -1;
 	}
 
-	if (!(table = find_table(tablename))) {
+	if (!(table = find_table(database, tablename))) {
 		ast_log(LOG_ERROR, "Table '%s' does not exist!!\n", tablename);
 		return -1;
 	}
@@ -1141,7 +1152,7 @@
 static int require_pgsql(const char *database, const char *tablename, va_list ap)
 {
 	struct columns *column;
-	struct tables *table = find_table(tablename);
+	struct tables *table = find_table(database, tablename);
 	char *elm;
 	int type, size, res = 0;
 
@@ -1543,7 +1554,7 @@
 		AST_LIST_UNLOCK(&psql_tables);
 	} else if (a->argc == 5) {
 		/* List of columns */
-		if ((cur = find_table(a->argv[4]))) {
+		if ((cur = find_table(NULL, a->argv[4]))) {
 			struct columns *col;
 			ast_cli(a->fd, "Columns for Table Cache '%s':\n", a->argv[4]);
 			ast_cli(a->fd, "%-20.20s %-20.20s %-3.3s %-8.8s\n", "Name", "Type", "Len", "Nullable");




More information about the asterisk-commits mailing list