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:
parent
710f2d3c79
commit
945510e735
@ -27,19 +27,6 @@
|
||||
#include <maxscale/spinlock.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
|
||||
|
||||
struct dcb;
|
||||
@ -177,18 +164,6 @@ typedef char* (*session_variable_handler_t)(void* context,
|
||||
const char* value_begin,
|
||||
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
|
||||
*
|
||||
@ -218,14 +193,11 @@ typedef struct session
|
||||
bool autocommit; /*< Whether autocommit is on. */
|
||||
intptr_t client_protocol_data; /*< Owned and managed by the client protocol. */
|
||||
bool qualifies_for_pooling; /**< Whether this session qualifies for the connection pool */
|
||||
SessionVarsByName* variables; /*< @maxscale variables associated with this session */
|
||||
struct
|
||||
{
|
||||
MXS_UPSTREAM up; /*< Upward component to receive buffer. */
|
||||
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 */
|
||||
session_close_t close_reason; /*< Reason why the session was closed */
|
||||
skygw_chk_t ses_chk_tail;
|
||||
} MXS_SESSION;
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <maxscale/adminusers.h>
|
||||
#include <maxscale/alloc.h>
|
||||
|
@ -13,6 +13,13 @@
|
||||
*/
|
||||
|
||||
#include <maxscale/cppdefs.hh>
|
||||
|
||||
#include <deque>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include <maxscale/session.h>
|
||||
#include <maxscale/resultset.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();
|
||||
|
@ -67,7 +67,7 @@ static void session_add_to_all_list(MXS_SESSION *session);
|
||||
static MXS_SESSION *session_find_free();
|
||||
static void session_final_free(MXS_SESSION *session);
|
||||
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);
|
||||
|
||||
/**
|
||||
@ -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);
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
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 = (MXS_SESSION *)(MXS_MALLOC(sizeof(*session)));
|
||||
SessionVarsByName *session_variables = new (std::nothrow) SessionVarsByName;
|
||||
DCBSet* dcb_set = new (std::nothrow) DCBSet;
|
||||
Session *session = new (std::nothrow) Session;
|
||||
|
||||
if ((session == NULL) || (session_variables == NULL) || (dcb_set == NULL))
|
||||
if (session == nullptr)
|
||||
{
|
||||
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);
|
||||
return session_alloc_body(service, client_dcb, session, id);
|
||||
}
|
||||
|
||||
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->router_session = NULL;
|
||||
session->stats.connect = time(0);
|
||||
session->qualifies_for_pooling = false;
|
||||
session->close_reason = SESSION_CLOSE_NONE;
|
||||
|
||||
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->service = service;
|
||||
memset(&session->head, 0, sizeof(session->head));
|
||||
memset(&session->tail, 0, sizeof(session->tail));
|
||||
|
||||
/*<
|
||||
* 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 has not been made available to the other threads at this
|
||||
* 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;
|
||||
/*<
|
||||
* 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->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
|
||||
* 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);
|
||||
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;
|
||||
|
||||
return (session->state == SESSION_STATE_TO_BE_FREED) ? NULL : session;
|
||||
}
|
||||
|
||||
@ -432,10 +414,7 @@ session_final_free(MXS_SESSION *session)
|
||||
session_dump_statements(session);
|
||||
}
|
||||
|
||||
delete session->variables;
|
||||
delete session->last_statements;
|
||||
delete session->dcb_set;
|
||||
MXS_FREE(session);
|
||||
delete session;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,16 +37,11 @@ Session::Session(Client* pClient)
|
||||
|
||||
strcpy(m_mysql_session.db, "dummy");
|
||||
|
||||
pSession->variables = new SessionVarsByName;
|
||||
|
||||
m_client_dcb.data = &m_mysql_session;
|
||||
}
|
||||
|
||||
Session::~Session()
|
||||
{
|
||||
delete variables;
|
||||
delete last_statements;
|
||||
delete dcb_set;
|
||||
}
|
||||
|
||||
Client& Session::client() const
|
||||
|
Loading…
x
Reference in New Issue
Block a user