Only close valid sessions

When a session is being closed, the state needs to be checked. If the
session creation failed, the session need to be only freed.
This commit is contained in:
Markus Mäkelä
2017-05-16 09:35:27 +03:00
parent 39ca791a49
commit 17ba824d9f
3 changed files with 31 additions and 21 deletions

View File

@ -383,7 +383,7 @@ extern uint8_t null_client_sha1[MYSQL_SCRAMBLE_LEN];
MYSQL_session* mysql_session_alloc(); MYSQL_session* mysql_session_alloc();
MySQLProtocol* mysql_protocol_init(DCB* dcb, int fd); MySQLProtocol* mysql_protocol_init(DCB* dcb, int fd);
void mysql_protocol_done (DCB* dcb); bool mysql_protocol_done (DCB* dcb);
const char *gw_mysql_protocol_state2string(int state); const char *gw_mysql_protocol_state2string(int state);
int mysql_send_com_quit(DCB* dcb, int packet_number, GWBUF* buf); int mysql_send_com_quit(DCB* dcb, int packet_number, GWBUF* buf);
GWBUF* mysql_create_com_quit(GWBUF* bufparam, int packet_number); GWBUF* mysql_create_com_quit(GWBUF* bufparam, int packet_number);

View File

@ -1295,11 +1295,22 @@ static int gw_client_close(DCB *dcb)
{ {
CHK_DCB(dcb); CHK_DCB(dcb);
ss_dassert(dcb->protocol); ss_dassert(dcb->protocol);
mysql_protocol_done(dcb);
MXS_SESSION* target = dcb->session; if (mysql_protocol_done(dcb))
ss_debug(MXS_SESSION* removed = ) mxs_worker_deregister_session(target->ses_id); {
ss_dassert(removed == target); MXS_SESSION* target = dcb->session;
session_close(target);
if (target->state != SESSION_STATE_TO_BE_FREED &&
target->state != SESSION_STATE_DUMMY)
{
ss_dassert(target->state == SESSION_STATE_ROUTER_READY ||
target->state == SESSION_STATE_STOPPING);
ss_debug(MXS_SESSION* removed =) mxs_worker_deregister_session(target->ses_id);
ss_dassert(removed == target);
session_close(target);
}
}
return 1; return 1;
} }

View File

@ -120,36 +120,35 @@ return_p:
} }
/** /**
* mysql_protocol_done * Free protocol object
* *
* free protocol allocations. * @param dcb Owner DCB
*
* @param dcb owner DCB
* *
* @return True if protocol was closed
*/ */
void mysql_protocol_done(DCB* dcb) bool mysql_protocol_done(DCB* dcb)
{ {
MySQLProtocol* p; bool rval = false;
server_command_t* scmd; MySQLProtocol* p = (MySQLProtocol *)dcb->protocol;
server_command_t* scmd2;
p = (MySQLProtocol *)dcb->protocol;
if (p->protocol_state == MYSQL_PROTOCOL_ACTIVE) if (p->protocol_state == MYSQL_PROTOCOL_ACTIVE)
{ {
scmd = p->protocol_cmd_history; server_command_t* scmd = p->protocol_cmd_history;
while (scmd != NULL) while (scmd)
{ {
scmd2 = scmd->scom_next; server_command_t* temp = scmd;
MXS_FREE(scmd); scmd = scmd->scom_next;
scmd = scmd2; MXS_FREE(temp);
} }
gwbuf_free(p->stored_query); gwbuf_free(p->stored_query);
p->protocol_state = MYSQL_PROTOCOL_DONE; p->protocol_state = MYSQL_PROTOCOL_DONE;
rval = true;
} }
return rval;
} }
/** /**