summaryrefslogtreecommitdiff
path: root/main/db.c
diff options
context:
space:
mode:
authorRussell Bryant <russell@russellbryant.com>2010-09-13 22:13:27 +0000
committerRussell Bryant <russell@russellbryant.com>2010-09-13 22:13:27 +0000
commitf13654961abfacec22aadb67319f3cb0d8dcb27f (patch)
tree928be67a79398e6870347e80c5466d123af8c7da /main/db.c
parent7b2c877fcb718ab23a0ee4bb85d2b4311dad695d (diff)
Merged revisions 286112 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.8 ........ r286112 | russell | 2010-09-10 15:31:58 -0500 (Fri, 10 Sep 2010) | 9 lines Rate limit calls to fsync() to 1 per second after astdb updates. Astdb was determined to be one of the most significant bottlenecks in SIP registration processing. This patch improved the speed of an astdb load test by 50000% (yes, Fifty-Thousand Percent). On this particular load test setup, this doubled the number of SIP registrations the server could handle. Review: https://reviewboard.asterisk.org/r/825/ ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@286498 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/db.c')
-rw-r--r--main/db.c51
1 files changed, 48 insertions, 3 deletions
diff --git a/main/db.c b/main/db.c
index 9129b321c..ce8a9069c 100644
--- a/main/db.c
+++ b/main/db.c
@@ -102,6 +102,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
static DB *astdb;
AST_MUTEX_DEFINE_STATIC(dblock);
+static ast_cond_t dbcond;
+
+static void db_sync(void);
static int dbinit(void)
{
@@ -182,7 +185,7 @@ int ast_db_deltree(const char *family, const char *keytree)
counter++;
}
}
- astdb->sync(astdb, 0);
+ db_sync();
ast_mutex_unlock(&dblock);
return counter;
}
@@ -207,7 +210,7 @@ int ast_db_put(const char *family, const char *keys, const char *value)
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);
@@ -276,7 +279,7 @@ int ast_db_del(const char *family, const char *keys)
key.size = fullkeylen + 1;
res = astdb->del(astdb, &key, 0);
- astdb->sync(astdb, 0);
+ db_sync();
ast_mutex_unlock(&dblock);
@@ -718,8 +721,50 @@ static int manager_dbdeltree(struct mansession *s, const struct message *m)
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 a 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.
+ * If changes happen rapidly, this thread will also ensure that the sync
+ * operations are rate limited.
+ */
+static void *db_sync_thread(void *data)
+{
+ ast_mutex_lock(&dblock);
+ for (;;) {
+ ast_cond_wait(&dbcond, &dblock);
+ ast_mutex_unlock(&dblock);
+ sleep(1);
+ ast_mutex_lock(&dblock);
+ astdb->sync(astdb, 0);
+ }
+
+ 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_xml("DBGet", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_dbget);