Improve shutdown signal safeness

The signal handler no longer acquires the service list lock which removes
a number of deadlock possibilities from the shutdown process. Instead, a
global shutdown flag is set that serves the same purpose as the individual
service shutdown flags did.
This commit is contained in:
Markus Mäkelä
2018-08-01 12:59:01 +03:00
parent 8a248dd930
commit 359f61c73b
5 changed files with 11 additions and 14 deletions

View File

@ -171,6 +171,9 @@ typedef enum count_spec_t
#define SERVICE_STATE_FAILED 3 /**< The service failed to start */
#define SERVICE_STATE_STOPPED 4 /**< The service has been stopped */
// Set to 1 when services should stop
extern volatile sig_atomic_t service_should_stop;
/**
* Find a service
*

View File

@ -125,7 +125,6 @@ Service* service_alloc(const char *name, const char *router, MXS_CONFIG_PARAMETE
service->ports = NULL;
service->dbref = NULL;
service->n_dbref = 0;
service->svc_do_shutdown = false;
service->filters = NULL;
service->n_filters = 0;
service->weightby[0] = '\0';
@ -482,7 +481,7 @@ int serviceStartAllPorts(Service* service)
if (port)
{
while (!service->svc_do_shutdown && port)
while (!service_should_stop && port)
{
listeners += serviceStartPort(service, port);
port = port->next;
@ -639,7 +638,7 @@ int service_launch_all()
error = true;
}
if (ptr->svc_do_shutdown)
if (service_should_stop)
{
break;
}
@ -1698,16 +1697,11 @@ serviceEnableLocalhostMatchWildcardHost(Service *service, int action)
return 1;
}
volatile sig_atomic_t service_should_stop = 0;
void service_shutdown()
{
spinlock_acquire(&service_spin);
for (Service* s: allServices)
{
s->svc_do_shutdown = true;
}
spinlock_release(&service_spin);
service_should_stop = 1;
}
void service_destroy_instances(void)

View File

@ -944,7 +944,7 @@ static int get_users(SERV_LISTENER *listener, bool skip_local)
int total_users = -1;
bool no_active_servers = true;
for (server = service->dbref; !service->svc_do_shutdown && server; server = server->next)
for (server = service->dbref; !service_should_stop && server; server = server->next)
{
if (!SERVER_REF_IS_ACTIVE(server) || !server_is_active(server->server) ||
(skip_local && server_is_mxs_service(server->server)))

View File

@ -463,7 +463,7 @@ avro_binlog_end_t avro_read_all_events(Avro *router)
ss_dassert(router->binlog_fd != -1);
while (!router->service->svc_do_shutdown)
while (!service_should_stop)
{
avro_binlog_end_t rc;
REP_HEADER hdr;

View File

@ -328,7 +328,7 @@ static bool conversion_task_ctl(Avro *inst, bool start)
{
bool rval = false;
if (!inst->service->svc_do_shutdown)
if (!service_should_stop)
{
Worker* worker = static_cast<Worker*>(mxs_rworker_get(MXS_RWORKER_MAIN));
std::auto_ptr<ConversionCtlTask> task(new (std::nothrow) ConversionCtlTask(inst, start));