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:
@ -90,12 +90,28 @@ poll_init()
|
||||
int
|
||||
poll_add_dcb(DCB *dcb)
|
||||
{
|
||||
int rc;
|
||||
dcb_state_t old_state = DCB_STATE_UNDEFINED;
|
||||
struct epoll_event ev;
|
||||
|
||||
ev.events = EPOLLIN | EPOLLOUT | EPOLLET;
|
||||
ev.data.ptr = dcb;
|
||||
|
||||
return epoll_ctl(epoll_fd, EPOLL_CTL_ADD, dcb->fd, &ev);
|
||||
/**
|
||||
* Service listeners have different state than
|
||||
* DCBs serving client requests.
|
||||
*/
|
||||
if (dcb->dcb_role == DCB_ROLE_SERVICE_LISTENER) {
|
||||
dcb_set_state(dcb, DCB_STATE_LISTENING, &old_state);
|
||||
} else if (dcb->dcb_role == DCB_ROLE_REQUEST_HANDLER) {
|
||||
dcb_set_state(dcb, DCB_STATE_POLLING, &old_state);
|
||||
}
|
||||
|
||||
rc = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, dcb->fd, &ev);
|
||||
if (rc != 0) {
|
||||
dcb_set_state(dcb, old_state, NULL);
|
||||
}
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
@ -203,15 +219,19 @@ poll_waitevents(void *arg)
|
||||
__uint32_t ev = events[i].events;
|
||||
|
||||
CHK_DCB(dcb);
|
||||
ss_dassert(dcb->state != DCB_STATE_IDLE &&
|
||||
dcb->state != DCB_STATE_ALLOC);
|
||||
|
||||
|
||||
ss_debug(spinlock_acquire(&dcb->dcb_initlock);)
|
||||
ss_dassert(dcb->state != DCB_STATE_ALLOC);
|
||||
ss_dassert(dcb->state != DCB_STATE_DISCONNECTED);
|
||||
ss_dassert(dcb->state != DCB_STATE_FREED);
|
||||
ss_debug(spinlock_release(&dcb->dcb_initlock);)
|
||||
|
||||
skygw_log_write(
|
||||
LOGFILE_TRACE,
|
||||
"%lu [poll_waitevents] event %d",
|
||||
pthread_self(),
|
||||
ev);
|
||||
|
||||
#if 0
|
||||
if (DCB_ISZOMBIE(dcb))
|
||||
{
|
||||
skygw_log_write(
|
||||
@ -233,7 +253,7 @@ poll_waitevents(void *arg)
|
||||
STRDCBSTATE(dcb->state));
|
||||
continue;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (ev & EPOLLERR)
|
||||
{
|
||||
@ -255,23 +275,21 @@ poll_waitevents(void *arg)
|
||||
}
|
||||
if (ev & EPOLLOUT)
|
||||
{
|
||||
simple_mutex_lock(&dcb->dcb_write_lock, true);
|
||||
simple_mutex_lock(&dcb->dcb_write_lock,
|
||||
true);
|
||||
ss_info_dassert(!dcb->dcb_write_active,
|
||||
"Write already active");
|
||||
dcb->dcb_write_active = TRUE;
|
||||
|
||||
skygw_log_write(LOGFILE_TRACE,
|
||||
"%lu [poll_waitevents] "
|
||||
"Write in fd %d",
|
||||
pthread_self(),
|
||||
dcb->fd);
|
||||
skygw_log_write(
|
||||
LOGFILE_TRACE,
|
||||
"%lu [poll_waitevents] "
|
||||
"Write in fd %d",
|
||||
pthread_self(),
|
||||
dcb->fd);
|
||||
atomic_add(&pollStats.n_write, 1);
|
||||
|
||||
dcb->func.write_ready(dcb);
|
||||
|
||||
dcb->dcb_write_active = FALSE;
|
||||
simple_mutex_unlock(
|
||||
&dcb->dcb_write_lock);
|
||||
simple_mutex_unlock(&dcb->dcb_write_lock);
|
||||
}
|
||||
if (ev & EPOLLIN)
|
||||
{
|
||||
|
Reference in New Issue
Block a user