Remove direct freeing of sessions
Sessions are now always freed by releasing the last reference to it.
This commit is contained in:
@ -204,7 +204,6 @@ typedef struct session
|
|||||||
|
|
||||||
SESSION *session_alloc(struct service *, struct dcb *);
|
SESSION *session_alloc(struct service *, struct dcb *);
|
||||||
SESSION *session_set_dummy(struct dcb *);
|
SESSION *session_set_dummy(struct dcb *);
|
||||||
bool session_free(SESSION *);
|
|
||||||
int session_isvalid(SESSION *);
|
int session_isvalid(SESSION *);
|
||||||
int session_reply(void *inst, void *session, GWBUF *data);
|
int session_reply(void *inst, void *session, GWBUF *data);
|
||||||
char *session_get_remote(SESSION *);
|
char *session_get_remote(SESSION *);
|
||||||
@ -347,10 +346,22 @@ static inline bool session_set_autocommit(SESSION* ses, bool autocommit)
|
|||||||
* @param id Unique session ID
|
* @param id Unique session ID
|
||||||
* @return Reference to a SESSION or NULL if the session was not found
|
* @return Reference to a SESSION or NULL if the session was not found
|
||||||
*
|
*
|
||||||
* @note The caller must free the session reference by passing it to the
|
* @note The caller must free the session reference by calling session_put_ref
|
||||||
* @c session_put_ref function
|
|
||||||
*/
|
*/
|
||||||
SESSION* session_get_ref(int id);
|
SESSION* session_get_by_id(int id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a session reference
|
||||||
|
*
|
||||||
|
* This creates an additional reference to a session which allows it to live
|
||||||
|
* as long as it is needed.
|
||||||
|
*
|
||||||
|
* @param session Session reference to get
|
||||||
|
* @return Reference to a SESSION
|
||||||
|
*
|
||||||
|
* @note The caller must free the session reference by calling session_put_ref
|
||||||
|
*/
|
||||||
|
SESSION* session_get_ref(SESSION *sessoin);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Release a session reference
|
* @brief Release a session reference
|
||||||
|
@ -348,7 +348,7 @@ dcb_final_free(DCB *dcb)
|
|||||||
bool is_client_dcb = (DCB_ROLE_CLIENT_HANDLER == dcb->dcb_role ||
|
bool is_client_dcb = (DCB_ROLE_CLIENT_HANDLER == dcb->dcb_role ||
|
||||||
DCB_ROLE_INTERNAL == dcb->dcb_role);
|
DCB_ROLE_INTERNAL == dcb->dcb_role);
|
||||||
|
|
||||||
session_free(local_session);
|
session_put_ref(local_session);
|
||||||
|
|
||||||
if (is_client_dcb)
|
if (is_client_dcb)
|
||||||
{
|
{
|
||||||
@ -1714,7 +1714,7 @@ dcb_maybe_add_persistent(DCB *dcb)
|
|||||||
CHK_SESSION(local_session);
|
CHK_SESSION(local_session);
|
||||||
if (SESSION_STATE_DUMMY != local_session->state)
|
if (SESSION_STATE_DUMMY != local_session->state)
|
||||||
{
|
{
|
||||||
session_free(local_session);
|
session_put_ref(local_session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spinlock_acquire(&dcb->cb_lock);
|
spinlock_acquire(&dcb->cb_lock);
|
||||||
|
@ -277,7 +277,7 @@ static bool process_argument(modulecmd_arg_type_t *type, const void* value,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MODULECMD_ARG_SESSION:
|
case MODULECMD_ARG_SESSION:
|
||||||
if ((arg->value.session = session_get_ref(atoi(value))))
|
if ((arg->value.session = session_get_by_id(atoi(value))))
|
||||||
{
|
{
|
||||||
arg->type.type = MODULECMD_ARG_SESSION;
|
arg->type.type = MODULECMD_ARG_SESSION;
|
||||||
}
|
}
|
||||||
|
@ -336,31 +336,14 @@ session_simple_free(SESSION *session, DCB *dcb)
|
|||||||
*
|
*
|
||||||
* @param session The session to deallocate
|
* @param session The session to deallocate
|
||||||
*/
|
*/
|
||||||
bool
|
static void session_free(SESSION *session)
|
||||||
session_free(SESSION *session)
|
|
||||||
{
|
{
|
||||||
if (NULL == session || SESSION_STATE_DUMMY == session->state)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
CHK_SESSION(session);
|
CHK_SESSION(session);
|
||||||
|
ss_dassert(session->refcount == 0);
|
||||||
|
|
||||||
/*
|
|
||||||
* Remove one reference. If there are no references left,
|
|
||||||
* free session.
|
|
||||||
*/
|
|
||||||
if (atomic_add(&session->refcount, -1) > 1)
|
|
||||||
{
|
|
||||||
/* Must be one or more references left */
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
session->state = SESSION_STATE_TO_BE_FREED;
|
session->state = SESSION_STATE_TO_BE_FREED;
|
||||||
|
|
||||||
atomic_add(&session->service->stats.n_current, -1);
|
atomic_add(&session->service->stats.n_current, -1);
|
||||||
|
|
||||||
/***
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
if (session->client_dcb)
|
if (session->client_dcb)
|
||||||
{
|
{
|
||||||
dcb_free_all_memory(session->client_dcb);
|
dcb_free_all_memory(session->client_dcb);
|
||||||
@ -396,9 +379,7 @@ session_free(SESSION *session)
|
|||||||
MXS_FREE(session->filters);
|
MXS_FREE(session->filters);
|
||||||
}
|
}
|
||||||
|
|
||||||
MXS_INFO("Stopped %s client session [%lu]",
|
MXS_INFO("Stopped %s client session [%lu]", session->service->name, session->ses_id);
|
||||||
session->service->name,
|
|
||||||
session->ses_id);
|
|
||||||
|
|
||||||
/** Disable trace and decrease trace logger counter */
|
/** Disable trace and decrease trace logger counter */
|
||||||
session_disable_log_priority(session, LOG_INFO);
|
session_disable_log_priority(session, LOG_INFO);
|
||||||
@ -409,7 +390,6 @@ session_free(SESSION *session)
|
|||||||
session->state = SESSION_STATE_FREE;
|
session->state = SESSION_STATE_FREE;
|
||||||
session_final_free(session);
|
session_final_free(session);
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -925,17 +905,14 @@ static bool ses_find_id(DCB *dcb, void *data)
|
|||||||
|
|
||||||
if (dcb->session->ses_id == *id)
|
if (dcb->session->ses_id == *id)
|
||||||
{
|
{
|
||||||
/** We need to increment the reference count of the session to prevent it
|
*ses = session_get_ref(dcb->session);
|
||||||
* from being freed while it's in use. */
|
|
||||||
atomic_add(&dcb->session->refcount, 1);
|
|
||||||
*ses = dcb->session;
|
|
||||||
rval = false;
|
rval = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
SESSION* session_get_ref(int id)
|
SESSION* session_get_by_id(int id)
|
||||||
{
|
{
|
||||||
SESSION *session = NULL;
|
SESSION *session = NULL;
|
||||||
void *params[] = {&session, &id};
|
void *params[] = {&session, &id};
|
||||||
@ -945,10 +922,20 @@ SESSION* session_get_ref(int id)
|
|||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SESSION* session_get_ref(SESSION *session)
|
||||||
|
{
|
||||||
|
atomic_add(&session->refcount, 1);
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
|
||||||
void session_put_ref(SESSION *session)
|
void session_put_ref(SESSION *session)
|
||||||
{
|
{
|
||||||
if (session)
|
if (session && session->state != SESSION_STATE_DUMMY)
|
||||||
{
|
{
|
||||||
session_free(session);
|
/** Remove one reference. If there are no references left, free session */
|
||||||
|
if (atomic_add(&session->refcount, -1) == 1)
|
||||||
|
{
|
||||||
|
session_free(session);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -701,7 +701,7 @@ freeSession(FILTER *instance, void *session)
|
|||||||
|
|
||||||
if (state == SESSION_STATE_ROUTER_READY)
|
if (state == SESSION_STATE_ROUTER_READY)
|
||||||
{
|
{
|
||||||
session_free(ses);
|
session_put_ref(ses);
|
||||||
}
|
}
|
||||||
else if (state == SESSION_STATE_TO_BE_FREED)
|
else if (state == SESSION_STATE_TO_BE_FREED)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user