Fix to bugs #665, and #664. Potentially to #649.

http://bugs.skysql.com/show_bug.cgi?id=665
http://bugs.skysql.com/show_bug.cgi?id=664
http://bugs.skysql.com/show_bug.cgi?id=649

dcb.c:dcb_final_free: (665):set dcb->session->client pointer to NULL so that it won't be read anymore and other threads won't try to close it.
	dcb_final_free:(664):don't free dcb->data, it is either freed in session_alloc if session creation fails or in session_free only.
session.c:if session creation fails, free dcb->data and remove links between client DCB and session.
mysql_backend.c:(665):gw_backend_close:check that session->client isn't NULL and that client DCB's state is still polling before calling dcb_close for it.
mysql_client.c:gw_mysql_do_authentication:if anything fails, and session_alloc won't be called, free dcb->data.
mysql_common.c:gw_send_authentication_to_backend:if session is already closing then return with error.
This commit is contained in:
VilhoRaatikka
2014-12-29 20:19:01 +02:00
parent beacd524da
commit 635fcf708f
8 changed files with 97 additions and 29 deletions

View File

@ -85,6 +85,11 @@ session_alloc(SERVICE *service, DCB *client_dcb)
"session object due error %d, %s.",
errno,
strerror(errno))));
if (client_dcb->data)
{
free(client_dcb->data);
client_dcb->data = NULL;
}
goto return_session;
}
#if defined(SS_DEBUG)
@ -149,6 +154,7 @@ session_alloc(SERVICE *service, DCB *client_dcb)
* Decrease refcount, set dcb's session pointer NULL
* and set session pointer to NULL.
*/
session->client = NULL;
session_free(session);
client_dcb->session = NULL;
session = NULL;
@ -189,6 +195,7 @@ session_alloc(SERVICE *service, DCB *client_dcb)
* Decrease refcount, set dcb's session pointer NULL
* and set session pointer to NULL.
*/
session->client = NULL;
session_free(session);
client_dcb->session = NULL;
session = NULL;
@ -207,6 +214,7 @@ session_alloc(SERVICE *service, DCB *client_dcb)
if (session->state != SESSION_STATE_READY)
{
spinlock_release(&session->ses_lock);
session->client = NULL;
session_free(session);
client_dcb->session = NULL;
session = NULL;
@ -336,7 +344,11 @@ int session_unlink_dcb(
if (dcb != NULL)
{
dcb->session = NULL;
if (session->client == dcb)
{
session->client = NULL;
}
dcb->session = NULL;
}
spinlock_release(&session->ses_lock);
@ -429,6 +441,11 @@ bool session_free(
if (!session->ses_is_child)
{
session->state = SESSION_STATE_FREE;
if (session->data)
{
free(session->data);
}
free(session);
}
succp = true;