You've already forked mariadb-connector-c
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:
@@ -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);
|
||||||
|
@@ -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},
|
||||||
|
Reference in New Issue
Block a user