Clean up filter usage in services

Using a stack-allocated vector allows the filter definition array to only
be allocated once all filters have been successfully processed.
This commit is contained in:
Markus Mäkelä 2018-07-15 20:26:41 +03:00
parent 16aece6f83
commit 728a3f6957
No known key found for this signature in database
GPG Key ID: 72D48FCE664F7B19
3 changed files with 25 additions and 49 deletions

View File

@ -285,7 +285,7 @@ bool service_has_named_listener(SERVICE *service, const char *name);
int serviceGetUser(SERVICE *service, char **user, char **auth);
int serviceSetUser(SERVICE *service, const char *user, const char *auth);
bool serviceSetFilters(SERVICE *service, char *filters);
bool service_set_filters(SERVICE *service, const char* filters);
int serviceEnableRootUser(SERVICE *service, int action);
int serviceSetTimeout(SERVICE *service, int val);
int serviceSetConnectionLimits(SERVICE *service, int max, int queued, int timeout);

View File

@ -3204,7 +3204,7 @@ int configure_new_service(CONFIG_CONTEXT *obj)
if (char* filters = config_get_value(obj->parameters, CN_FILTERS))
{
if (!serviceSetFilters(service, filters))
if (!service_set_filters(service, filters))
{
error_count++;
}

View File

@ -48,6 +48,7 @@
#include <maxscale/spinlock.h>
#include <maxscale/users.h>
#include <maxscale/utils.h>
#include <maxscale/utils.hh>
#include <maxscale/version.h>
#include <maxscale/jansson.h>
#include <maxscale/json_api.h>
@ -1116,83 +1117,58 @@ void service_set_retry_interval(SERVICE *service, int value)
/**
* Set the filters used by the service
*
* @param service The service itself
* @param filters ASCII string of filters to use
* @param service The service itself
* @param filters The filters to use separated by the pipe character |
*
* @return True if loading and creating all filters was successful. False if a
* filter module was not found or the instance creation failed.
* filter module was not found or the instance creation failed.
*/
bool
serviceSetFilters(SERVICE *service, char *filters)
bool service_set_filters(SERVICE* service, const char* filters)
{
MXS_FILTER_DEF **flist = NULL;
char *ptr = NULL, *brkt = NULL;
int n = 0;
bool rval = true;
std::vector<MXS_FILTER_DEF*> flist;
uint64_t capabilities = 0;
if ((flist = (MXS_FILTER_DEF **) MXS_MALLOC(sizeof(MXS_FILTER_DEF *))) == NULL)
for (auto&& f: mxs::strtok(filters, "| \t"))
{
return false;
}
ptr = strtok_r(filters, "|", &brkt);
while (ptr)
{
fix_object_name(ptr);
fix_object_name(&f[0]);
n++;
MXS_FILTER_DEF **tmp;
if ((tmp = (MXS_FILTER_DEF **) MXS_REALLOC(flist,
(n + 1) * sizeof(MXS_FILTER_DEF *))) == NULL)
if (MXS_FILTER_DEF* def = filter_def_find(f.c_str()))
{
rval = false;
break;
}
flist = tmp;
char *filter_name = trim(ptr);
if ((flist[n - 1] = filter_def_find(filter_name)))
{
if (filter_load(flist[n - 1]))
if (filter_load(def))
{
const MXS_MODULE* module = get_module(flist[n - 1]->module, MODULE_FILTER);
flist.push_back(def);
const MXS_MODULE* module = get_module(def->module, MODULE_FILTER);
ss_dassert(module);
capabilities |= module->module_capabilities;
if (flist[n - 1]->obj->getCapabilities)
if (def->obj->getCapabilities)
{
capabilities |= flist[n - 1]->obj->getCapabilities(flist[n - 1]->filter);
capabilities |= def->obj->getCapabilities(def->filter);
}
}
else
{
MXS_ERROR("Failed to load filter '%s' for service '%s'.",
filter_name, service->name);
MXS_ERROR("Failed to load filter '%s' for service '%s'.", f.c_str(), service->name);
rval = false;
break;
}
}
else
{
MXS_ERROR("Unable to find filter '%s' for service '%s'",
filter_name, service->name);
MXS_ERROR("Unable to find filter '%s' for service '%s'", f.c_str(), service->name);
rval = false;
break;
}
flist[n] = NULL;
ptr = strtok_r(NULL, "|", &brkt);
}
if (rval)
{
service->filters = flist;
service->n_filters = n;
service->filters = (MXS_FILTER_DEF**)MXS_MALLOC((flist.size() + 1) * sizeof(MXS_FILTER_DEF*));
std::copy(flist.begin(), flist.end(), service->filters);
service->n_filters = flist.size();
service->filters[service->n_filters] = NULL;
service->capabilities |= capabilities;
}
else
{
MXS_FREE(flist);
}
return rval;
}