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:
@ -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
|
||||
*
|
||||
|
@ -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)
|
||||
|
@ -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)))
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
Reference in New Issue
Block a user