client->data is copied to session->data already in session_alloc to ensure that authentication information is set when background connection is started to establish in concurrent thread.
This commit is contained in:
parent
786468fc5d
commit
9a8e271417
@ -31,12 +31,16 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <session.h>
|
||||
#include <service.h>
|
||||
#include <router.h>
|
||||
#include <dcb.h>
|
||||
#include <spinlock.h>
|
||||
#include <atomic.h>
|
||||
#include <skygw_utils.h>
|
||||
#include <log_manager.h>
|
||||
|
||||
|
||||
static SPINLOCK session_spin = SPINLOCK_INIT;
|
||||
static SESSION *allSessions = NULL;
|
||||
@ -55,18 +59,40 @@ static SESSION *allSessions = NULL;
|
||||
SESSION *
|
||||
session_alloc(SERVICE *service, DCB *client)
|
||||
{
|
||||
SESSION *session;
|
||||
SESSION *session;
|
||||
|
||||
if ((session = (SESSION *)malloc(sizeof(SESSION))) == NULL)
|
||||
session = (SESSION *)calloc(1, sizeof(SESSION));
|
||||
|
||||
if (session == NULL) {
|
||||
int eno = errno;
|
||||
errno = 0;
|
||||
skygw_log_write_flush(
|
||||
LOGFILE_ERROR,
|
||||
"%lu [session_alloc] Allocating memory for session "
|
||||
"object failed. Errno %d, %s.",
|
||||
pthread_self(),
|
||||
eno,
|
||||
strerror(eno));
|
||||
return NULL;
|
||||
}
|
||||
session->ses_chk_top = CHK_NUM_SESSION;
|
||||
session->ses_chk_tail = CHK_NUM_SESSION;
|
||||
spinlock_init(&session->ses_lock);
|
||||
session->service = service;
|
||||
/**
|
||||
* Prevent backend threads from accessing before session is completely
|
||||
* initialized.
|
||||
*/
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
session->service = service;
|
||||
session->client = client;
|
||||
memset(&session->stats, 0, sizeof(SESSION_STATS));
|
||||
session->stats.connect = time(0);
|
||||
session->state = SESSION_STATE_ALLOC;
|
||||
/**
|
||||
* If client has data pointer to authentication info, set it to session.
|
||||
*/
|
||||
session->data = client->data;
|
||||
client->session = session;
|
||||
|
||||
/*
|
||||
* Only create a router session if we are not the listening
|
||||
* DCB. Creating a router session may create a connection to a
|
||||
@ -75,17 +101,22 @@ SESSION *session;
|
||||
*/
|
||||
if (client->state != DCB_STATE_LISTENING)
|
||||
{
|
||||
session->router_session = service->router->newSession(service->router_instance, session);
|
||||
session->router_session =
|
||||
service->router->newSession(service->router_instance, session);
|
||||
}
|
||||
|
||||
spinlock_acquire(&session_spin);
|
||||
session->next = allSessions;
|
||||
allSessions = session;
|
||||
spinlock_release(&session_spin);
|
||||
|
||||
/** This indicates that session is ready to be shared with backend DCBs. */
|
||||
session->state = SESSION_STATE_READY;
|
||||
/** Release session lock */
|
||||
spinlock_release(&session->ses_lock);
|
||||
|
||||
atomic_add(&service->stats.n_sessions, 1);
|
||||
atomic_add(&service->stats.n_current, 1);
|
||||
|
||||
CHK_SESSION(session);
|
||||
return session;
|
||||
}
|
||||
|
||||
@ -98,8 +129,9 @@ void
|
||||
session_free(SESSION *session)
|
||||
{
|
||||
SESSION *ptr;
|
||||
|
||||
CHK_SESSION(session);
|
||||
/* First of all remove from the linked list */
|
||||
|
||||
spinlock_acquire(&session_spin);
|
||||
if (allSessions == session)
|
||||
{
|
||||
@ -117,7 +149,6 @@ SESSION *ptr;
|
||||
}
|
||||
spinlock_release(&session_spin);
|
||||
atomic_add(&session->service->stats.n_current, -1);
|
||||
|
||||
/* Clean up session and free the memory */
|
||||
free(session);
|
||||
}
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <time.h>
|
||||
#include <atomic.h>
|
||||
#include <spinlock.h>
|
||||
#include <skygw_utils.h>
|
||||
|
||||
struct dcb;
|
||||
struct service;
|
||||
@ -46,6 +47,21 @@ typedef struct {
|
||||
time_t connect; /**< Time when the session was started */
|
||||
} SESSION_STATS;
|
||||
|
||||
|
||||
#if 0
|
||||
#define SESSION_STATE_ALLOC 0 /**< The session has been allocated */
|
||||
#define SESSION_STATE_READY 1 /**< The session is ready to route queries */
|
||||
#define SESSION_STATE_LISTENER 2 /**< The session is a running listener */
|
||||
#define SESSION_STATE_LISTENER_STOPPED 3 /**< The session listener is stopped */
|
||||
#else
|
||||
typedef enum {
|
||||
SESSION_STATE_ALLOC,
|
||||
SESSION_STATE_READY,
|
||||
SESSION_STATE_LISTENER,
|
||||
SESSION_STATE_LISTENER_STOPPED
|
||||
} session_state_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The session status block
|
||||
*
|
||||
@ -54,8 +70,9 @@ typedef struct {
|
||||
* and originating service together for the client session.
|
||||
*/
|
||||
typedef struct session {
|
||||
skygw_chk_t ses_chk_top;
|
||||
SPINLOCK ses_lock;
|
||||
int state; /**< Current descriptor state */
|
||||
session_state_t state; /**< Current descriptor state */
|
||||
struct dcb *client; /**< The client connection */
|
||||
struct dcb *backends; /**< The set of backend servers */
|
||||
void *data; /**< The session data */
|
||||
@ -63,13 +80,9 @@ typedef struct session {
|
||||
SESSION_STATS stats; /**< Session statistics */
|
||||
struct service *service; /**< The service this session is using */
|
||||
struct session *next; /**< Linked list of all sessions */
|
||||
skygw_chk_t ses_chk_tail;
|
||||
} SESSION;
|
||||
|
||||
#define SESSION_STATE_ALLOC 0 /**< The session has been allocated */
|
||||
#define SESSION_STATE_READY 1 /**< The session is ready to route queries */
|
||||
#define SESSION_STATE_LISTENER 2 /**< The session is a running listener */
|
||||
#define SESSION_STATE_LISTENER_STOPPED 3 /**< The session listener is stopped */
|
||||
|
||||
#define SESSION_PROTOCOL(x, type) DCB_PROTOCOL((x)->client, type)
|
||||
|
||||
extern SESSION *session_alloc(struct service *, struct dcb *);
|
||||
|
Loading…
x
Reference in New Issue
Block a user