MXS-1929: Add Session class
The Session class now contains all of the C++ objects that were previously in the MXS_SESSION struct. It is also allocated with new but all initialization is still done outside of the Session in session_alloc_body. This commit will not compile as it is a part of a set of commits that make parts of the session private.
This commit is contained in:
@ -27,19 +27,6 @@
|
|||||||
#include <maxscale/spinlock.h>
|
#include <maxscale/spinlock.h>
|
||||||
#include <maxscale/jansson.h>
|
#include <maxscale/jansson.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <unordered_set>
|
|
||||||
#include <string>
|
|
||||||
#include <deque>
|
|
||||||
#include <vector>
|
|
||||||
typedef std::deque<std::vector<uint8_t> > SessionStmtQueue;
|
|
||||||
typedef std::unordered_set<DCB*> DCBSet;
|
|
||||||
#else
|
|
||||||
typedef void SessionStmtQueue;
|
|
||||||
typedef void DCBSet;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MXS_BEGIN_DECLS
|
MXS_BEGIN_DECLS
|
||||||
|
|
||||||
struct dcb;
|
struct dcb;
|
||||||
@ -177,18 +164,6 @@ typedef char* (*session_variable_handler_t)(void* context,
|
|||||||
const char* value_begin,
|
const char* value_begin,
|
||||||
const char* value_end);
|
const char* value_end);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
typedef struct session_variable
|
|
||||||
{
|
|
||||||
session_variable_handler_t handler;
|
|
||||||
void* context;
|
|
||||||
} SESSION_VARIABLE;
|
|
||||||
|
|
||||||
typedef std::unordered_map<std::string, SESSION_VARIABLE> SessionVarsByName;
|
|
||||||
#else
|
|
||||||
typedef void SessionVarsByName;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The session status block
|
* The session status block
|
||||||
*
|
*
|
||||||
@ -218,14 +193,11 @@ typedef struct session
|
|||||||
bool autocommit; /*< Whether autocommit is on. */
|
bool autocommit; /*< Whether autocommit is on. */
|
||||||
intptr_t client_protocol_data; /*< Owned and managed by the client protocol. */
|
intptr_t client_protocol_data; /*< Owned and managed by the client protocol. */
|
||||||
bool qualifies_for_pooling; /**< Whether this session qualifies for the connection pool */
|
bool qualifies_for_pooling; /**< Whether this session qualifies for the connection pool */
|
||||||
SessionVarsByName* variables; /*< @maxscale variables associated with this session */
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
MXS_UPSTREAM up; /*< Upward component to receive buffer. */
|
MXS_UPSTREAM up; /*< Upward component to receive buffer. */
|
||||||
GWBUF* buffer; /*< Buffer to deliver to up. */
|
GWBUF* buffer; /*< Buffer to deliver to up. */
|
||||||
} response; /*< Shortcircuited response */
|
} response; /*< Shortcircuited response */
|
||||||
SessionStmtQueue* last_statements; /*< The N last statements by the client */
|
|
||||||
DCBSet* dcb_set; /*< Set of associated backend DCBs */
|
|
||||||
session_close_t close_reason; /*< Reason why the session was closed */
|
session_close_t close_reason; /*< Reason why the session was closed */
|
||||||
skygw_chk_t ses_chk_tail;
|
skygw_chk_t ses_chk_tail;
|
||||||
} MXS_SESSION;
|
} MXS_SESSION;
|
||||||
|
|||||||
@ -37,6 +37,7 @@
|
|||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#include <maxscale/adminusers.h>
|
#include <maxscale/adminusers.h>
|
||||||
#include <maxscale/alloc.h>
|
#include <maxscale/alloc.h>
|
||||||
|
|||||||
@ -13,6 +13,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <maxscale/cppdefs.hh>
|
#include <maxscale/cppdefs.hh>
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <maxscale/session.h>
|
#include <maxscale/session.h>
|
||||||
#include <maxscale/resultset.hh>
|
#include <maxscale/resultset.hh>
|
||||||
#include <maxscale/utils.hh>
|
#include <maxscale/utils.hh>
|
||||||
@ -40,4 +47,22 @@ struct RegistryTraits<MXS_SESSION>
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct SESSION_VARIABLE
|
||||||
|
{
|
||||||
|
session_variable_handler_t handler;
|
||||||
|
void* context;
|
||||||
|
} SESSION_VARIABLE;
|
||||||
|
|
||||||
|
typedef std::unordered_map<std::string, SESSION_VARIABLE> SessionVarsByName;
|
||||||
|
typedef std::deque<std::vector<uint8_t>> SessionStmtQueue;
|
||||||
|
typedef std::unordered_set<DCB*> DCBSet;
|
||||||
|
|
||||||
|
class Session: public MXS_SESSION
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
SessionVarsByName m_variables;
|
||||||
|
SessionStmtQueue m_last_statements; /*< The N last statements by the client */
|
||||||
|
DCBSet m_dcb_set; /*< Set of associated backend DCBs */
|
||||||
|
};
|
||||||
|
|
||||||
std::unique_ptr<ResultSet> sessionGetList();
|
std::unique_ptr<ResultSet> sessionGetList();
|
||||||
|
|||||||
@ -67,7 +67,7 @@ static void session_add_to_all_list(MXS_SESSION *session);
|
|||||||
static MXS_SESSION *session_find_free();
|
static MXS_SESSION *session_find_free();
|
||||||
static void session_final_free(MXS_SESSION *session);
|
static void session_final_free(MXS_SESSION *session);
|
||||||
static MXS_SESSION* session_alloc_body(SERVICE* service, DCB* client_dcb,
|
static MXS_SESSION* session_alloc_body(SERVICE* service, DCB* client_dcb,
|
||||||
MXS_SESSION* session);
|
MXS_SESSION* session, uint64_t id);
|
||||||
static void session_deliver_response(MXS_SESSION* session);
|
static void session_deliver_response(MXS_SESSION* session);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -79,25 +79,6 @@ static void session_deliver_response(MXS_SESSION* session);
|
|||||||
*/
|
*/
|
||||||
static int session_reply(MXS_FILTER *inst, MXS_FILTER_SESSION *session, GWBUF *data);
|
static int session_reply(MXS_FILTER *inst, MXS_FILTER_SESSION *session, GWBUF *data);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize a session
|
|
||||||
*
|
|
||||||
* This routine puts initial values into the fields of the session pointed to
|
|
||||||
* by the parameter.
|
|
||||||
*
|
|
||||||
* @param *session Pointer to the session to be initialized
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
session_initialize(MXS_SESSION *session)
|
|
||||||
{
|
|
||||||
memset(session, 0, sizeof(MXS_SESSION));
|
|
||||||
|
|
||||||
session->ses_chk_top = CHK_NUM_SESSION;
|
|
||||||
session->state = SESSION_STATE_ALLOC;
|
|
||||||
session->last_statements = new SessionStmtQueue;
|
|
||||||
session->ses_chk_tail = CHK_NUM_SESSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
MXS_SESSION* session_alloc(SERVICE *service, DCB *client_dcb)
|
MXS_SESSION* session_alloc(SERVICE *service, DCB *client_dcb)
|
||||||
{
|
{
|
||||||
return session_alloc_with_id(service, client_dcb, session_get_next_id());
|
return session_alloc_with_id(service, client_dcb, session_get_next_id());
|
||||||
@ -105,39 +86,28 @@ MXS_SESSION* session_alloc(SERVICE *service, DCB *client_dcb)
|
|||||||
|
|
||||||
MXS_SESSION* session_alloc_with_id(SERVICE *service, DCB *client_dcb, uint64_t id)
|
MXS_SESSION* session_alloc_with_id(SERVICE *service, DCB *client_dcb, uint64_t id)
|
||||||
{
|
{
|
||||||
MXS_SESSION *session = (MXS_SESSION *)(MXS_MALLOC(sizeof(*session)));
|
Session *session = new (std::nothrow) Session;
|
||||||
SessionVarsByName *session_variables = new (std::nothrow) SessionVarsByName;
|
|
||||||
DCBSet* dcb_set = new (std::nothrow) DCBSet;
|
|
||||||
|
|
||||||
if ((session == NULL) || (session_variables == NULL) || (dcb_set == NULL))
|
if (session == nullptr)
|
||||||
{
|
{
|
||||||
MXS_FREE(session);
|
|
||||||
delete session_variables;
|
|
||||||
delete dcb_set;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
session_initialize(session);
|
return session_alloc_body(service, client_dcb, session, id);
|
||||||
session->variables = session_variables;
|
|
||||||
session->dcb_set = dcb_set;
|
|
||||||
session->ses_id = id;
|
|
||||||
return session_alloc_body(service, client_dcb, session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static MXS_SESSION* session_alloc_body(SERVICE* service, DCB* client_dcb,
|
static MXS_SESSION* session_alloc_body(SERVICE* service, DCB* client_dcb,
|
||||||
MXS_SESSION* session)
|
MXS_SESSION* session, uint64_t id)
|
||||||
{
|
{
|
||||||
session->service = service;
|
session->ses_chk_top = CHK_NUM_SESSION;
|
||||||
|
session->state = SESSION_STATE_READY;
|
||||||
|
session->ses_id = id;
|
||||||
session->client_dcb = client_dcb;
|
session->client_dcb = client_dcb;
|
||||||
|
session->router_session = NULL;
|
||||||
session->stats.connect = time(0);
|
session->stats.connect = time(0);
|
||||||
session->qualifies_for_pooling = false;
|
session->service = service;
|
||||||
session->close_reason = SESSION_CLOSE_NONE;
|
memset(&session->head, 0, sizeof(session->head));
|
||||||
|
memset(&session->tail, 0, sizeof(session->tail));
|
||||||
MXS_CONFIG *config = config_get_global_options();
|
|
||||||
// If MaxScale is running in Oracle mode, then autocommit needs to
|
|
||||||
// initially be off.
|
|
||||||
bool autocommit = (config->qc_sql_mode == QC_SQL_MODE_ORACLE) ? false : true;
|
|
||||||
session_set_autocommit(session, autocommit);
|
|
||||||
|
|
||||||
/*<
|
/*<
|
||||||
* Associate the session to the client DCB and set the reference count on
|
* Associate the session to the client DCB and set the reference count on
|
||||||
@ -145,16 +115,25 @@ static MXS_SESSION* session_alloc_body(SERVICE* service, DCB* client_dcb,
|
|||||||
* session. There is no need to protect this or use atomic add as the
|
* session. There is no need to protect this or use atomic add as the
|
||||||
* session has not been made available to the other threads at this
|
* session has not been made available to the other threads at this
|
||||||
* point.
|
* point.
|
||||||
|
*
|
||||||
|
* Note: Strictly speaking, we do have to increment it with a relaxed atomic
|
||||||
|
* operation but in practice it doesn't matter.
|
||||||
*/
|
*/
|
||||||
session->refcount = 1;
|
session->refcount = 1;
|
||||||
/*<
|
|
||||||
* This indicates that session is ready to be shared with backend
|
|
||||||
* DCBs. Note that this doesn't mean that router is initialized yet!
|
|
||||||
*/
|
|
||||||
session->state = SESSION_STATE_READY;
|
|
||||||
|
|
||||||
session->trx_state = SESSION_TRX_INACTIVE;
|
session->trx_state = SESSION_TRX_INACTIVE;
|
||||||
session->autocommit = true;
|
|
||||||
|
MXS_CONFIG *config = config_get_global_options();
|
||||||
|
// If MaxScale is running in Oracle mode, then autocommit needs to
|
||||||
|
// initially be off.
|
||||||
|
bool autocommit = (config->qc_sql_mode == QC_SQL_MODE_ORACLE) ? false : true;
|
||||||
|
session_set_autocommit(session, autocommit);
|
||||||
|
|
||||||
|
session->client_protocol_data = 0;
|
||||||
|
session->qualifies_for_pooling = false;
|
||||||
|
memset(&session->response, 0, sizeof(session->response));
|
||||||
|
session->close_reason = SESSION_CLOSE_NONE;
|
||||||
|
session->ses_chk_tail = CHK_NUM_SESSION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Only create a router session if we are not the listening DCB or an
|
* Only create a router session if we are not the listening DCB or an
|
||||||
* internal DCB. Creating a router session may create a connection to
|
* internal DCB. Creating a router session may create a connection to
|
||||||
@ -240,7 +219,10 @@ static MXS_SESSION* session_alloc_body(SERVICE* service, DCB* client_dcb,
|
|||||||
atomic_add(&service->stats.n_current, 1);
|
atomic_add(&service->stats.n_current, 1);
|
||||||
CHK_SESSION(session);
|
CHK_SESSION(session);
|
||||||
|
|
||||||
|
// Store the session in the client DCB even if the session creation fails.
|
||||||
|
// It will be freed later on when the DCB is closed.
|
||||||
client_dcb->session = session;
|
client_dcb->session = session;
|
||||||
|
|
||||||
return (session->state == SESSION_STATE_TO_BE_FREED) ? NULL : session;
|
return (session->state == SESSION_STATE_TO_BE_FREED) ? NULL : session;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,10 +414,7 @@ session_final_free(MXS_SESSION *session)
|
|||||||
session_dump_statements(session);
|
session_dump_statements(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete session->variables;
|
delete session;
|
||||||
delete session->last_statements;
|
|
||||||
delete session->dcb_set;
|
|
||||||
MXS_FREE(session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -37,16 +37,11 @@ Session::Session(Client* pClient)
|
|||||||
|
|
||||||
strcpy(m_mysql_session.db, "dummy");
|
strcpy(m_mysql_session.db, "dummy");
|
||||||
|
|
||||||
pSession->variables = new SessionVarsByName;
|
|
||||||
|
|
||||||
m_client_dcb.data = &m_mysql_session;
|
m_client_dcb.data = &m_mysql_session;
|
||||||
}
|
}
|
||||||
|
|
||||||
Session::~Session()
|
Session::~Session()
|
||||||
{
|
{
|
||||||
delete variables;
|
|
||||||
delete last_statements;
|
|
||||||
delete dcb_set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Client& Session::client() const
|
Client& Session::client() const
|
||||||
|
|||||||
Reference in New Issue
Block a user