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:
@ -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.
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
*
|
*
|
||||||
@ -116,4 +124,4 @@ bool service_set_param_value(SERVICE* service, CONFIG_PARAMETER* param, char* v
|
|||||||
void printService(SERVICE *service);
|
void printService(SERVICE *service);
|
||||||
void printAllServices(void);
|
void printAllServices(void);
|
||||||
|
|
||||||
MXS_END_DECLS
|
MXS_END_DECLS
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user