Move poll_[add|remove]_dcb to dcb.c
This commit is contained in:
@ -3512,3 +3512,145 @@ dcb_session_check(DCB *dcb, const char *function)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int poll_add_dcb(DCB *dcb)
|
||||||
|
{
|
||||||
|
int rc = -1;
|
||||||
|
dcb_state_t old_state = dcb->state;
|
||||||
|
dcb_state_t new_state;
|
||||||
|
uint32_t events = 0;
|
||||||
|
|
||||||
|
CHK_DCB(dcb);
|
||||||
|
|
||||||
|
#ifdef EPOLLRDHUP
|
||||||
|
events = EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLHUP | EPOLLET;
|
||||||
|
#else
|
||||||
|
events = EPOLLIN | EPOLLOUT | EPOLLHUP | EPOLLET;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*<
|
||||||
|
* Choose new state according to the role of dcb.
|
||||||
|
*/
|
||||||
|
if (dcb->dcb_role == DCB_ROLE_CLIENT_HANDLER || dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER)
|
||||||
|
{
|
||||||
|
new_state = DCB_STATE_POLLING;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ss_dassert(dcb->dcb_role == DCB_ROLE_SERVICE_LISTENER);
|
||||||
|
new_state = DCB_STATE_LISTENING;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Check DCB current state seems sensible
|
||||||
|
*/
|
||||||
|
if (DCB_STATE_DISCONNECTED == dcb->state
|
||||||
|
|| DCB_STATE_ZOMBIE == dcb->state
|
||||||
|
|| DCB_STATE_UNDEFINED == dcb->state)
|
||||||
|
{
|
||||||
|
MXS_ERROR("%lu [poll_add_dcb] Error : existing state of dcb %p "
|
||||||
|
"is %s, but this should be impossible, crashing.",
|
||||||
|
pthread_self(),
|
||||||
|
dcb,
|
||||||
|
STRDCBSTATE(dcb->state));
|
||||||
|
raise(SIGABRT);
|
||||||
|
}
|
||||||
|
if (DCB_STATE_POLLING == dcb->state
|
||||||
|
|| DCB_STATE_LISTENING == dcb->state)
|
||||||
|
{
|
||||||
|
MXS_ERROR("%lu [poll_add_dcb] Error : existing state of dcb %p "
|
||||||
|
"is %s, but this is probably an error, not crashing.",
|
||||||
|
pthread_self(),
|
||||||
|
dcb,
|
||||||
|
STRDCBSTATE(dcb->state));
|
||||||
|
}
|
||||||
|
dcb->state = new_state;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The only possible failure that will not cause a crash is
|
||||||
|
* running out of system resources.
|
||||||
|
*/
|
||||||
|
int worker_id = 0;
|
||||||
|
|
||||||
|
if (dcb->dcb_role == DCB_ROLE_SERVICE_LISTENER)
|
||||||
|
{
|
||||||
|
worker_id = MXS_WORKER_ALL;
|
||||||
|
}
|
||||||
|
else if (dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER)
|
||||||
|
{
|
||||||
|
worker_id = dcb->session->client_dcb->poll.thread.id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
worker_id = MXS_WORKER_ANY;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = poll_add_fd_to_worker(worker_id, dcb->fd, events, (MXS_POLL_DATA*)dcb);
|
||||||
|
|
||||||
|
if (0 == rc)
|
||||||
|
{
|
||||||
|
dcb_add_to_list(dcb);
|
||||||
|
|
||||||
|
MXS_DEBUG("%lu [poll_add_dcb] Added dcb %p in state %s to poll set.",
|
||||||
|
pthread_self(),
|
||||||
|
dcb,
|
||||||
|
STRDCBSTATE(dcb->state));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dcb->state = old_state;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int poll_remove_dcb(DCB *dcb)
|
||||||
|
{
|
||||||
|
int dcbfd, rc = 0;
|
||||||
|
struct epoll_event ev;
|
||||||
|
CHK_DCB(dcb);
|
||||||
|
|
||||||
|
/*< It is possible that dcb has already been removed from the set */
|
||||||
|
if (dcb->state == DCB_STATE_NOPOLLING ||
|
||||||
|
dcb->state == DCB_STATE_ZOMBIE)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (DCB_STATE_POLLING != dcb->state
|
||||||
|
&& DCB_STATE_LISTENING != dcb->state)
|
||||||
|
{
|
||||||
|
MXS_ERROR("%lu [poll_remove_dcb] Error : existing state of dcb %p "
|
||||||
|
"is %s, but this is probably an error, not crashing.",
|
||||||
|
pthread_self(),
|
||||||
|
dcb,
|
||||||
|
STRDCBSTATE(dcb->state));
|
||||||
|
}
|
||||||
|
/*<
|
||||||
|
* Set state to NOPOLLING and remove dcb from poll set.
|
||||||
|
*/
|
||||||
|
dcb->state = DCB_STATE_NOPOLLING;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only positive fds can be removed from epoll set.
|
||||||
|
* Cloned DCBs can have a state of DCB_STATE_POLLING but are not in
|
||||||
|
* the epoll set and do not have a valid file descriptor. Hence the
|
||||||
|
* only action for them is already done - the change of state to
|
||||||
|
* DCB_STATE_NOPOLLING.
|
||||||
|
*/
|
||||||
|
dcbfd = dcb->fd;
|
||||||
|
|
||||||
|
if (dcbfd > 0)
|
||||||
|
{
|
||||||
|
int worker_id;
|
||||||
|
|
||||||
|
if (dcb->dcb_role == DCB_ROLE_SERVICE_LISTENER)
|
||||||
|
{
|
||||||
|
worker_id = MXS_WORKER_ALL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
worker_id = dcb->poll.thread.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = poll_remove_fd_from_worker(worker_id, dcbfd);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|||||||
@ -420,148 +420,6 @@ int poll_remove_fd_from_worker(int wid, int fd)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int poll_add_dcb(DCB *dcb)
|
|
||||||
{
|
|
||||||
int rc = -1;
|
|
||||||
dcb_state_t old_state = dcb->state;
|
|
||||||
dcb_state_t new_state;
|
|
||||||
uint32_t events = 0;
|
|
||||||
|
|
||||||
CHK_DCB(dcb);
|
|
||||||
|
|
||||||
#ifdef EPOLLRDHUP
|
|
||||||
events = EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLHUP | EPOLLET;
|
|
||||||
#else
|
|
||||||
events = EPOLLIN | EPOLLOUT | EPOLLHUP | EPOLLET;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*<
|
|
||||||
* Choose new state according to the role of dcb.
|
|
||||||
*/
|
|
||||||
if (dcb->dcb_role == DCB_ROLE_CLIENT_HANDLER || dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER)
|
|
||||||
{
|
|
||||||
new_state = DCB_STATE_POLLING;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ss_dassert(dcb->dcb_role == DCB_ROLE_SERVICE_LISTENER);
|
|
||||||
new_state = DCB_STATE_LISTENING;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Check DCB current state seems sensible
|
|
||||||
*/
|
|
||||||
if (DCB_STATE_DISCONNECTED == dcb->state
|
|
||||||
|| DCB_STATE_ZOMBIE == dcb->state
|
|
||||||
|| DCB_STATE_UNDEFINED == dcb->state)
|
|
||||||
{
|
|
||||||
MXS_ERROR("%lu [poll_add_dcb] Error : existing state of dcb %p "
|
|
||||||
"is %s, but this should be impossible, crashing.",
|
|
||||||
pthread_self(),
|
|
||||||
dcb,
|
|
||||||
STRDCBSTATE(dcb->state));
|
|
||||||
raise(SIGABRT);
|
|
||||||
}
|
|
||||||
if (DCB_STATE_POLLING == dcb->state
|
|
||||||
|| DCB_STATE_LISTENING == dcb->state)
|
|
||||||
{
|
|
||||||
MXS_ERROR("%lu [poll_add_dcb] Error : existing state of dcb %p "
|
|
||||||
"is %s, but this is probably an error, not crashing.",
|
|
||||||
pthread_self(),
|
|
||||||
dcb,
|
|
||||||
STRDCBSTATE(dcb->state));
|
|
||||||
}
|
|
||||||
dcb->state = new_state;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The only possible failure that will not cause a crash is
|
|
||||||
* running out of system resources.
|
|
||||||
*/
|
|
||||||
int worker_id = 0;
|
|
||||||
|
|
||||||
if (dcb->dcb_role == DCB_ROLE_SERVICE_LISTENER)
|
|
||||||
{
|
|
||||||
worker_id = MXS_WORKER_ALL;
|
|
||||||
}
|
|
||||||
else if (dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER)
|
|
||||||
{
|
|
||||||
worker_id = dcb->session->client_dcb->poll.thread.id;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
worker_id = (unsigned int)atomic_add(&next_epoll_fd, 1) % n_threads;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = poll_add_fd_to_worker(worker_id, dcb->fd, events, (MXS_POLL_DATA*)dcb);
|
|
||||||
|
|
||||||
if (0 == rc)
|
|
||||||
{
|
|
||||||
dcb_add_to_list(dcb);
|
|
||||||
|
|
||||||
MXS_DEBUG("%lu [poll_add_dcb] Added dcb %p in state %s to poll set.",
|
|
||||||
pthread_self(),
|
|
||||||
dcb,
|
|
||||||
STRDCBSTATE(dcb->state));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dcb->state = old_state;
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
int poll_remove_dcb(DCB *dcb)
|
|
||||||
{
|
|
||||||
int dcbfd, rc = 0;
|
|
||||||
struct epoll_event ev;
|
|
||||||
CHK_DCB(dcb);
|
|
||||||
|
|
||||||
/*< It is possible that dcb has already been removed from the set */
|
|
||||||
if (dcb->state == DCB_STATE_NOPOLLING ||
|
|
||||||
dcb->state == DCB_STATE_ZOMBIE)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (DCB_STATE_POLLING != dcb->state
|
|
||||||
&& DCB_STATE_LISTENING != dcb->state)
|
|
||||||
{
|
|
||||||
MXS_ERROR("%lu [poll_remove_dcb] Error : existing state of dcb %p "
|
|
||||||
"is %s, but this is probably an error, not crashing.",
|
|
||||||
pthread_self(),
|
|
||||||
dcb,
|
|
||||||
STRDCBSTATE(dcb->state));
|
|
||||||
}
|
|
||||||
/*<
|
|
||||||
* Set state to NOPOLLING and remove dcb from poll set.
|
|
||||||
*/
|
|
||||||
dcb->state = DCB_STATE_NOPOLLING;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Only positive fds can be removed from epoll set.
|
|
||||||
* Cloned DCBs can have a state of DCB_STATE_POLLING but are not in
|
|
||||||
* the epoll set and do not have a valid file descriptor. Hence the
|
|
||||||
* only action for them is already done - the change of state to
|
|
||||||
* DCB_STATE_NOPOLLING.
|
|
||||||
*/
|
|
||||||
dcbfd = dcb->fd;
|
|
||||||
|
|
||||||
if (dcbfd > 0)
|
|
||||||
{
|
|
||||||
int worker_id;
|
|
||||||
|
|
||||||
if (dcb->dcb_role == DCB_ROLE_SERVICE_LISTENER)
|
|
||||||
{
|
|
||||||
worker_id = MXS_WORKER_ALL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
worker_id = dcb->poll.thread.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = poll_remove_fd_from_worker(worker_id, dcbfd);
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check error returns from epoll_ctl. Most result in a crash since they
|
* Check error returns from epoll_ctl. Most result in a crash since they
|
||||||
* are "impossible". Adding when already present is assumed non-fatal.
|
* are "impossible". Adding when already present is assumed non-fatal.
|
||||||
|
|||||||
Reference in New Issue
Block a user