summaryrefslogtreecommitdiff
path: root/main/db.c
diff options
context:
space:
mode:
authorMatthew Jordan <mjordan@digium.com>2012-11-04 01:19:43 +0000
committerMatthew Jordan <mjordan@digium.com>2012-11-04 01:19:43 +0000
commita243f4f153bf405bf1d2475c1394b366df5acf25 (patch)
tree53f3a465ac859617f8392857b43cd9f233c6f319 /main/db.c
parentff469e9d5d61b8fc2b24b0965182a380fb347155 (diff)
Properly finalize prepared SQLite3 statements to prevent memory leak
The AstDB uses prepared SQLite3 statements to retrieve data from the SQLite3 database. These statements should be finalized during Asterisk shutdown so that the SQLite3 database can be properly closed. Failure to finalize the statements results in a memory leak and a failure when closing the database. This patch fixes those issues by ensuring that all prepared statements are properly finalized at shutdown. (closes issue ASTERISK-20647) Reported by: Corey Farrell patches: astdb-sqlite3_close.patch uploaded by Corey Farrell (license 5909) ........ Merged revisions 375761 from http://svn.asterisk.org/svn/asterisk/branches/10 ........ Merged revisions 375763 from http://svn.asterisk.org/svn/asterisk/branches/11 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@375770 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/db.c')
-rw-r--r--main/db.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/main/db.c b/main/db.c
index bb27a9e31..6ccdb17f9 100644
--- a/main/db.c
+++ b/main/db.c
@@ -141,6 +141,36 @@ static int init_stmt(sqlite3_stmt **stmt, const char *sql, size_t len)
return 0;
}
+/*! \internal
+ * \brief Clean up the prepared SQLite3 statement
+ * \note dblock should already be locked prior to calling this method
+ */
+static int clean_stmt(sqlite3_stmt *stmt, const char *sql)
+{
+ if (sqlite3_finalize(stmt) != SQLITE_OK) {
+ ast_log(LOG_WARNING, "Couldn't finalize statement '%s': %s\n", sql, sqlite3_errmsg(astdb));
+ return -1;
+ }
+ return 0;
+}
+
+/*! \internal
+ * \brief Clean up all prepared SQLite3 statements
+ * \note dblock should already be locked prior to calling this method
+ */
+static void clean_statements(void)
+{
+ clean_stmt(get_stmt, get_stmt_sql);
+ clean_stmt(del_stmt, del_stmt_sql);
+ clean_stmt(deltree_stmt, deltree_stmt_sql);
+ clean_stmt(deltree_all_stmt, deltree_all_stmt_sql);
+ clean_stmt(gettree_stmt, gettree_stmt_sql);
+ clean_stmt(gettree_all_stmt, gettree_all_stmt_sql);
+ clean_stmt(showkey_stmt, showkey_stmt_sql);
+ clean_stmt(put_stmt, put_stmt_sql);
+ clean_stmt(create_astdb_stmt, create_astdb_stmt_sql);
+}
+
static int init_statements(void)
{
/* Don't initialize create_astdb_statment here as the astdb table needs to exist
@@ -955,6 +985,7 @@ static void *db_sync_thread(void *data)
/*! \internal \brief Clean up resources on Asterisk shutdown */
static void astdb_atexit(void)
{
+ ast_cli_unregister_multiple(cli_database, ARRAY_LEN(cli_database));
ast_manager_unregister("DBGet");
ast_manager_unregister("DBPut");
ast_manager_unregister("DBDel");
@@ -969,7 +1000,10 @@ static void astdb_atexit(void)
pthread_join(syncthread, NULL);
ast_mutex_lock(&dblock);
- sqlite3_close(astdb);
+ clean_statements();
+ if (sqlite3_close(astdb) == SQLITE_OK) {
+ astdb = NULL;
+ }
ast_mutex_unlock(&dblock);
}