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_FAILED 3 /**< The service failed to start */
|
||||||
#define SERVICE_STATE_STOPPED 4 /**< The service has been stopped */
|
#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
|
* Find a service
|
||||||
*
|
*
|
||||||
|
@ -125,7 +125,6 @@ Service* service_alloc(const char *name, const char *router, MXS_CONFIG_PARAMETE
|
|||||||
service->ports = NULL;
|
service->ports = NULL;
|
||||||
service->dbref = NULL;
|
service->dbref = NULL;
|
||||||
service->n_dbref = 0;
|
service->n_dbref = 0;
|
||||||
service->svc_do_shutdown = false;
|
|
||||||
service->filters = NULL;
|
service->filters = NULL;
|
||||||
service->n_filters = 0;
|
service->n_filters = 0;
|
||||||
service->weightby[0] = '\0';
|
service->weightby[0] = '\0';
|
||||||
@ -482,7 +481,7 @@ int serviceStartAllPorts(Service* service)
|
|||||||
|
|
||||||
if (port)
|
if (port)
|
||||||
{
|
{
|
||||||
while (!service->svc_do_shutdown && port)
|
while (!service_should_stop && port)
|
||||||
{
|
{
|
||||||
listeners += serviceStartPort(service, port);
|
listeners += serviceStartPort(service, port);
|
||||||
port = port->next;
|
port = port->next;
|
||||||
@ -639,7 +638,7 @@ int service_launch_all()
|
|||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ptr->svc_do_shutdown)
|
if (service_should_stop)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1698,16 +1697,11 @@ serviceEnableLocalhostMatchWildcardHost(Service *service, int action)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
volatile sig_atomic_t service_should_stop = 0;
|
||||||
|
|
||||||
void service_shutdown()
|
void service_shutdown()
|
||||||
{
|
{
|
||||||
spinlock_acquire(&service_spin);
|
service_should_stop = 1;
|
||||||
|
|
||||||
for (Service* s: allServices)
|
|
||||||
{
|
|
||||||
s->svc_do_shutdown = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
spinlock_release(&service_spin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void service_destroy_instances(void)
|
void service_destroy_instances(void)
|
||||||
|
@ -944,7 +944,7 @@ static int get_users(SERV_LISTENER *listener, bool skip_local)
|
|||||||
int total_users = -1;
|
int total_users = -1;
|
||||||
bool no_active_servers = true;
|
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) ||
|
if (!SERVER_REF_IS_ACTIVE(server) || !server_is_active(server->server) ||
|
||||||
(skip_local && server_is_mxs_service(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);
|
ss_dassert(router->binlog_fd != -1);
|
||||||
|
|
||||||
while (!router->service->svc_do_shutdown)
|
while (!service_should_stop)
|
||||||
{
|
{
|
||||||
avro_binlog_end_t rc;
|
avro_binlog_end_t rc;
|
||||||
REP_HEADER hdr;
|
REP_HEADER hdr;
|
||||||
|
@ -328,7 +328,7 @@ static bool conversion_task_ctl(Avro *inst, bool start)
|
|||||||
{
|
{
|
||||||
bool rval = false;
|
bool rval = false;
|
||||||
|
|
||||||
if (!inst->service->svc_do_shutdown)
|
if (!service_should_stop)
|
||||||
{
|
{
|
||||||
Worker* worker = static_cast<Worker*>(mxs_rworker_get(MXS_RWORKER_MAIN));
|
Worker* worker = static_cast<Worker*>(mxs_rworker_get(MXS_RWORKER_MAIN));
|
||||||
std::auto_ptr<ConversionCtlTask> task(new (std::nothrow) ConversionCtlTask(inst, start));
|
std::auto_ptr<ConversionCtlTask> task(new (std::nothrow) ConversionCtlTask(inst, start));
|
||||||
|
Reference in New Issue
Block a user