Fixed idle session processing
The current implementation of idle connection timeouts is not safe. The sessions are handled in a way which is not thread-safe and the checking is done from a non-polling thread. With this change, the checks for the session timeouts are done in one of the polling threads in a thread-safe manner only if at least one service has enabled the timing out of idle client connections.
This commit is contained in:
@ -98,7 +98,7 @@ static int find_type(typelib_t* tl, const char* needle, int maxlen);
|
||||
|
||||
static void service_add_qualified_param(SERVICE* svc,
|
||||
CONFIG_PARAMETER* param);
|
||||
void service_interal_restart(void *data);
|
||||
static void service_internal_restart(void *data);
|
||||
|
||||
/**
|
||||
* Allocate a new service for the gateway to support
|
||||
@ -142,6 +142,7 @@ service_alloc(const char *servname, const char *router)
|
||||
service->resources = NULL;
|
||||
service->localhost_match_wildcard_host = SERVICE_PARAM_UNINIT;
|
||||
service->retry_start = true;
|
||||
service->conn_idle_timeout = SERVICE_NO_SESSION_TIMEOUT;
|
||||
service->weightby = NULL;
|
||||
service->credentials.authdata = NULL;
|
||||
service->credentials.name = NULL;
|
||||
@ -431,11 +432,6 @@ int serviceStartAllPorts(SERVICE* service)
|
||||
{
|
||||
service->state = SERVICE_STATE_STARTED;
|
||||
service->stats.started = time(0);
|
||||
/** Add the task that monitors session timeouts */
|
||||
if (service->conn_timeout > 0)
|
||||
{
|
||||
hktask_add("connection_timeout", session_close_timeouts, NULL, 5);
|
||||
}
|
||||
}
|
||||
else if (service->retry_start)
|
||||
{
|
||||
@ -445,7 +441,7 @@ int serviceStartAllPorts(SERVICE* service)
|
||||
int retry_after = MIN(service->stats.n_failed_starts * 10, SERVICE_MAX_RETRY_INTERVAL);
|
||||
snprintf(taskname, sizeof (taskname), "%s_start_retry_%d",
|
||||
service->name, service->stats.n_failed_starts);
|
||||
hktask_oneshot(taskname, service_interal_restart,
|
||||
hktask_oneshot(taskname, service_internal_restart,
|
||||
(void*) service, retry_after);
|
||||
MXS_NOTICE("Failed to start service %s, retrying in %d seconds.",
|
||||
service->name, retry_after);
|
||||
@ -1117,7 +1113,13 @@ serviceSetTimeout(SERVICE *service, int val)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
service->conn_timeout = val;
|
||||
|
||||
/** Enable the session timeout checks if and only if at least one service is
|
||||
* configured with a idle timeout. */
|
||||
if ((service->conn_idle_timeout = val))
|
||||
{
|
||||
enable_session_timeouts();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -2241,7 +2243,7 @@ int serviceInitSSL(SERVICE* service)
|
||||
* Function called by the housekeeper thread to retry starting of a service
|
||||
* @param data Service to restart
|
||||
*/
|
||||
void service_interal_restart(void *data)
|
||||
static void service_internal_restart(void *data)
|
||||
{
|
||||
SERVICE* service = (SERVICE*)data;
|
||||
serviceStartAllPorts(service);
|
||||
|
Reference in New Issue
Block a user