dcb.h
------- Removed DCB states DCB_STATE_IDLE, and DCB_STATE_PROCESSING. Added DCB_STATE_UNDEFINED for initial content for state variable which doesn't have any specific value set, and DCB_STATE_NOPOLLING to indicate that dcb has been removed from poll set. Added following dcb roles: DCB_ROLE_SERVICE_LISTENER for listeners of services, and DCB_ROLE_REQUEST_HANDLER for client/backend dcbs. Listeners may have state DCB_STATE_LISTENING, but not DCB_STATE_POLLING. Request handlers may have DCB_STATE_POLLING but not DCB_STATE_LISTENING. Role is passed as an argument to dcb.c:dcb_alloc. From now on, struct check numbers of DCB are included and checked in DEBUG build only. Added dcb_role_t dcb_role-member to DCB as well as SPINLOCK dcb_initlock, which protects state changes. Removed extern keyword from function declarations because functions are by default externally visible if they are declared in header. dcb.b ------ Function dcb_set_state, and dcb_set_state_nomutex provide functions for changing dcb states. Latter implements a state machine for dcb. Function dcb_add_to_zombieslist replaces dcb_free. It adds in atomic step dcb to zombieslist and changes state to DCB_STATE_ZOMBIE. Function dcb_final_free removes dcb from allDCBs list, terminates router and client sessions, and frees dcb and related memory. Function dcb_process_zombies removes executing thread from dcb's bitmask, and it there are no further thread bits, moves dcb to a victim list, and finally, for each dcb on victim list, closes fd and sets state to DCB_STATE_DISCONNECTED. Function dcb_close sets dcb state to DCB_STATE_NOPOLLIN, removes dcb from poll set and sets bit to bitmask for each server thread in an atomic step. poll.c ------ Function poll_add_dcb sets either DCB_STATE_LISTENING or DCB_STATE_POLLING state for newly created dcb, depending whether the role of dcb is DCB_ROLE_SERVICE_LISTENER, or DCB_ROLE_REQUEST_HANDLER, respectively. Then dcb is set to poll set. poll_waitevents : commented out code which skipped event if dcb was added to zombieslist or if fd was closed. Added state checks. service.c : Minor changes. httpd.c : Removed dcb state changes. They are done in core. mysql_backend.c : Added checks, removed dcb state changes. mysql_client.c : Removed dcb state changes. Added checks. mysql_common.c : Minor changes telnetd.c : Removed state changes. Replaced some typecasts and pointer references with local variable reads. skygw_debug.h : Removed two states, and added two to state printing macro.
This commit is contained in:
@ -146,37 +146,21 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
MYSQL_session *current_session = NULL;
|
||||
int rc = 0;
|
||||
|
||||
dcb->state = DCB_STATE_PROCESSING;
|
||||
CHK_DCB(dcb);
|
||||
CHK_SESSION(dcb->session);
|
||||
ss_info_dassert(dcb->session != NULL,
|
||||
"Backend dcb doesn't have session");
|
||||
|
||||
ss_info_dassert(dcb->session->client != NULL,
|
||||
"Session's client dcb pointer is NULL");
|
||||
|
||||
if(dcb->session) {
|
||||
CHK_SESSION(dcb->session);
|
||||
if (dcb->session->client == NULL) {
|
||||
dcb->state = DCB_STATE_DISCONNECTED;
|
||||
skygw_log_write(
|
||||
LOGFILE_ERROR,
|
||||
"%lu [gw_read_backend_event] client dcb is NULL for backend dcb %d.",
|
||||
pthread_self(),
|
||||
dcb->fd);
|
||||
dcb->state = DCB_STATE_DISCONNECTED;
|
||||
return 1;
|
||||
}
|
||||
client_protocol = SESSION_PROTOCOL(dcb->session, MySQLProtocol);
|
||||
} else {
|
||||
skygw_log_write(
|
||||
LOGFILE_ERROR,
|
||||
"%lu [gw_read_backend_event] dcb->session is NULL for backend dcb %d.",
|
||||
pthread_self(),
|
||||
dcb->fd);
|
||||
dcb->state = DCB_STATE_DISCONNECTED;
|
||||
return 1;
|
||||
}
|
||||
backend_protocol = (MySQLProtocol *) dcb->protocol;
|
||||
client_protocol = SESSION_PROTOCOL(dcb->session, MySQLProtocol);
|
||||
backend_protocol = (MySQLProtocol *) dcb->protocol;
|
||||
|
||||
/** return only with complete session */
|
||||
current_session = gw_get_shared_session_auth_info(dcb);
|
||||
ss_dassert(current_session != NULL);
|
||||
ss_dassert(dcb->session->state != SESSION_STATE_ALLOC);
|
||||
|
||||
|
||||
/* fprintf(stderr, ">>> backend EPOLLIN from %i, command %i,protocol
|
||||
* state [%s]\n", dcb->fd, dcb->command, gw_mysql_protocol_state2string
|
||||
* (backend_protocol->state));
|
||||
@ -202,17 +186,18 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
/* ready to check the authentication reply from backend */
|
||||
|
||||
if (backend_protocol->state == MYSQL_AUTH_RECV) {
|
||||
ROUTER_OBJECT *router = NULL;
|
||||
ROUTER_OBJECT *router = NULL;
|
||||
ROUTER *router_instance = NULL;
|
||||
void *rsession = NULL;
|
||||
int rv = -1;
|
||||
SESSION *session = dcb->session;
|
||||
|
||||
if (session) {
|
||||
router = session->service->router;
|
||||
router_instance = session->service->router_instance;
|
||||
rsession = session->router_session;
|
||||
}
|
||||
CHK_SESSION(session);
|
||||
|
||||
router = session->service->router;
|
||||
router_instance = session->service->router_instance;
|
||||
rsession = session->router_session;
|
||||
|
||||
/* read backed auth reply */
|
||||
rv = gw_receive_backend_auth(backend_protocol);
|
||||
|
||||
@ -222,12 +207,17 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
LOGFILE_ERROR,
|
||||
"%lu [gw_read_backend_event] caught "
|
||||
"MYSQL_FAILED_AUTHENTICATION from "
|
||||
"gw_receive_backend_auth. Fd %d, user %s.",
|
||||
"gw_receive_backend_auth. Fd %d, "
|
||||
"user %s.",
|
||||
pthread_self(),
|
||||
dcb->fd,
|
||||
current_session->user);
|
||||
|
||||
backend_protocol->state = MYSQL_AUTH_FAILED;
|
||||
#if 0
|
||||
ss_dassert(backend_protocol->state !=
|
||||
MYSQL_AUTH_FAILED);
|
||||
#endif
|
||||
/* send an error to the client */
|
||||
mysql_send_custom_error(
|
||||
dcb->session->client,
|
||||
@ -245,17 +235,19 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
if (rsession != NULL) {
|
||||
skygw_log_write_flush(
|
||||
LOGFILE_TRACE,
|
||||
"%lu [gw_read_backend_event] Call "
|
||||
"closeSession for backend session.",
|
||||
"%lu [gw_read_backend_event] "
|
||||
"Call closeSession for backend "
|
||||
"session.",
|
||||
pthread_self());
|
||||
/* close the active session */
|
||||
router->closeSession(router_instance, rsession);
|
||||
router->closeSession(router_instance,
|
||||
rsession);
|
||||
} else {
|
||||
skygw_log_write(
|
||||
LOGFILE_TRACE,
|
||||
"%lu [gw_read_backend_event] "
|
||||
"closeSession already called for "
|
||||
"backend session.",
|
||||
"closeSession already called "
|
||||
"for backend session.",
|
||||
pthread_self());
|
||||
}
|
||||
rc = 1;
|
||||
@ -266,7 +258,8 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
LOGFILE_TRACE,
|
||||
"%lu [gw_read_backend_event] caught "
|
||||
"MYSQL_SUCCESFUL_AUTHENTICATION from "
|
||||
"gw_receive_backend_auth. Fd %d, user %s.",
|
||||
"gw_receive_backend_auth. Fd %d, "
|
||||
"user %s.",
|
||||
pthread_self(),
|
||||
dcb->fd,
|
||||
current_session->user);
|
||||
@ -276,7 +269,6 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
/* check the delay queue and flush the data */
|
||||
if(dcb->delayq) {
|
||||
backend_write_delayqueue(dcb);
|
||||
dcb->state = DCB_STATE_POLLING;
|
||||
spinlock_release(&dcb->authlock);
|
||||
rc = 1;
|
||||
goto return_rc;
|
||||
@ -304,6 +296,7 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
void *rsession = NULL;
|
||||
SESSION *session = dcb->session;
|
||||
|
||||
CHK_SESSION(session);
|
||||
/* read available backend data */
|
||||
rc = dcb_read(dcb, &head);
|
||||
|
||||
@ -312,26 +305,22 @@ static int gw_read_backend_event(DCB *dcb) {
|
||||
goto return_rc;
|
||||
}
|
||||
|
||||
if (session != NULL) {
|
||||
router = session->service->router;
|
||||
router_instance = session->service->router_instance;
|
||||
rsession = session->router_session;
|
||||
}
|
||||
|
||||
router = session->service->router;
|
||||
router_instance = session->service->router_instance;
|
||||
rsession = session->router_session;
|
||||
/* Note the gwbuf doesn't have here a valid queue->command
|
||||
* descriptions as it is a fresh new one!
|
||||
* We only have the copied value in dcb->command from previuos func.write()
|
||||
* and this will be used by the router->clientReply
|
||||
* We only have the copied value in dcb->command from
|
||||
* previuos func.write() and this will be used by the
|
||||
* router->clientReply
|
||||
* and pass now the gwbuf to the router
|
||||
*/
|
||||
|
||||
/* and pass now the gwbuf to the router */
|
||||
router->clientReply(router_instance, rsession, head, dcb);
|
||||
rc = 1;
|
||||
goto return_rc;
|
||||
}
|
||||
rc = 0;
|
||||
return_rc:
|
||||
dcb->state = DCB_STATE_POLLING;
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -347,18 +336,16 @@ static int gw_write_backend_event(DCB *dcb) {
|
||||
//fprintf(stderr, ">>> backend EPOLLOUT %i, protocol state [%s]\n", backend_protocol->fd, gw_mysql_protocol_state2string(backend_protocol->state));
|
||||
|
||||
// spinlock_acquire(&dcb->connectlock);
|
||||
dcb->state = DCB_STATE_PROCESSING;
|
||||
|
||||
/**
|
||||
* vraa: what is the logic in this?
|
||||
*/
|
||||
if (backend_protocol->state == MYSQL_PENDING_CONNECT) {
|
||||
backend_protocol->state = MYSQL_CONNECTED;
|
||||
|
||||
backend_protocol->state = MYSQL_CONNECTED;
|
||||
// spinlock_release(&dcb->connectlock);
|
||||
dcb->state = DCB_STATE_POLLING;
|
||||
return 1;
|
||||
}
|
||||
// spinlock_release(&dcb->connectlock);
|
||||
dcb_drain_writeq(dcb);
|
||||
dcb->state = DCB_STATE_POLLING;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -456,7 +443,8 @@ static int gw_create_backend_connection(
|
||||
skygw_log_write(
|
||||
LOGFILE_TRACE,
|
||||
"%lu [gw_create_backend_connection] Established "
|
||||
"connection to %s:%i, backend fd %d client fd %d.",
|
||||
"connection to %s:%i, backend fd %d client "
|
||||
"fd %d.",
|
||||
pthread_self(),
|
||||
server->name,
|
||||
server->port,
|
||||
@ -492,8 +480,6 @@ static int gw_create_backend_connection(
|
||||
session->client->fd);
|
||||
break;
|
||||
} /**< switch */
|
||||
|
||||
backend_dcb->state = DCB_STATE_POLLING;
|
||||
return_fd:
|
||||
ss_dassert(backend_dcb->fd == fd);
|
||||
ss_dassert(backend_dcb->fd == protocol->fd);
|
||||
@ -547,7 +533,6 @@ static void backend_set_delayqueue(DCB *dcb, GWBUF *queue) {
|
||||
dcb->delayq = queue;
|
||||
}
|
||||
}
|
||||
|
||||
spinlock_release(&dcb->delayqlock);
|
||||
}
|
||||
|
||||
@ -681,4 +666,3 @@ static int gw_session(DCB *backend_dcb, void *data) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
/////
|
||||
|
Reference in New Issue
Block a user