1
0
mirror of https://github.com/mariadb-corporation/mariadb-connector-c.git synced 2025-08-08 14:02:17 +03:00

(Corrected) Fix for CONC-118: memory leak when reconnecting

This commit is contained in:
Georg Richter
2015-01-14 15:29:27 +01:00
parent 5c471dc0d8
commit 0e92a68589
2 changed files with 39 additions and 4 deletions

View File

@@ -2022,11 +2022,12 @@ static my_bool mysql_reconnect(MYSQL *mysql)
} }
tmp_mysql.reconnect= mysql->reconnect; tmp_mysql.reconnect= mysql->reconnect;
bzero((char*) &mysql->options,sizeof(mysql->options));
if (!mysql_real_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd, if (!mysql_real_connect(&tmp_mysql,mysql->host,mysql->user,mysql->passwd,
mysql->db, mysql->port, mysql->unix_socket, mysql->db, mysql->port, mysql->unix_socket,
mysql->client_flag | CLIENT_REMEMBER_OPTIONS)) mysql->client_flag | CLIENT_REMEMBER_OPTIONS))
{ {
/* don't free options (CONC-118) */
memset(&tmp_mysql.options, 0, sizeof(struct st_mysql_options));
my_set_error(mysql, tmp_mysql.net.last_errno, my_set_error(mysql, tmp_mysql.net.last_errno,
tmp_mysql.net.sqlstate, tmp_mysql.net.sqlstate,
tmp_mysql.net.last_error); tmp_mysql.net.last_error);
@@ -2046,14 +2047,16 @@ static my_bool mysql_reconnect(MYSQL *mysql)
stmt->state= MYSQL_STMT_INITTED; stmt->state= MYSQL_STMT_INITTED;
SET_CLIENT_STMT_ERROR(stmt, CR_SERVER_LOST, SQLSTATE_UNKNOWN, 0); SET_CLIENT_STMT_ERROR(stmt, CR_SERVER_LOST, SQLSTATE_UNKNOWN, 0);
} }
else
tmp_mysql.stmts= list_add(tmp_mysql.stmts, &stmt->list);
} }
tmp_mysql.free_me= mysql->free_me;
tmp_mysql.stmts= mysql->stmts;
/* Don't free options, we moved them to tmp_mysql */
memset(&mysql->options, 0, sizeof(mysql->options));
mysql->free_me=0; mysql->free_me=0;
mysql->stmts= NULL; mysql->stmts= NULL;
mysql_close(mysql); mysql_close(mysql);
memset(&mysql->options, 0, sizeof(mysql->options));
*mysql=tmp_mysql; *mysql=tmp_mysql;
mysql->reconnect= 1; mysql->reconnect= 1;
net_clear(&mysql->net); net_clear(&mysql->net);

View File

@@ -638,7 +638,39 @@ int test_connection_timeout(MYSQL *my)
return OK; return OK;
} }
/* test should run with valgrind */
static int test_conc118(MYSQL *mysql)
{
int rc;
mysql->reconnect= 1;
mysql->options.unused_1= 1;
rc= mysql_kill(mysql, mysql_thread_id(mysql));
sleep(2);
rc= mysql_query(mysql, "SET @a:=1");
check_mysql_rc(rc, mysql);
FAIL_IF(mysql->options.unused_1 != 1, "options got lost");
rc= mysql_kill(mysql, mysql_thread_id(mysql));
sleep(2);
mysql->host= "foo";
rc= mysql_query(mysql, "SET @a:=1");
FAIL_IF(!rc, "error expected");
mysql->host= hostname;
rc= mysql_query(mysql, "SET @a:=1");
check_mysql_rc(rc, mysql);
return OK;
}
struct my_tests_st my_tests[] = { struct my_tests_st my_tests[] = {
{"test_conc118", test_conc118, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_conc66", test_conc66, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc66", test_conc66, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
{"test_bug20023", test_bug20023, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"test_bug20023", test_bug20023, TEST_CONNECTION_NEW, 0, NULL, NULL},
{"test_bug31669", test_bug31669, TEST_CONNECTION_NEW, 0, NULL, NULL}, {"test_bug31669", test_bug31669, TEST_CONNECTION_NEW, 0, NULL, NULL},