MXS-1929: Remove listener from service and workers

When a listener is removed from a service, it should also be removed from
any workers it has been added to. This guarantees that if the opening of
the listener was successful, no requests will be accepted on it after the
removal of the listener.
This commit is contained in:
Markus Mäkelä
2018-07-18 08:16:38 +03:00
parent 4069072164
commit aeb94cbc9e
2 changed files with 37 additions and 24 deletions

View File

@ -87,6 +87,18 @@ SERV_LISTENER* serviceCreateListener(SERVICE *service, const char *name,
unsigned short port, const char *authenticator,
const char *options, SSL_LISTENER *ssl);
/**
* @brief Remove a listener from use
*
* @note This does not free the memory
*
* @param service Service that owns the listener
* @param char Name of the listener to remove
*
* @return True if listener was found and removed
*/
bool service_remove_listener(SERVICE *service, const char* target);
void serviceRemoveBackend(SERVICE *service, const SERVER *server);
/**

View File

@ -496,29 +496,6 @@ int serviceInitialize(SERVICE *service)
return listeners;
}
/**
* @brief Remove a listener from use
*
* @note This does not free the memory
*
* @param service Service where @c port points to
* @param port Port to remove
*/
void serviceRemoveListener(SERVICE *service, SERV_LISTENER *target)
{
LISTENER_ITERATOR iter;
for (SERV_LISTENER *listener = listener_iterator_init(service, &iter);
listener; listener = listener_iterator_next(&iter))
{
if (listener == target)
{
listener_set_active(listener, false);
break;
}
}
}
bool serviceLaunchListener(SERVICE *service, SERV_LISTENER *port)
{
ss_dassert(service->state != SERVICE_STATE_FAILED);
@ -529,7 +506,7 @@ bool serviceLaunchListener(SERVICE *service, SERV_LISTENER *port)
if (serviceStartPort(service, port) == 0)
{
/** Failed to start the listener */
serviceRemoveListener(service, port);
service_remove_listener(service, port->name);
rval = false;
}
@ -698,6 +675,30 @@ static void service_add_listener(SERVICE* service, SERV_LISTENER* proto)
while (!atomic_cas_ptr((void**)&service->ports, (void**)&proto->next, proto));
}
bool service_remove_listener(SERVICE *service, const char* target)
{
bool rval = false;
LISTENER_ITERATOR iter;
for (SERV_LISTENER *listener = listener_iterator_init(service, &iter);
listener; listener = listener_iterator_next(&iter))
{
if (listener_is_active(listener) && strcmp(listener->name, target) == 0)
{
listener_set_active(listener, false);
if (poll_remove_dcb(listener->listener) == 0)
{
listener->listener->session->state = SESSION_STATE_LISTENER_STOPPED;
rval = true;
}
break;
}
}
return rval;
}
/**
* Create a listener for the service
*