From e14b29baf90f7ab3f62ea5a0314b0b1da0e5a7d5 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Sun, 21 Jun 2015 12:51:54 +0300 Subject: [PATCH] Fix to MXS-212: https://mariadb.atlassian.net/browse/MXS-212 The listener DCB is now properly closed instead of just being removed from the poll set. --- server/core/dcb.c | 8 +++++++- server/core/poll.c | 3 ++- server/core/service.c | 19 +++++++++---------- server/modules/protocol/mysql_client.c | 2 +- server/modules/protocol/mysql_common.c | 5 ++++- 5 files changed, 23 insertions(+), 14 deletions(-) diff --git a/server/core/dcb.c b/server/core/dcb.c index 7f3651953..fc9329524 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -1949,13 +1949,15 @@ dcb_close(DCB *dcb) } ss_dassert(dcb->state == DCB_STATE_POLLING || + dcb->state == DCB_STATE_LISTENING || dcb->state == DCB_STATE_NOPOLLING || dcb->state == DCB_STATE_ZOMBIE); /*< * Stop dcb's listening and modify state accordingly. */ - if (dcb->state == DCB_STATE_POLLING) + if (dcb->state == DCB_STATE_POLLING || + dcb->state == DCB_STATE_LISTENING) { rc = poll_remove_dcb(dcb); @@ -2428,6 +2430,10 @@ static bool dcb_set_state_nomutex( case DCB_STATE_POLLING: /*< ok to try but state can't change */ succp = true; break; + case DCB_STATE_LISTENING: + dcb->state = new_state; + succp = true; + break; default: ss_dassert(old_state != NULL); break; diff --git a/server/core/poll.c b/server/core/poll.c index 377310cb0..9a1a5565d 100644 --- a/server/core/poll.c +++ b/server/core/poll.c @@ -330,7 +330,8 @@ poll_remove_dcb(DCB *dcb) CHK_DCB(dcb); /*< It is possible that dcb has already been removed from the set */ - if (dcb->state != DCB_STATE_POLLING) + if (dcb->state != DCB_STATE_POLLING && + dcb->state != DCB_STATE_LISTENING) { if (dcb->state == DCB_STATE_NOPOLLING || dcb->state == DCB_STATE_ZOMBIE) diff --git a/server/core/service.c b/server/core/service.c index b0959e6c3..c11c0bddc 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -534,11 +534,13 @@ int listeners = 0; port = service->ports; while (port) { - poll_remove_dcb(port->listener); - port->listener->session->state = SESSION_STATE_LISTENER_STOPPED; + if(port->listener) + { + dcb_close(port->listener); + port->listener = NULL; listeners++; - - port = port->next; + } + port = port->next; } service->state = SERVICE_STATE_STOPPED; @@ -562,13 +564,10 @@ int listeners = 0; port = service->ports; while (port) { - if (poll_add_dcb(port->listener) == 0) { - port->listener->session->state = SESSION_STATE_LISTENER; - listeners++; - } - port = port->next; + listeners += serviceStartPort(service,port); + port = port->next; } - + service->state = SERVICE_STATE_STARTED; return listeners; } diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index c3e463139..21a11dc42 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -1771,7 +1771,7 @@ gw_client_close(DCB *dcb) dcb->state == DCB_STATE_NOPOLLING || dcb->state == DCB_STATE_ZOMBIE) { - if (!DCB_IS_CLONE(dcb)) CHK_PROTOCOL(protocol); + if (!DCB_IS_CLONE(dcb) && protocol) CHK_PROTOCOL(protocol); } #endif LOGIF(LD, (skygw_log_write(LOGFILE_DEBUG, diff --git a/server/modules/protocol/mysql_common.c b/server/modules/protocol/mysql_common.c index 83e2912e5..eb044c1fb 100644 --- a/server/modules/protocol/mysql_common.c +++ b/server/modules/protocol/mysql_common.c @@ -128,7 +128,10 @@ void mysql_protocol_done ( MySQLProtocol* p; server_command_t* scmd; server_command_t* scmd2; - + + if(dcb->protocol == NULL) + return; + p = (MySQLProtocol *)dcb->protocol; spinlock_acquire(&p->protocol_lock);