[asterisk-commits] tilghman: branch tilghman/adaptive_realtime r120787 - /team/tilghman/adaptive...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Jun 5 13:33:41 CDT 2008


Author: tilghman
Date: Thu Jun  5 13:33:40 2008
New Revision: 120787

URL: http://svn.digium.com/view/asterisk?view=rev&rev=120787
Log:
Found the evil nasty lockup

Modified:
    team/tilghman/adaptive_realtime/res/res_config_pgsql.c

Modified: team/tilghman/adaptive_realtime/res/res_config_pgsql.c
URL: http://svn.digium.com/view/asterisk/team/tilghman/adaptive_realtime/res/res_config_pgsql.c?view=diff&rev=120787&r1=120786&r2=120787
==============================================================================
--- team/tilghman/adaptive_realtime/res/res_config_pgsql.c (original)
+++ team/tilghman/adaptive_realtime/res/res_config_pgsql.c Thu Jun  5 13:33:40 2008
@@ -78,11 +78,13 @@
 static int parse_config(int reload);
 static int pgsql_reconnect(const char *database);
 static char *handle_cli_realtime_pgsql_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
+static char *handle_cli_realtime_pgsql_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
 
 enum { RQ_WARN, RQ_CREATECLOSE, RQ_CREATECHAR } requirements;
 
 static struct ast_cli_entry cli_realtime[] = {
 	AST_CLI_DEFINE(handle_cli_realtime_pgsql_status, "Shows connection information for the PostgreSQL RealTime driver"),
+	AST_CLI_DEFINE(handle_cli_realtime_pgsql_cache, "Shows cached tables within the PostgreSQL realtime driver"),
 };
 
 static void destroy_table(struct tables *table)
@@ -110,15 +112,20 @@
 	AST_LIST_LOCK(&psql_tables);
 	AST_LIST_TRAVERSE(&psql_tables, table, list) {
 		if (!strcasecmp(table->name, tablename)) {
+			ast_debug(1, "Found table in cache; now locking\n");
 			ast_mutex_lock(&table->lock);
+			ast_debug(1, "Lock cached table; now returning\n");
 			AST_LIST_UNLOCK(&psql_tables);
 			return table;
 		}
 	}
+
+	ast_debug(1, "Table '%s' not found in cache, querying now\n", tablename);
 
 	/* Not found, scan the table */
 	ast_str_set(&sql, 0, "SELECT a.attname, t.typname, a.attlen, a.attnotnull, d.adsrc 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", tablename);
 	result = PQexec(pgsqlConn, sql->str);
+	ast_debug(1, "Query of table structure complete.  Now retrieving results.\n");
 	if (PQresultStatus(result) != PGRES_TUPLES_OK) {
 		pgerror = PQresultErrorMessage(result);
 		ast_log(LOG_ERROR, "Failed to query database columns: %s\n", pgerror);
@@ -977,6 +984,7 @@
 					continue;
 				}
 				ast_str_set(&sql, 0, "ALTER TABLE %s ADD COLUMN %s %s", tablename, elm, fieldtype->str);
+				ast_debug(1, "About to lock pgsql_lock (running alter on table '%s' to add column '%s')\n", tablename, elm);
 
 				ast_mutex_lock(&pgsql_lock);
 				if (!pgsql_reconnect(database)) {
@@ -987,11 +995,15 @@
 					continue;
 				}
 
+				ast_debug(1, "About to run ALTER query on table '%s' to add column '%s'\n", tablename, elm);
 				res = PQexec(pgsqlConn, sql->str);
+				ast_debug(1, "Finished running ALTER query on table '%s'\n", tablename);
 				if (PQresultStatus(res) != PGRES_COMMAND_OK) {
 					ast_log(LOG_ERROR, "Unable to add column: %s\n", sql->str);
 				}
 				PQclear(res);
+				ast_mutex_unlock(&pgsql_lock);
+
 				ast_free(sql);
 				ast_free(fieldtype);
 			}
@@ -999,6 +1011,28 @@
 	}
 	ast_mutex_unlock(&table->lock);
 	return res;
+}
+
+static int unload_pgsql(const char *database, const char *tablename)
+{
+	struct tables *cur;
+	ast_debug(1, "About to lock table cache list\n");
+	AST_LIST_LOCK(&psql_tables);
+	ast_debug(1, "About to traverse table cache list\n");
+	AST_LIST_TRAVERSE_SAFE_BEGIN(&psql_tables, cur, list) {
+		if (strcmp(cur->name, tablename) == 0) {
+			ast_debug(1, "About to remove matching cache entry\n");
+			AST_LIST_REMOVE_CURRENT(list);
+			ast_debug(1, "About to destroy matching cache entry\n");
+			destroy_table(cur);
+			ast_debug(1, "Cache entry destroyed\n");
+			break;
+		}
+	}
+	AST_LIST_TRAVERSE_SAFE_END
+	AST_LIST_UNLOCK(&psql_tables);
+	ast_debug(1, "About to return\n");
+	return cur ? 0 : -1;
 }
 
 static struct ast_config_engine pgsql_engine = {
@@ -1010,6 +1044,7 @@
 	.destroy_func = destroy_pgsql,
 	.update_func = update_pgsql,
 	.require_func = require_pgsql,
+	.unload_func = unload_pgsql,
 };
 
 static int load_module(void)
@@ -1210,6 +1245,60 @@
 		ast_debug(1, "PostgreSQL RealTime: One or more of the parameters in the config does not pass our validity checks.\n");
 		return 1;
 	}
+}
+
+static char *handle_cli_realtime_pgsql_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	struct tables *cur;
+	int l, which;
+	char *ret = NULL;
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "realtime pgsql cache";
+		e->usage =
+			"Usage: realtime pgsql cache [<table>]\n"
+			"       Shows table cache for the PostgreSQL RealTime driver\n";
+		return NULL;
+	case CLI_GENERATE:
+		if (a->argc != 3) {
+			return NULL;
+		}
+		l = strlen(a->word);
+		which = 0;
+		AST_LIST_LOCK(&psql_tables);
+		AST_LIST_TRAVERSE(&psql_tables, cur, list) {
+			if (!strncasecmp(a->word, cur->name, l) && ++which > a->n) {
+				ret = ast_strdup(cur->name);
+				break;
+			}
+		}
+		AST_LIST_UNLOCK(&psql_tables);
+		return ret;
+	}
+
+	if (a->argc == 3) {
+		/* List of tables */
+		AST_LIST_LOCK(&psql_tables);
+		AST_LIST_TRAVERSE(&psql_tables, cur, list) {
+			ast_cli(a->fd, "%s\n", cur->name);
+		}
+		AST_LIST_UNLOCK(&psql_tables);
+	} else if (a->argc == 4) {
+		/* List of columns */
+		if ((cur = find_table(a->argv[3]))) {
+			struct columns *col;
+			ast_cli(a->fd, "Columns for Table Cache '%s':\n", a->argv[3]);
+			ast_cli(a->fd, "%-20.20s %-20.20s %-3.3s %-8.8s\n", "Name", "Type", "Len", "Nullable");
+			AST_LIST_TRAVERSE(&cur->columns, col, list) {
+				ast_cli(a->fd, "%-20.20s %-20.20s %3d %-8.8s\n", col->name, col->type, col->len, col->notnull ? "NOT NULL" : "");
+			}
+			ast_mutex_unlock(&cur->lock);
+		} else {
+			ast_cli(a->fd, "No such table '%s'\n", a->argv[3]);
+		}
+	}
+	return 0;
 }
 
 static char *handle_cli_realtime_pgsql_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)




More information about the asterisk-commits mailing list