Skip to content

Commit

Permalink
Fix MySQL memory leak
Browse files Browse the repository at this point in the history
Before commit 1f987e7, there were issues upgrading my music database to
the latest format (because of duplicate keys, which are solved by using
REPLACE instead of INSERT).

This pointed out a severe memory leak in
xbmc/dbwrappers/mysqldataset.cpp, which is confirmed by valgrind.

This is an attempt to fix the leak, and should solve xbmc#12459.
  • Loading branch information
stintel committed Oct 9, 2012
1 parent 054a227 commit f102080
Showing 1 changed file with 14 additions and 0 deletions.
14 changes: 14 additions & 0 deletions xbmc/dbwrappers/mysqldataset.cpp
Expand Up @@ -240,7 +240,10 @@ int MysqlDatabase::copy(const char *backup_name) {
// create the new database
sprintf(sql, "CREATE DATABASE `%s`", backup_name);
if ( (ret=query_with_reconnect(sql)) != MYSQL_OK )
{
mysql_free_result(res);
throw DbErrors("Can't create database for copy: '%s' (%d)", db.c_str(), ret);
}

MYSQL_ROW row;

Expand All @@ -252,15 +255,22 @@ int MysqlDatabase::copy(const char *backup_name) {
backup_name, row[0], row[0]);

if ( (ret=query_with_reconnect(sql)) != MYSQL_OK )
{
mysql_free_result(res);
throw DbErrors("Can't copy schema for table '%s'\nError: %s", db.c_str(), ret);
}

// copy the table data
sprintf(sql, "INSERT INTO %s.%s SELECT * FROM %s",
backup_name, row[0], row[0]);

if ( (ret=query_with_reconnect(sql)) != MYSQL_OK )
{
mysql_free_result(res);
throw DbErrors("Can't copy data for table '%s'\nError: %s", row[0], ret);
}
}
mysql_free_result(res);

// after table are recreated and repopulated we can recreate views
// grab a list of views and their definitions
Expand All @@ -279,7 +289,10 @@ int MysqlDatabase::copy(const char *backup_name) {
backup_name, row[0], row[1]);

if ( (ret=query_with_reconnect(sql)) != MYSQL_OK )
{
mysql_free_result(resViews);
throw DbErrors("Can't create view '%s'\nError: %s", db.c_str(), ret);
}
}
mysql_free_result(resViews);
}
Expand Down Expand Up @@ -336,6 +349,7 @@ long MysqlDatabase::nextid(const char* sname) {
lengths = mysql_fetch_lengths(res);
CLog::Log(LOGINFO,"Next id is [%.*s] ", (int) lengths[0], row[0]);
sprintf(sqlcmd,"update %s set nextid=%d where seq_name = '%s'",seq_table,id,sname);
mysql_free_result(res);
if ((last_err = query_with_reconnect(sqlcmd) != 0)) return DB_UNEXPECTED_RESULT;
return id;
}
Expand Down

0 comments on commit f102080

Please sign in to comment.