Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhanced mysql_close_slow_part() and other related parts to prevent memory leaks in the non-blocking mode #199

Merged
merged 4 commits into from Jul 25, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Next Next commit
enhanced mysql_close() and other related parts to prevent memory leak…
…s when terminating an initiated but unestablished connection
  • Loading branch information
hyung-hwan committed Jun 21, 2022
commit c0fea17e2a05d636bbea980be73ba8e67361ee07
8 changes: 8 additions & 0 deletions include/ma_context.h
Expand Up @@ -223,6 +223,14 @@ struct mysql_async_context {
struct st_ma_pvio *pvio;
void (*suspend_resume_hook)(my_bool suspend, void *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
operation and switch back to the application context, to resume the
Expand Down
25 changes: 25 additions & 0 deletions libmariadb/mariadb_lib.c
Expand Up @@ -1737,7 +1737,18 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
}

if (ma_net_init(net, pvio))
{
ma_pvio_close(pvio);
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)
net->max_packet_size= mysql->options.max_allowed_packet;
Expand Down Expand Up @@ -2343,6 +2354,20 @@ void mysql_close_slow_part(MYSQL *mysql)
ma_simple_command(mysql, COM_QUIT,NullS,0,1,0);
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)
Expand Down
27 changes: 23 additions & 4 deletions plugins/pvio/pvio_socket.c
Expand Up @@ -732,6 +732,16 @@ int pvio_socket_fast_send(MARIADB_PVIO *pvio)
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
pvio_socket_connect_sync_or_async(MARIADB_PVIO *pvio,
const struct sockaddr *name, uint namelen)
Expand All @@ -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
* via mysql_get_socket api call, so we need to assign pvio */
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]);
return pvio_socket_connect_async(pvio, name, namelen);
}

return pvio_socket_internal_connect(pvio, name, namelen);
Expand Down Expand Up @@ -916,7 +924,18 @@ my_bool pvio_socket_connect(MARIADB_PVIO *pvio, MA_PVIO_CINFO *cinfo)
}
}

rc= pvio_socket_connect_sync_or_async(pvio, save_res->ai_addr, (uint)save_res->ai_addrlen);
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);
}

if (!rc)
{
MYSQL *mysql= pvio->mysql;
Expand Down