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]);
}
/*<
* Destroy the router and filter instances of all services.
*/
service_destroy_instances();
/*<
* Wait the flush thread.
*/

View File

@ -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
MXS_END_DECLS

View File

@ -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)
{