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);
/**
* Free a service
*
* @param service Service to free
*/
void service_free(SERVICE* service);
/**
* @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
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);
service->next = allServices;
allServices = service;
@ -166,6 +180,28 @@ SERVICE* service_alloc(const char *name, const char *router, MXS_CONFIG_PARAMETE
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
*
@ -434,9 +470,8 @@ int serviceStartAllPorts(SERVICE* service)
* This function loads the protocol modules for each port on which the
* 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
*
* @return Returns the number of listeners created
*/
int serviceInitialize(SERVICE *service)
@ -446,13 +481,6 @@ int serviceInitialize(SERVICE *service)
int listeners = 0;
if ((service->router_instance = service->router->createInstance(service, service->svc_config_param)))
{
if (service->router->getCapabilities)
{
service->capabilities |= service->router->getCapabilities(service->router_instance);
}
if (!config_get_global_options()->config_check)
{
listeners = serviceStartAllPorts(service);
@ -462,12 +490,6 @@ int serviceInitialize(SERVICE *service)
/** We're only checking that the configuration is valid */
listeners++;
}
}
else
{
MXS_ERROR("%s: Failed to create router instance. Service not started.", service->name);
service->state = SERVICE_STATE_FAILED;
}
return listeners;
}