Added new state to SESSION: SESSION_STATE_STOPPING, which is set in protocol module before calling closeSession (router). THe new state tells that session is closing and DCBs included may not be polling anymore.

Fixed some crash scenarios.
This commit is contained in:
VilhoRaatikka
2014-05-08 23:17:35 +03:00
parent a1361d9c9e
commit 8be4aba223
8 changed files with 216 additions and 113 deletions

View File

@ -217,15 +217,26 @@ getUsers(SERVICE *service, struct users *users)
*/
server = service->databases;
dpwd = decryptPassword(service_passwd);
while (server != NULL && mysql_real_connect(con,
while (server != NULL && (mysql_real_connect(con,
server->name,
service_user,
dpwd,
NULL,
server->port,
NULL,
0) == NULL)
0) == NULL))
{
if (server == NULL)
{
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : Unable to connect to %s:%d, \"%s\"",
server->name,
server->port,
mysql_error(con))));
mysql_close(con);
return -1;
}
server = server->nextdb;
}
free(dpwd);

View File

@ -688,11 +688,20 @@ dcb_write(DCB *dcb, GWBUF *queue)
ss_dassert(queue != NULL);
/**
* SESSION_STATE_STOPPING means that one of the backends is closing
* the router session. Some backends may have not completed
* authentication yet and thus they have no information about router
* being closed. Session state is changed to SESSION_STATE_STOPPING
* before router's closeSession is called and that tells that DCB may
* still be writable.
*/
if (queue == NULL ||
(dcb->state != DCB_STATE_ALLOC &&
dcb->state != DCB_STATE_POLLING &&
dcb->state != DCB_STATE_LISTENING &&
dcb->state != DCB_STATE_NOPOLLING))
dcb->state != DCB_STATE_NOPOLLING &&
dcb->session->state != SESSION_STATE_STOPPING))
{
LOGIF(LD, (skygw_log_write(
LOGFILE_DEBUG,
@ -703,6 +712,7 @@ dcb_write(DCB *dcb, GWBUF *queue)
dcb,
STRDCBSTATE(dcb->state),
dcb->fd)));
ss_dassert(false);
return 0;
}

View File

@ -129,6 +129,10 @@ session_alloc(SERVICE *service, DCB *client_dcb)
session);
if (session->router_session == NULL) {
/**
* Inform other threads that session is closing.
*/
session->state == SESSION_STATE_STOPPING;
/*<
* Decrease refcount, set dcb's session pointer NULL
* and set session pointer to NULL.
@ -439,3 +443,18 @@ session_state(int state)
return "Invalid State";
}
}
SESSION* get_session_by_router_ses(
void* rses)
{
SESSION* ses = allSessions;
while (ses->router_session != rses && ses->next != NULL)
ses = ses->next;
if (ses->router_session != rses)
{
ses = NULL;
}
return ses;
}