[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