[asterisk-commits] twilson: branch twilson/res_config_sqlite3 r334294 - in /team/twilson/res_con...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Sep 2 09:25:41 CDT 2011
Author: twilson
Date: Fri Sep 2 09:25:30 2011
New Revision: 334294
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=334294
Log:
Add batch support
BUG: doing a reload where the batch value changes doesn't work right now.
I will proably rework the reload stuff a little more tomorrow.
Modified:
team/twilson/res_config_sqlite3/configs/res_config_sqlite3.conf.sample
team/twilson/res_config_sqlite3/res/res_config_sqlite3.c
Modified: team/twilson/res_config_sqlite3/configs/res_config_sqlite3.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/twilson/res_config_sqlite3/configs/res_config_sqlite3.conf.sample?view=diff&rev=334294&r1=334293&r2=334294
==============================================================================
--- team/twilson/res_config_sqlite3/configs/res_config_sqlite3.conf.sample (original)
+++ team/twilson/res_config_sqlite3/configs/res_config_sqlite3.conf.sample Fri Sep 2 09:25:30 2011
@@ -23,5 +23,9 @@
; made during this time could be lost. Due to the nearly 100x performance
; benefit, the default is 100 ms. Set to 0 to disable batching.
;
+; PLEASE NOTE: If you need to write to the database from another connection
+; you will need to set batch=0 as the transactions will cause the database
+; to lock for writing.
+;
;batch=1000
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=334294&r1=334293&r2=334294
==============================================================================
--- team/twilson/res_config_sqlite3/res/res_config_sqlite3.c (original)
+++ team/twilson/res_config_sqlite3/res/res_config_sqlite3.c Fri Sep 2 09:25:30 2011
@@ -44,7 +44,8 @@
#include "asterisk/config.h"
#include "asterisk/paths.h"
#include "asterisk/astobj2.h"
-
+#include "asterisk/lock.h"
+#include "asterisk/utils.h"
/*** DOCUMENTATION
***/
@@ -84,9 +85,12 @@
AST_STRING_FIELD(filename);
);
sqlite3 *handle;
+ pthread_t syncthread;
+ ast_cond_t cond;
unsigned int requirements:2;
unsigned int dirty:1;
unsigned int debug:1;
+ unsigned int exiting:1;
unsigned int batch;
};
@@ -94,6 +98,8 @@
#define DB_BUCKETS 7
AST_MUTEX_DEFINE_STATIC(config_lock);
+
+static int realtime_sqlite3_execute_handle(struct realtime_sqlite3_db *db, const char *sql, int (*callback)(void*, int, char **, char **), void *arg, int sync);
static int db_hash_fn(const void *obj, const int flags)
{
@@ -115,6 +121,8 @@
ast_debug(1, "Destroying db: %s\n", db->name);
ast_string_field_free_memory(db);
+ db->exiting = 1;
+ ast_cond_signal(&db->cond);
if (db->handle) {
ao2_lock(db);
sqlite3_close(db->handle);
@@ -174,6 +182,32 @@
ast_debug(3, "DB: %s SQL: %s\n", db->name, sql);
}
+static void *db_sync_thread(void *data)
+{
+ struct realtime_sqlite3_db *db = data;
+ ao2_lock(db);
+ realtime_sqlite3_execute_handle(db, "BEGIN TRANSACTION", NULL, NULL, 0);
+ for (;;) {
+ /* We're ok with spurious wakeups, so we don't worry about a predicate */
+ ast_cond_wait(&db->cond, ao2_object_get_lockaddr(db));
+ if (realtime_sqlite3_execute_handle(db, "COMMIT", NULL, NULL, 0) < 0) {
+ realtime_sqlite3_execute_handle(db, "ROLLBACK", NULL, NULL, 0);
+ }
+ if (db->exiting) {
+ ao2_unlock(db);
+ break;
+ }
+ realtime_sqlite3_execute_handle(db, "BEGIN TRANSACTION", NULL, NULL, 0);
+ ao2_unlock(db);
+ usleep(1000 * db->batch);
+ ao2_lock(db);
+ }
+
+ unref_db(&db);
+
+ return NULL;
+}
+
static int create_or_update_db(struct ast_config *config, const char *cat)
{
struct ast_variable *var;
@@ -188,7 +222,7 @@
}
/* 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
+ * It is very important that 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. */
@@ -251,6 +285,9 @@
if (new) {
ao2_link(databases, db);
+ ast_cond_init(&db->cond, NULL);
+ ao2_ref(db, +1);
+ ast_pthread_create_background(&db->syncthread, NULL, db_sync_thread, db);
}
ao2_unlock(db);
@@ -368,7 +405,7 @@
* \retval -1 ERROR
* \retval > -1 Number of rows changed
*/
-static int realtime_sqlite3_execute_handle(struct realtime_sqlite3_db *db, const char *sql, int (*callback)(void*, int, char **, char **), void *arg)
+static int realtime_sqlite3_execute_handle(struct realtime_sqlite3_db *db, const char *sql, int (*callback)(void*, int, char **, char **), void *arg, int sync)
{
int res = 0;
char *errmsg;
@@ -383,6 +420,10 @@
}
ao2_unlock(db);
+ if (sync) {
+ ast_cond_signal(&db->cond);
+ }
+
return res;
}
@@ -391,7 +432,7 @@
* \retval -1 ERROR
* \retval > -1 Number of rows changed
*/
-static int realtime_sqlite3_execute(const char *database, const char *sql, int (*callback)(void*, int, char **, char **), void *arg)
+static int realtime_sqlite3_execute(const char *database, const char *sql, int (*callback)(void*, int, char **, char **), void *arg, int sync)
{
struct realtime_sqlite3_db *db;
int res;
@@ -401,7 +442,7 @@
return -1;
}
- res = realtime_sqlite3_execute_handle(db, sql, callback, arg);
+ res = realtime_sqlite3_execute_handle(db, sql, callback, arg, sync);
ao2_ref(db, -1);
return res;
@@ -431,7 +472,7 @@
args.flags = flags;
args.who_asked = who_asked;
- realtime_sqlite3_execute(database, sql, static_realtime_cb, &args);
+ realtime_sqlite3_execute(database, sql, static_realtime_cb, &args, 0);
sqlite3_free(sql);
@@ -466,7 +507,7 @@
ast_str_append(&sql, 0, "%s", " LIMIT 1");
}
- if (realtime_sqlite3_execute(database, ast_str_buffer(sql), is_multi ? append_row_to_cfg : row_to_varlist, arg) < 0) {
+ if (realtime_sqlite3_execute(database, ast_str_buffer(sql), is_multi ? append_row_to_cfg : row_to_varlist, arg, 0) < 0) {
ast_free(sql);
return -1;
}
@@ -536,7 +577,7 @@
ast_str_append(&sql, 0, " WHERE %s%s '%s'", keyfield, strchr(keyfield, ' ') ? "" : " =", entity);
- tmp = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL);
+ tmp = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);
ast_free(sql);
return tmp;
@@ -587,7 +628,7 @@
ast_str_append(&sql, 0, "%s", ast_str_buffer(where_clause));
- tmp = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL);
+ tmp = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);
ast_free(sql);
ast_free(where_clause);
@@ -631,7 +672,7 @@
ast_str_append(&sql, 0, "%s)", ast_str_buffer(values));
- tmp = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL);
+ tmp = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);
ast_free(sql);
ast_free(values);
@@ -666,7 +707,7 @@
}
}
- tmp = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL);
+ tmp = realtime_sqlite3_execute(database, ast_str_buffer(sql), NULL, NULL, 1);
ast_free(sql);
@@ -727,7 +768,7 @@
ast_str_append(&sql, 0, ")");
- tmp = realtime_sqlite3_execute_handle(db, ast_str_buffer(sql), NULL, NULL) < 0 ? -1 : 0;
+ tmp = realtime_sqlite3_execute_handle(db, ast_str_buffer(sql), NULL, NULL, 1) < 0 ? -1 : 0;
ast_free(sql);
return tmp;
@@ -750,7 +791,7 @@
return -1;
}
- if (!(res = realtime_sqlite3_execute_handle(db, sql, NULL, NULL) < 0 ? -1 : 0)) {
+ if (!(res = realtime_sqlite3_execute_handle(db, sql, NULL, NULL, 1) < 0 ? -1 : 0)) {
ast_log(LOG_NOTICE, "Creating column '%s' type %s for table %s\n", column, sqltype, table);
}
@@ -826,7 +867,7 @@
return -1;
}
- if ((res = realtime_sqlite3_execute_handle(db, sql, add_column_name, columns)) < 0) {
+ if ((res = realtime_sqlite3_execute_handle(db, sql, add_column_name, columns, 0)) < 0) {
unref_db(&db);
ao2_ref(columns, -1);
sqlite3_free(sql);
@@ -923,6 +964,7 @@
ao2_ref(databases, -1);
databases = NULL;
ast_mutex_unlock(&config_lock);
+
return 0;
}
More information about the asterisk-commits
mailing list