If backend fails and sets session state to SESSION_STATE_STOPPING before session is in state SESSION_STATE_ROUTER_READY, sessoin.c:session_alloc overwrites the session state by SESSION_STATE_ROUTER_READY. Protected session state modification and added check before changing the state.
cloesSession was called in session.c:session_free if all DCBs had been removed their references to session. closeSession, however, is function which handles closing router. Router is responsible for closing all backend DCBs (=connections). Thus, calling sessionClose after all backend connections had been removed already is unnecessary and causes assertion traps. Simply removed the call.
This commit is contained in:
@ -116,7 +116,8 @@ MODULE_INFO *mod_info = NULL;
|
|||||||
LOGIF(LE, (skygw_log_write_flush(
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
LOGFILE_ERROR,
|
LOGFILE_ERROR,
|
||||||
"Error : Unable to load library for module: "
|
"Error : Unable to load library for module: "
|
||||||
"%s\n\t\t\t %s.",
|
"%s\n\n\t\t %s."
|
||||||
|
"\n\n",
|
||||||
module,
|
module,
|
||||||
dlerror())));
|
dlerror())));
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@ -127,7 +127,8 @@ session_alloc(SERVICE *service, DCB *client_dcb)
|
|||||||
* session, therefore it is important that the session lock is
|
* session, therefore it is important that the session lock is
|
||||||
* relinquished beforethe router call.
|
* relinquished beforethe router call.
|
||||||
*/
|
*/
|
||||||
if (client_dcb->state != DCB_STATE_LISTENING && client_dcb->dcb_role != DCB_ROLE_INTERNAL)
|
if (client_dcb->state != DCB_STATE_LISTENING &&
|
||||||
|
client_dcb->dcb_role != DCB_ROLE_INTERNAL)
|
||||||
{
|
{
|
||||||
session->router_session =
|
session->router_session =
|
||||||
service->router->newSession(service->router_instance,
|
service->router->newSession(service->router_instance,
|
||||||
@ -192,14 +193,28 @@ session_alloc(SERVICE *service, DCB *client_dcb)
|
|||||||
}
|
}
|
||||||
|
|
||||||
spinlock_acquire(&session_spin);
|
spinlock_acquire(&session_spin);
|
||||||
session->state = SESSION_STATE_ROUTER_READY;
|
|
||||||
session->next = allSessions;
|
|
||||||
allSessions = session;
|
|
||||||
spinlock_release(&session_spin);
|
|
||||||
atomic_add(&service->stats.n_sessions, 1);
|
|
||||||
atomic_add(&service->stats.n_current, 1);
|
|
||||||
CHK_SESSION(session);
|
|
||||||
|
|
||||||
|
if (session->state != SESSION_STATE_READY)
|
||||||
|
{
|
||||||
|
session_free(session);
|
||||||
|
client_dcb->session = NULL;
|
||||||
|
session = NULL;
|
||||||
|
LOGIF(LE, (skygw_log_write_flush(
|
||||||
|
LOGFILE_ERROR,
|
||||||
|
"Error : Failed to create %s session.",
|
||||||
|
service->name)));
|
||||||
|
spinlock_release(&session_spin);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
session->state = SESSION_STATE_ROUTER_READY;
|
||||||
|
session->next = allSessions;
|
||||||
|
allSessions = session;
|
||||||
|
spinlock_release(&session_spin);
|
||||||
|
atomic_add(&service->stats.n_sessions, 1);
|
||||||
|
atomic_add(&service->stats.n_current, 1);
|
||||||
|
CHK_SESSION(session);
|
||||||
|
}
|
||||||
return_session:
|
return_session:
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
@ -306,9 +321,6 @@ bool session_free(
|
|||||||
|
|
||||||
/* Free router_session and session */
|
/* Free router_session and session */
|
||||||
if (session->router_session) {
|
if (session->router_session) {
|
||||||
session->service->router->closeSession(
|
|
||||||
session->service->router_instance,
|
|
||||||
session->router_session);
|
|
||||||
session->service->router->freeSession(
|
session->service->router->freeSession(
|
||||||
session->service->router_instance,
|
session->service->router_instance,
|
||||||
session->router_session);
|
session->router_session);
|
||||||
|
|||||||
Reference in New Issue
Block a user