From 643fc825fae02fee3b734970c236ce4ba85b86a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Fri, 18 May 2018 10:07:34 +0300 Subject: [PATCH] MXS-553: Provide full session to DCB mapping By storing a link to the backend DCBs in the session object itself, we can reach all related objects from the session. This removes the need to iterate over all DCBs to find the set of related DCBs. --- include/maxscale/session.h | 4 ++++ server/core/dcb.cc | 10 +++++----- server/core/internal/session.h | 8 ++++++++ server/core/session.cc | 14 ++++++++++++-- server/modules/filter/test/mock_session.cc | 2 ++ 5 files changed, 31 insertions(+), 7 deletions(-) diff --git a/include/maxscale/session.h b/include/maxscale/session.h index c401fe9d3..d86c063e5 100644 --- a/include/maxscale/session.h +++ b/include/maxscale/session.h @@ -29,12 +29,15 @@ #ifdef __cplusplus #include +#include #include #include #include typedef std::deque > SessionStmtQueue; +typedef std::tr1::unordered_set DCBSet; #else typedef void SessionStmtQueue; +typedef void DCBSet; #endif MXS_BEGIN_DECLS @@ -211,6 +214,7 @@ typedef struct session GWBUF* buffer; /*< Buffer to deliver to up. */ } response; /*< Shortcircuited response */ SessionStmtQueue* last_statements; /*< The N last statements by the client */ + DCBSet* dcb_set; /*< Set of associated backend DCBs */ skygw_chk_t ses_chk_tail; } MXS_SESSION; diff --git a/server/core/dcb.cc b/server/core/dcb.cc index a9f7ac094..7d9612a71 100644 --- a/server/core/dcb.cc +++ b/server/core/dcb.cc @@ -245,7 +245,7 @@ dcb_final_free(DCB *dcb) DCB_ROLE_SERVICE_LISTENER == dcb->dcb_role || DCB_ROLE_INTERNAL == dcb->dcb_role); - session_put_ref(local_session); + session_unlink_backend_dcb(local_session, dcb); if (is_client_dcb) { @@ -464,7 +464,7 @@ dcb_connect(SERVER *server, MXS_SESSION *session, const char *protocol) MXS_DEBUG("Failed to connect to server [%s]:%d, from backend dcb %p, client dcp %p fd %d", server->address, server->port, dcb, session->client_dcb, session->client_dcb->fd); // Remove the inc ref that was done in session_link_backend_dcb(). - session_put_ref(dcb->session); + session_unlink_backend_dcb(dcb->session, dcb); dcb->session = NULL; dcb_free_all_memory(dcb); return NULL; @@ -501,7 +501,7 @@ dcb_connect(SERVER *server, MXS_SESSION *session, const char *protocol) close(dcb->fd); dcb->fd = DCBFD_CLOSED; // Remove the inc ref that was done in session_link_backend_dcb(). - session_put_ref(dcb->session); + session_unlink_backend_dcb(dcb->session, dcb); dcb->session = NULL; dcb_free_all_memory(dcb); return NULL; @@ -517,7 +517,7 @@ dcb_connect(SERVER *server, MXS_SESSION *session, const char *protocol) close(dcb->fd); dcb->fd = DCBFD_CLOSED; // Remove the inc ref that was done in session_link_backend_dcb(). - session_put_ref(dcb->session); + session_unlink_backend_dcb(dcb->session, dcb); dcb->session = NULL; dcb_free_all_memory(dcb); return NULL; @@ -1326,7 +1326,7 @@ dcb_maybe_add_persistent(DCB *dcb) CHK_SESSION(local_session); if (SESSION_STATE_DUMMY != local_session->state) { - session_put_ref(local_session); + session_unlink_backend_dcb(local_session, dcb); } } diff --git a/server/core/internal/session.h b/server/core/internal/session.h index 6867d7ba9..6fb8254d4 100644 --- a/server/core/internal/session.h +++ b/server/core/internal/session.h @@ -51,6 +51,14 @@ const char *session_state(mxs_session_state_t); */ void session_link_backend_dcb(MXS_SESSION *session, struct dcb *dcb); +/** + * Unlink a session to a backend DCB. + * + * @param session The session to unlink with the dcb + * @param dcb The backend DCB to be unlinked + */ +void session_unlink_backend_dcb(MXS_SESSION *session, struct dcb *dcb); + RESULTSET *sessionGetList(SESSIONLISTFILTER); void printAllSessions(); diff --git a/server/core/session.cc b/server/core/session.cc index 5ac85b49d..f75119c1d 100644 --- a/server/core/session.cc +++ b/server/core/session.cc @@ -106,17 +106,19 @@ MXS_SESSION* session_alloc_with_id(SERVICE *service, DCB *client_dcb, uint64_t i { MXS_SESSION *session = (MXS_SESSION *)(MXS_MALLOC(sizeof(*session))); SessionVarsByName *session_variables = new (std::nothrow) SessionVarsByName; + DCBSet* dcb_set = new (std::nothrow) DCBSet; - if ((session == NULL) || (session_variables == NULL)) + if ((session == NULL) || (session_variables == NULL) || (dcb_set == NULL)) { MXS_FREE(session); delete session_variables; - + delete dcb_set; return NULL; } session_initialize(session); session->variables = session_variables; + session->dcb_set = dcb_set; session->ses_id = id; return session_alloc_body(service, client_dcb, session); } @@ -279,6 +281,13 @@ void session_link_backend_dcb(MXS_SESSION *session, DCB *dcb) dcb->service = session->service; /** Move this DCB under the same thread */ dcb->poll.thread.id = session->client_dcb->poll.thread.id; + session->dcb_set->insert(dcb); +} + +void session_unlink_backend_dcb(MXS_SESSION *session, DCB *dcb) +{ + session->dcb_set->erase(dcb); + session_put_ref(session); } /** @@ -396,6 +405,7 @@ session_final_free(MXS_SESSION *session) delete session->variables; delete session->last_statements; + delete session->dcb_set; MXS_FREE(session); } diff --git a/server/modules/filter/test/mock_session.cc b/server/modules/filter/test/mock_session.cc index ecac686de..5a15ce7f8 100644 --- a/server/modules/filter/test/mock_session.cc +++ b/server/modules/filter/test/mock_session.cc @@ -45,6 +45,8 @@ Session::Session(Client* pClient) Session::~Session() { delete variables; + delete last_statements; + delete dcb_set; } Client& Session::client() const