From 93521e43271d03459de92da30b54cdd44ae62156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 24 Jul 2018 08:41:36 +0300 Subject: [PATCH] MXS-1929: Destroy filters separately from services The previous implementation did not destroy filters that were not used by services. With the full initialization of filters in filter_alloc, we can simply traverse the list of created filters and destroy them knowing that they are all valid. --- server/core/filter.cc | 16 ++++++++ server/core/internal/filter.h | 4 ++ server/core/service.cc | 76 +++-------------------------------- 3 files changed, 25 insertions(+), 71 deletions(-) diff --git a/server/core/filter.cc b/server/core/filter.cc index 84c977ce7..6879dfa80 100644 --- a/server/core/filter.cc +++ b/server/core/filter.cc @@ -181,6 +181,22 @@ void filter_destroy(MXS_FILTER_DEF *filter) ss_info_dassert(!true, "Not yet implemented"); } +void filter_destroy_instances() +{ + spinlock_acquire(&filter_spin); + + for (MXS_FILTER_DEF* filter = allFilters; filter; filter = filter->next) + { + // NOTE: replace this with filter_destroy + if (filter->obj->destroyInstance) + { + filter->obj->destroyInstance(filter->filter); + } + } + + spinlock_release(&filter_spin); +} + const char* filter_def_get_name(const MXS_FILTER_DEF* filter_def) { return filter_def->name; diff --git a/server/core/internal/filter.h b/server/core/internal/filter.h index 42d2f9cc1..ede0ca90a 100644 --- a/server/core/internal/filter.h +++ b/server/core/internal/filter.h @@ -63,5 +63,9 @@ bool filter_can_be_destroyed(MXS_FILTER_DEF *filter); */ void filter_destroy(MXS_FILTER_DEF *filter); +/** + * Destroy all filters + */ +void filter_destroy_instances(); MXS_END_DECLS diff --git a/server/core/service.cc b/server/core/service.cc index 994cd1ecb..bcb913b6b 100644 --- a/server/core/service.cc +++ b/server/core/service.cc @@ -1763,89 +1763,23 @@ serviceEnableLocalhostMatchWildcardHost(SERVICE *service, int action) void service_shutdown() { - SERVICE* svc; spinlock_acquire(&service_spin); - svc = allServices; - while (svc != NULL) + + for (SERVICE* svc = allServices; svc; svc = svc->next) { svc->svc_do_shutdown = true; - svc = svc->next; } + spinlock_release(&service_spin); } -/** - * Destroy a listener - * - * @param sl The listener to destroy. - * - * @return The next listener or NULL if there is not one. - */ -static SERV_LISTENER* service_destroy_listener(SERV_LISTENER* sl) -{ - SERV_LISTENER* next = sl->next; - - dcb_close(sl->listener); - - // TODO: What else should be closed and freed here? - - return next; -} - -typedef std::map DestructorsByFilter; -/** - * Destroy one service instance - * - * @param svc The service to destroy. - */ -static void service_destroy_instance(SERVICE* svc, DestructorsByFilter* filters_to_delete) -{ - SERV_LISTENER* sl = svc->ports; - - while (sl) - { - sl = service_destroy_listener(sl); - } - - /* Call destroyInstance hook for routers */ - if (svc->router->destroyInstance && svc->router_instance) - { - svc->router->destroyInstance(svc->router_instance); - } - if (svc->n_filters) - { - MXS_FILTER_DEF **filters = svc->filters; - for (int i = 0; i < svc->n_filters; i++) - { - if (filters[i]->obj->destroyInstance && filters[i]->filter) - { - if (filters_to_delete->find(filters[i]->filter) == filters_to_delete->end()) - { - auto entry = std::make_pair(filters[i]->filter, filters[i]->obj->destroyInstance); - - filters_to_delete->insert(entry); - } - } - } - } -} - void service_destroy_instances(void) { spinlock_acquire(&service_spin); - DestructorsByFilter filters_to_delete; - SERVICE* svc = allServices; - while (svc != NULL) - { - ss_dassert(svc->svc_do_shutdown); - service_destroy_instance(svc, &filters_to_delete); - svc = svc->next; - } - - for (auto i = filters_to_delete.begin(); i != filters_to_delete.end(); ++i) + for (SERVICE* svc = allServices; svc; svc = svc->next) { - i->second(i->first); + service_destroy(svc); } spinlock_release(&service_spin);