diff --git a/include/maxscale/session.h b/include/maxscale/session.h index 6b5f401c7..3553cc0ab 100644 --- a/include/maxscale/session.h +++ b/include/maxscale/session.h @@ -204,7 +204,6 @@ typedef struct session SESSION *session_alloc(struct service *, struct dcb *); SESSION *session_set_dummy(struct dcb *); -bool session_free(SESSION *); int session_isvalid(SESSION *); int session_reply(void *inst, void *session, GWBUF *data); char *session_get_remote(SESSION *); @@ -347,10 +346,22 @@ static inline bool session_set_autocommit(SESSION* ses, bool autocommit) * @param id Unique session ID * @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 - * @c session_put_ref function + * @note The caller must free the session reference by calling session_put_ref */ -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 diff --git a/server/core/dcb.c b/server/core/dcb.c index 8589315fb..8ac2fd1f7 100644 --- a/server/core/dcb.c +++ b/server/core/dcb.c @@ -348,7 +348,7 @@ dcb_final_free(DCB *dcb) bool is_client_dcb = (DCB_ROLE_CLIENT_HANDLER == dcb->dcb_role || DCB_ROLE_INTERNAL == dcb->dcb_role); - session_free(local_session); + session_put_ref(local_session); if (is_client_dcb) { @@ -1714,7 +1714,7 @@ dcb_maybe_add_persistent(DCB *dcb) CHK_SESSION(local_session); if (SESSION_STATE_DUMMY != local_session->state) { - session_free(local_session); + session_put_ref(local_session); } } spinlock_acquire(&dcb->cb_lock); diff --git a/server/core/modulecmd.c b/server/core/modulecmd.c index d9146563a..d3cdd38b3 100644 --- a/server/core/modulecmd.c +++ b/server/core/modulecmd.c @@ -277,7 +277,7 @@ static bool process_argument(modulecmd_arg_type_t *type, const void* value, break; 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; } diff --git a/server/core/session.c b/server/core/session.c index 15fc6207b..54ab0fe81 100644 --- a/server/core/session.c +++ b/server/core/session.c @@ -336,31 +336,14 @@ session_simple_free(SESSION *session, DCB *dcb) * * @param session The session to deallocate */ -bool -session_free(SESSION *session) +static void session_free(SESSION *session) { - if (NULL == session || SESSION_STATE_DUMMY == session->state) - { - return true; - } 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; - atomic_add(&session->service->stats.n_current, -1); - /*** - * - */ if (session->client_dcb) { dcb_free_all_memory(session->client_dcb); @@ -396,9 +379,7 @@ session_free(SESSION *session) MXS_FREE(session->filters); } - MXS_INFO("Stopped %s client session [%lu]", - session->service->name, - session->ses_id); + MXS_INFO("Stopped %s client session [%lu]", session->service->name, session->ses_id); /** Disable trace and decrease trace logger counter */ session_disable_log_priority(session, LOG_INFO); @@ -409,7 +390,6 @@ session_free(SESSION *session) session->state = SESSION_STATE_FREE; session_final_free(session); } - return true; } static void @@ -925,17 +905,14 @@ static bool ses_find_id(DCB *dcb, void *data) if (dcb->session->ses_id == *id) { - /** We need to increment the reference count of the session to prevent it - * from being freed while it's in use. */ - atomic_add(&dcb->session->refcount, 1); - *ses = dcb->session; + *ses = session_get_ref(dcb->session); rval = false; } return rval; } -SESSION* session_get_ref(int id) +SESSION* session_get_by_id(int id) { SESSION *session = NULL; void *params[] = {&session, &id}; @@ -945,10 +922,20 @@ SESSION* session_get_ref(int id) return session; } +SESSION* session_get_ref(SESSION *session) +{ + atomic_add(&session->refcount, 1); + return 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); + } } } diff --git a/server/modules/filter/tee/tee.c b/server/modules/filter/tee/tee.c index 26a15e130..0e8707b77 100644 --- a/server/modules/filter/tee/tee.c +++ b/server/modules/filter/tee/tee.c @@ -701,7 +701,7 @@ freeSession(FILTER *instance, void *session) if (state == SESSION_STATE_ROUTER_READY) { - session_free(ses); + session_put_ref(ses); } else if (state == SESSION_STATE_TO_BE_FREED) {