MXS-1929: Create router instance in service_alloc

By creating the router instance as a part of the service allocation
process, we are guaranteed that either the creation of the service is
completely successful or it fails. This should make runtime creation of
services easier.
This commit is contained in:
Markus Mäkelä
2018-07-17 15:41:53 +03:00
parent d8b539c85a
commit 36822da172
2 changed files with 49 additions and 20 deletions

View File

@ -37,6 +37,13 @@ MXS_BEGIN_DECLS
*/ */
SERVICE* service_alloc(const char *name, const char *router, MXS_CONFIG_PARAMETER* params); SERVICE* service_alloc(const char *name, const char *router, MXS_CONFIG_PARAMETER* params);
/**
* Free a service
*
* @param service Service to free
*/
void service_free(SERVICE* service);
/** /**
* @brief Shut all services down * @brief Shut all services down
* *

View File

@ -158,6 +158,20 @@ SERVICE* service_alloc(const char *name, const char *router, MXS_CONFIG_PARAMETE
// Store parameters in the service // Store parameters in the service
service_add_parameters(service, params); service_add_parameters(service, params);
service->router_instance = router_api->createInstance(service, params);
if (service->router_instance == NULL)
{
MXS_ERROR("%s: Failed to create router instance. Service not started.", service->name);
service_free(service);
return NULL;
}
if (router_api->getCapabilities)
{
service->capabilities |= router_api->getCapabilities(service->router_instance);
}
spinlock_acquire(&service_spin); spinlock_acquire(&service_spin);
service->next = allServices; service->next = allServices;
allServices = service; allServices = service;
@ -166,6 +180,28 @@ SERVICE* service_alloc(const char *name, const char *router, MXS_CONFIG_PARAMETE
return service; return service;
} }
void service_free(SERVICE* service)
{
if (service->router && service->router_instance)
{
service->router->destroyInstance(service->router_instance);
}
while (service->dbref)
{
SERVER_REF* tmp = service->dbref;
service->dbref = service->dbref->next;
MXS_FREE(tmp);
}
config_parameter_free(service->svc_config_param);
MXS_FREE(service->name);
MXS_FREE(service->routerModule);
MXS_FREE(service->filters);
MXS_FREE(service->rate_limits);
MXS_FREE(service);
}
/** /**
* Check to see if a service pointer is valid * Check to see if a service pointer is valid
* *
@ -434,10 +470,9 @@ int serviceStartAllPorts(SERVICE* service)
* This function loads the protocol modules for each port on which the * This function loads the protocol modules for each port on which the
* service listens and starts the listener on that port * service listens and starts the listener on that port
* *
* Also create the router_instance for the service. * @param service The Service that should be started
* *
* @param service The Service that should be started * @return Returns the number of listeners created
* @return Returns the number of listeners created
*/ */
int serviceInitialize(SERVICE *service) int serviceInitialize(SERVICE *service)
{ {
@ -446,27 +481,14 @@ int serviceInitialize(SERVICE *service)
int listeners = 0; int listeners = 0;
if ((service->router_instance = service->router->createInstance(service, service->svc_config_param))) if (!config_get_global_options()->config_check)
{ {
if (service->router->getCapabilities) listeners = serviceStartAllPorts(service);
{
service->capabilities |= service->router->getCapabilities(service->router_instance);
}
if (!config_get_global_options()->config_check)
{
listeners = serviceStartAllPorts(service);
}
else
{
/** We're only checking that the configuration is valid */
listeners++;
}
} }
else else
{ {
MXS_ERROR("%s: Failed to create router instance. Service not started.", service->name); /** We're only checking that the configuration is valid */
service->state = SERVICE_STATE_FAILED; listeners++;
} }
return listeners; return listeners;