From 12f0886ca2aae7951756665d24d03614c689664d Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Thu, 8 Dec 2016 16:28:28 +0200 Subject: [PATCH] Call destroyInstance after workers have exited Router and filter instances cannot be destroyed before all worker threads have exited. Otherwise there is a risk that data gets deleted while someone might still be accessing it. Further, since all router and filter instances are created by the main-thread it is better that they are deleted by that thread as well (and not by whichever thread happens to execute service_shutdown()). That will reduce the risk that some unknown assumptions are violated. --- server/core/gateway.cc | 6 ++++++ server/core/maxscale/service.h | 14 +++++++++++--- server/core/service.c | 12 ++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/server/core/gateway.cc b/server/core/gateway.cc index b34998269..001bf2e82 100644 --- a/server/core/gateway.cc +++ b/server/core/gateway.cc @@ -2044,6 +2044,12 @@ int main(int argc, char **argv) { thread_wait(threads[thread_id]); } + + /*< + * Destroy the router and filter instances of all services. + */ + service_destroy_instances(); + /*< * Wait the flush thread. */ diff --git a/server/core/maxscale/service.h b/server/core/maxscale/service.h index ada5c7c7c..71788c7b1 100644 --- a/server/core/maxscale/service.h +++ b/server/core/maxscale/service.h @@ -46,11 +46,19 @@ void service_free(SERVICE *service); /** * @brief Shut all services down * - * Stops all services and calls the destroyInstance entry points for all routers - * and filter. This should only be called once by the main shutdown code. + * Turns on the shutdown flag in each service. This should be done as + * part of the MaxScale shutdown. */ void service_shutdown(void); +/** + * @brief Destroy all service router and filter instances + * + * Calls the @c destroyInstance entry point of each service' router and + * filters. This should be done after all worker threads have exited. + */ +void service_destroy_instances(void); + /** * @brief Launch all services * @@ -116,4 +124,4 @@ bool service_set_param_value(SERVICE* service, CONFIG_PARAMETER* param, char* v void printService(SERVICE *service); void printAllServices(void); -MXS_END_DECLS \ No newline at end of file +MXS_END_DECLS diff --git a/server/core/service.c b/server/core/service.c index 452b597ec..ee43add49 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -1892,6 +1892,18 @@ void service_shutdown() while (svc != NULL) { svc->svc_do_shutdown = true; + svc = svc->next; + } + spinlock_release(&service_spin); +} + +void service_destroy_instances(void) +{ + spinlock_acquire(&service_spin); + SERVICE* svc = allServices; + while (svc != NULL) + { + ss_dassert(svc->svc_do_shutdown); /* Call destroyInstance hook for routers */ if (svc->router->destroyInstance && svc->router_instance) {