You've already forked mariadb-connector-c
mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-08-07 02:42:49 +03:00
enhanced mysql_close() and other related parts to prevent memory leaks when terminating an initiated but unestablished connection
This commit is contained in:
@@ -223,6 +223,14 @@ struct mysql_async_context {
|
|||||||
struct st_ma_pvio *pvio;
|
struct st_ma_pvio *pvio;
|
||||||
void (*suspend_resume_hook)(my_bool suspend, void *user_data);
|
void (*suspend_resume_hook)(my_bool suspend, void *user_data);
|
||||||
void *suspend_resume_hook_user_data;
|
void *suspend_resume_hook_user_data;
|
||||||
|
|
||||||
|
/* If non-NULL, this is a poitner to the result of getaddrinfo() currently
|
||||||
|
* under traversal in pvio_socket_connect(). It gets reset to NULL when a
|
||||||
|
* connection has been established to a server. The main objective is to
|
||||||
|
* free this memory resource in mysql_close() while an initiated connection
|
||||||
|
* has not been established. */
|
||||||
|
struct addrinfo* pending_gai_res;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is used to save the execution contexts so that we can suspend an
|
This is used to save the execution contexts so that we can suspend an
|
||||||
operation and switch back to the application context, to resume the
|
operation and switch back to the application context, to resume the
|
||||||
|
@@ -1737,7 +1737,18 @@ restart:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ma_net_init(net, pvio))
|
if (ma_net_init(net, pvio))
|
||||||
|
{
|
||||||
|
ma_pvio_close(pvio);
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mysql->options.extension && mysql->options.extension->async_context && mysql->options.extension->async_context->pvio)
|
||||||
|
{
|
||||||
|
/* pvio delegated to mysql->net.pvio by ma_net_init().
|
||||||
|
* invalidate the pvio pointer in the async context */
|
||||||
|
mysql->options.extension->async_context->pvio = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (mysql->options.max_allowed_packet)
|
if (mysql->options.max_allowed_packet)
|
||||||
net->max_packet_size= mysql->options.max_allowed_packet;
|
net->max_packet_size= mysql->options.max_allowed_packet;
|
||||||
@@ -2343,6 +2354,20 @@ void mysql_close_slow_part(MYSQL *mysql)
|
|||||||
ma_simple_command(mysql, COM_QUIT,NullS,0,1,0);
|
ma_simple_command(mysql, COM_QUIT,NullS,0,1,0);
|
||||||
end_server(mysql);
|
end_server(mysql);
|
||||||
}
|
}
|
||||||
|
/* there is an ongoing async operation */
|
||||||
|
else if (mysql->options.extension && mysql->options.extension->async_context)
|
||||||
|
{
|
||||||
|
if (mysql->options.extension->async_context->pending_gai_res)
|
||||||
|
{
|
||||||
|
freeaddrinfo(mysql->options.extension->async_context->pending_gai_res);
|
||||||
|
mysql->options.extension->async_context->pending_gai_res = 0;
|
||||||
|
}
|
||||||
|
if (mysql->options.extension->async_context->pvio)
|
||||||
|
{
|
||||||
|
ma_pvio_close(mysql->options.extension->async_context->pvio);
|
||||||
|
mysql->options.extension->async_context->pvio = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ma_clear_session_state(MYSQL *mysql)
|
static void ma_clear_session_state(MYSQL *mysql)
|
||||||
|
@@ -732,6 +732,16 @@ int pvio_socket_fast_send(MARIADB_PVIO *pvio)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
pvio_socket_connect_async(MARIADB_PVIO *pvio,
|
||||||
|
const struct sockaddr *name, uint namelen)
|
||||||
|
{
|
||||||
|
MYSQL *mysql= pvio->mysql;
|
||||||
|
mysql->options.extension->async_context->pvio= pvio;
|
||||||
|
pvio_socket_blocking(pvio, 0, 0);
|
||||||
|
return my_connect_async(pvio, name, namelen, pvio->timeout[PVIO_CONNECT_TIMEOUT]);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pvio_socket_connect_sync_or_async(MARIADB_PVIO *pvio,
|
pvio_socket_connect_sync_or_async(MARIADB_PVIO *pvio,
|
||||||
const struct sockaddr *name, uint namelen)
|
const struct sockaddr *name, uint namelen)
|
||||||
@@ -742,9 +752,7 @@ pvio_socket_connect_sync_or_async(MARIADB_PVIO *pvio,
|
|||||||
{
|
{
|
||||||
/* even if we are not connected yet, application needs to check socket
|
/* even if we are not connected yet, application needs to check socket
|
||||||
* via mysql_get_socket api call, so we need to assign pvio */
|
* via mysql_get_socket api call, so we need to assign pvio */
|
||||||
mysql->options.extension->async_context->pvio= pvio;
|
return pvio_socket_connect_async(pvio, name, namelen);
|
||||||
pvio_socket_blocking(pvio, 0, 0);
|
|
||||||
return my_connect_async(pvio, name, namelen, pvio->timeout[PVIO_CONNECT_TIMEOUT]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pvio_socket_internal_connect(pvio, name, namelen);
|
return pvio_socket_internal_connect(pvio, name, namelen);
|
||||||
@@ -916,7 +924,18 @@ my_bool pvio_socket_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mysql->options.extension && mysql->options.extension->async_context &&
|
||||||
|
mysql->options.extension->async_context->active)
|
||||||
|
{
|
||||||
|
mysql->options.extension->async_context->pending_gai_res = res;
|
||||||
|
rc= pvio_socket_connect_async(pvio, save_res->ai_addr, (uint)save_res->ai_addrlen);
|
||||||
|
mysql->options.extension->async_context->pending_gai_res = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
rc= pvio_socket_connect_sync_or_async(pvio, save_res->ai_addr, (uint)save_res->ai_addrlen);
|
rc= pvio_socket_connect_sync_or_async(pvio, save_res->ai_addr, (uint)save_res->ai_addrlen);
|
||||||
|
}
|
||||||
|
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
MYSQL *mysql= pvio->mysql;
|
MYSQL *mysql= pvio->mysql;
|
||||||
|
Reference in New Issue
Block a user