[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