From 5984af468c7c9aa01830bd82527cbbde28c90a44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 17 Mar 2020 14:45:06 +0200 Subject: [PATCH] Process EPOLL[RD]HUP after EPOLLIN This allows COM_QUIT packets to be processed first in case a EPOLLIN and a EPOLLRDHUP event arrive at the same time. This fixes the pers_01 test. --- server/core/dcb.cc | 74 +++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/server/core/dcb.cc b/server/core/dcb.cc index 00116a513..c3bf5b483 100644 --- a/server/core/dcb.cc +++ b/server/core/dcb.cc @@ -2653,6 +2653,12 @@ static uint32_t dcb_process_poll_events(DCB* dcb, uint32_t events) /** * Any of these callbacks might close the DCB. Hence, the value of 'n_close' * must be checked after each callback invocation. + * + * The order in which the events are processed is meaningful and should not be changed. EPOLLERR is + * handled first to get the best possible error message in the log message in case EPOLLERR is returned + * with another event from epoll_wait. EPOLLOUT and EPOLLIN are processed before EPOLLHUP and EPOLLRDHUP + * so that all client events are processed in case EPOLLIN and EPOLLRDHUP events arrive in the same + * epoll_wait. */ if ((events & EPOLLERR) && (dcb->n_close == 0)) { @@ -2665,6 +2671,40 @@ static uint32_t dcb_process_poll_events(DCB* dcb, uint32_t events) } } + if ((events & EPOLLOUT) && (dcb->n_close == 0)) + { + rc |= MXB_POLL_WRITE; + + if (dcb_session_check(dcb, "write_ready")) + { + DCB_EH_NOTICE("Calling dcb->func.write_ready(%p)", dcb); + dcb->func.write_ready(dcb); + } + } + + if ((events & EPOLLIN) && (dcb->n_close == 0)) + { + rc |= MXB_POLL_READ; + + if (dcb_session_check(dcb, "read")) + { + int return_code = 1; + /** SSL authentication is still going on, we need to call dcb_accept_SSL + * until it return 1 for success or -1 for error */ + if (dcb->ssl_state == SSL_HANDSHAKE_REQUIRED) + { + return_code = (DCB::Role::CLIENT == dcb->role) ? + dcb_accept_SSL(dcb) : + dcb_connect_SSL(dcb); + } + if (1 == return_code) + { + DCB_EH_NOTICE("Calling dcb->func.read(%p)", dcb); + dcb->func.read(dcb); + } + } + } + if ((events & EPOLLHUP) && (dcb->n_close == 0)) { rc |= MXB_POLL_HUP; @@ -2699,40 +2739,6 @@ static uint32_t dcb_process_poll_events(DCB* dcb, uint32_t events) } #endif - if ((events & EPOLLOUT) && (dcb->n_close == 0)) - { - rc |= MXB_POLL_WRITE; - - if (dcb_session_check(dcb, "write_ready")) - { - DCB_EH_NOTICE("Calling dcb->func.write_ready(%p)", dcb); - dcb->func.write_ready(dcb); - } - } - - if ((events & EPOLLIN) && (dcb->n_close == 0)) - { - rc |= MXB_POLL_READ; - - if (dcb_session_check(dcb, "read")) - { - int return_code = 1; - /** SSL authentication is still going on, we need to call dcb_accept_SSL - * until it return 1 for success or -1 for error */ - if (dcb->ssl_state == SSL_HANDSHAKE_REQUIRED) - { - return_code = (DCB::Role::CLIENT == dcb->role) ? - dcb_accept_SSL(dcb) : - dcb_connect_SSL(dcb); - } - if (1 == return_code) - { - DCB_EH_NOTICE("Calling dcb->func.read(%p)", dcb); - dcb->func.read(dcb); - } - } - } - return rc; }