MXS-1721 Destroy a filter instance only once
If two services referred to the same filter instance, it would cause the filter to deleted twice at MaxScale shutdown with a crash as the result. Now when the services are deleted we just collect the unique filter instances and then delete them after all services have been deleted.
This commit is contained in:
parent
2178667245
commit
391ec78a0b
@ -26,6 +26,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <math.h>
|
||||
#include <fcntl.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
@ -1960,12 +1961,13 @@ static SERV_LISTENER* service_destroy_listener(SERV_LISTENER* sl)
|
||||
return next;
|
||||
}
|
||||
|
||||
typedef std::map<MXS_FILTER*, void(*)(MXS_FILTER*)> DestructorsByFilter;
|
||||
/**
|
||||
* Destroy one service instance
|
||||
*
|
||||
* @param svc The service to destroy.
|
||||
*/
|
||||
static void service_destroy_instance(SERVICE* svc)
|
||||
static void service_destroy_instance(SERVICE* svc, DestructorsByFilter* filters_to_delete)
|
||||
{
|
||||
SERV_LISTENER* sl = svc->ports;
|
||||
|
||||
@ -1986,8 +1988,12 @@ static void service_destroy_instance(SERVICE* svc)
|
||||
{
|
||||
if (filters[i]->obj->destroyInstance && filters[i]->filter)
|
||||
{
|
||||
/* Call destroyInstance hook for filters */
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1996,14 +2002,21 @@ static void service_destroy_instance(SERVICE* svc)
|
||||
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);
|
||||
service_destroy_instance(svc, &filters_to_delete);
|
||||
|
||||
svc = svc->next;
|
||||
}
|
||||
|
||||
for (auto i = filters_to_delete.begin(); i != filters_to_delete.end(); ++i)
|
||||
{
|
||||
i->second(i->first);
|
||||
}
|
||||
|
||||
spinlock_release(&service_spin);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user