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.
This commit is contained in:
Johan Wikman
2016-12-08 16:28:28 +02:00
parent aa4ed2d28d
commit 12f0886ca2
3 changed files with 29 additions and 3 deletions

View File

@ -2044,6 +2044,12 @@ int main(int argc, char **argv)
{ {
thread_wait(threads[thread_id]); thread_wait(threads[thread_id]);
} }
/*<
* Destroy the router and filter instances of all services.
*/
service_destroy_instances();
/*< /*<
* Wait the flush thread. * Wait the flush thread.
*/ */

View File

@ -46,11 +46,19 @@ void service_free(SERVICE *service);
/** /**
* @brief Shut all services down * @brief Shut all services down
* *
* Stops all services and calls the destroyInstance entry points for all routers * Turns on the shutdown flag in each service. This should be done as
* and filter. This should only be called once by the main shutdown code. * part of the MaxScale shutdown.
*/ */
void service_shutdown(void); 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 * @brief Launch all services
* *

View File

@ -1892,6 +1892,18 @@ void service_shutdown()
while (svc != NULL) while (svc != NULL)
{ {
svc->svc_do_shutdown = true; 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 */ /* Call destroyInstance hook for routers */
if (svc->router->destroyInstance && svc->router_instance) if (svc->router->destroyInstance && svc->router_instance)
{ {