russell
By: a guest | Sep 6th, 2010 | Syntax:
None | Size: 2.07 KB | Hits: 23 | Expires: Never
Index: main/db.c
===================================================================
--- main/db.c (revision 285158)
+++ main/db.c (working copy)
@@ -50,7 +50,10 @@
static DB *astdb;
AST_MUTEX_DEFINE_STATIC(dblock);
+static ast_cond_t dbcond;
+static void db_sync(void);
+
static int dbinit(void)
{
if (!astdb && !(astdb = dbopen(ast_config_AST_DB, O_CREAT | O_RDWR, AST_FILE_MODE, DB_BTREE, NULL))) {
@@ -130,7 +133,7 @@
counter++;
}
}
- astdb->sync(astdb, 0);
+ db_sync();
ast_mutex_unlock(&dblock);
return counter;
}
@@ -155,7 +158,7 @@
data.data = (char *) value;
data.size = strlen(value) + 1;
res = astdb->put(astdb, &key, &data, 0);
- astdb->sync(astdb, 0);
+ db_sync();
ast_mutex_unlock(&dblock);
if (res)
ast_log(LOG_WARNING, "Unable to put value '%s' for key '%s' in family '%s'\n", value, keys, family);
@@ -224,7 +227,7 @@
key.size = fullkeylen + 1;
res = astdb->del(astdb, &key, 0);
- astdb->sync(astdb, 0);
+ db_sync();
ast_mutex_unlock(&dblock);
@@ -662,8 +665,46 @@
return 0;
}
+/*!
+ * \internal
+ * \brief Signal the astdb sync thread to do its thing.
+ *
+ * \note dblock is assumed to be held when calling this function.
+ */
+static void db_sync(void)
+{
+ ast_cond_signal(&dbcond);
+}
+
+/*!
+ * \internal
+ * \brief astdb sync thread
+ *
+ * This thread is in charge of syncing astdb to disk after every change.
+ * By pushing it off to this thread to take care of, this I/O bound operation
+ * will not block other threads from performing other critical processing.
+ */
+static void *db_sync_thread(void *data)
+{
+ for (;;) {
+ ast_mutex_lock(&dblock);
+ ast_cond_wait(&dbcond, &dblock);
+ astdb->sync(astdb, 0);
+ ast_mutex_unlock(&dblock);
+ }
+
+ return NULL;
+}
+
int astdb_init(void)
{
+ pthread_t dont_care;
+
+ ast_cond_init(&dbcond, NULL);
+ if (ast_pthread_create_background(&dont_care, NULL, db_sync_thread, NULL)) {
+ return -1;
+ }
+
dbinit();
ast_cli_register_multiple(cli_database, ARRAY_LEN(cli_database));
ast_manager_register("DBGet", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_dbget, "Get DB Entry");