[asterisk-commits] twilson: branch twilson/res_config_sqlite3 r334292 - /team/twilson/res_config...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Sep 1 23:33:48 CDT 2011
Author: twilson
Date: Thu Sep 1 23:33:44 2011
New Revision: 334292
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=334292
Log:
Properly handle reloads
Modified:
team/twilson/res_config_sqlite3/res/res_config_sqlite3.c
Modified: team/twilson/res_config_sqlite3/res/res_config_sqlite3.c
URL: http://svnview.digium.com/svn/asterisk/team/twilson/res_config_sqlite3/res/res_config_sqlite3.c?view=diff&rev=334292&r1=334291&r2=334292
==============================================================================
--- team/twilson/res_config_sqlite3/res/res_config_sqlite3.c (original)
+++ team/twilson/res_config_sqlite3/res/res_config_sqlite3.c Thu Sep 1 23:33:44 2011
@@ -113,9 +113,12 @@
{
struct realtime_sqlite3_db *db = obj;
+ ast_debug(1, "Destroying db: %s\n", db->name);
ast_string_field_free_memory(db);
if (db->handle) {
+ ao2_lock(db);
sqlite3_close(db->handle);
+ ao2_unlock(db);
}
}
@@ -139,7 +142,7 @@
static void mark_all_databases_dirty(void)
{
- ao2_callback(databases, OBJ_MULTIPLE | OBJ_NODATA | OBJ_UNLINK, mark_dirty_cb, NULL);
+ ao2_callback(databases, OBJ_MULTIPLE | OBJ_NODATA, mark_dirty_cb, NULL);
}
static int is_dirty_cb(void *obj, void *arg, int flags)
@@ -171,27 +174,47 @@
ast_debug(3, "DB: %s SQL: %s\n", db->name, sql);
}
-static struct realtime_sqlite3_db *new_realtime_sqlite3_db(struct ast_config *config, const char *cat)
+static int create_or_update_db(struct ast_config *config, const char *cat)
{
struct ast_variable *var;
struct realtime_sqlite3_db *db;
-
- if (!(db = ao2_alloc(sizeof(*db), db_destructor))) {
- return NULL;
- }
-
- if (ast_string_field_init(db, 64)) {
+ int new = 0, reopen = 0;
+
+ if (!(db = find_database(cat))) {
+ if (!(db = ao2_alloc(sizeof(*db), db_destructor))) {
+ return -1;
+ }
+ new = 1;
+ }
+
+ /* At this point db has a refcount of 1 (alloc'd) if new or 2 (linked and found) if !new
+ * It is very important than any error exit unlinks !new entries. We could just throw
+ * away the find_database ref above and rely on the link, but we can't be guaranteed
+ * that some code sometime won't be added that unlinks us from another thread, etc. */
+
+ ao2_lock(db);
+
+ if (new && ast_string_field_init(db, 64)) {
+ ao2_unlock(db);
unref_db(&db);
- return NULL;
+ return -1;
}
/* Set defaults */
db->requirements = REALTIME_SQLITE3_REQ_WARN;
db->batch = 100;
+ db->debug = 0;
+ db->dirty = 0;
ast_string_field_set(db, name, cat);
for (var = ast_variable_browse(config, cat); var; var = var->next) {
if (!strcasecmp(var->name, "dbfile")) {
+ if (!new && strcmp(db->filename, var->value)) {
+ /* We are updating the db with this name to a new location */
+ ast_debug(1, "DB %s moving from %s to %s\n", db->name, db->filename, var->value);
+ sqlite3_close(db->handle);
+ reopen = 1;
+ }
ast_string_field_set(db, filename, var->value);
} else if (!strcasecmp(var->name, "requirements")) {
db->requirements = str_to_requirements(var->value);
@@ -204,25 +227,35 @@
if (ast_strlen_zero(db->filename)) {
ast_log(LOG_WARNING, "Must specify dbfile in res_config_sqlite3.conf\n");
+ ao2_unlock(db);
unref_db(&db);
- return NULL;
- }
-
- if (sqlite3_open(db->filename, &db->handle) != SQLITE_OK) {
+ if (!new) {
+ ao2_unlink(databases, db);
+ }
+ return -1;
+ }
+
+ if ((new || reopen) && sqlite3_open(db->filename, &db->handle) != SQLITE_OK) {
ast_log(LOG_WARNING, "Could not open %s: %s\n", db->filename, sqlite3_errmsg(db->handle));
+ ao2_unlock(db);
unref_db(&db);
- return NULL;
+ if (!new) {
+ ao2_unlink(databases, db);
+ }
+ return -1;
}
if (db->debug) {
sqlite3_trace(db->handle, trace_cb, db);
}
- return db;
-}
-
-static int update_realtime_sqlite3_db(struct ast_config *config, const char *cat)
-{
+ if (new) {
+ ao2_link(databases, db);
+ }
+
+ ao2_unlock(db);
+ unref_db(&db);
+
return 0;
}
@@ -858,22 +891,14 @@
config == CONFIG_STATUS_FILEMISSING ? "Missing" : "Invalid", config_filename);
} else {
const char *cat;
- struct realtime_sqlite3_db *db;
mark_all_databases_dirty();
for (cat = ast_category_browse(config, NULL); cat; cat = ast_category_browse(config, cat)) {
if (!strcasecmp(cat, "general")) {
continue;
}
- if (!(db = find_database(cat))) {
- if (!(db = new_realtime_sqlite3_db(config, cat))) {
- continue;
- }
- ao2_link(databases, db);
- unref_db(&db);
- } else {
- update_realtime_sqlite3_db(config, cat);
- unref_db(&db);
+ if (create_or_update_db(config, cat)) {
+ continue;
}
}
unlink_dirty_databases();
More information about the asterisk-commits
mailing list