Merge branch '2.3' into develop

This commit is contained in:
Markus Mäkelä
2019-01-17 10:55:27 +02:00
2 changed files with 31 additions and 35 deletions

View File

@ -3086,8 +3086,8 @@ int poll_add_dcb(DCB* dcb)
} }
else else
{ {
// Round-robin the client connection worker assignment // Assign to current worker
owner = RoutingWorker::pick_worker(); owner = RoutingWorker::get_current();
} }
new_state = DCB_STATE_POLLING; new_state = DCB_STATE_POLLING;

View File

@ -1398,6 +1398,17 @@ int gw_MySQLAccept(DCB* client_dcb)
static void gw_process_one_new_client(DCB* client_dcb) static void gw_process_one_new_client(DCB* client_dcb)
{ {
/**
* The worker who owns the DCB is chosen here, before any epoll events for it can be processed.
* This guarantees that the first event for the DCB is processed only after the following
* task has been processed by the owning thread.
*/
mxs::RoutingWorker* worker = mxs::RoutingWorker::pick_worker();
worker->execute([=]() {
client_dcb->protocol = mysql_protocol_init(client_dcb, client_dcb->fd);
MXS_ABORT_IF_NULL(client_dcb->protocol);
/** /**
* Set new descriptor to event set. At the same time, * Set new descriptor to event set. At the same time,
* change state to DCB_STATE_POLLING so that * change state to DCB_STATE_POLLING so that
@ -1406,9 +1417,7 @@ static void gw_process_one_new_client(DCB* client_dcb)
if (poll_add_dcb(client_dcb) == -1) if (poll_add_dcb(client_dcb) == -1)
{ {
/* Send a custom error as MySQL command reply */ /* Send a custom error as MySQL command reply */
mysql_send_custom_error(client_dcb, mysql_send_custom_error(client_dcb, 1, 0,
1,
0,
"MaxScale encountered system limit while " "MaxScale encountered system limit while "
"attempting to register on an epoll instance."); "attempting to register on an epoll instance.");
@ -1417,26 +1426,13 @@ static void gw_process_one_new_client(DCB* client_dcb)
/** Previous state is recovered in poll_add_dcb. */ /** Previous state is recovered in poll_add_dcb. */
MXS_ERROR("Failed to add dcb %p for fd %d to epoll set.", MXS_ERROR("Failed to add dcb %p for fd %d to epoll set.",
client_dcb, client_dcb, client_dcb->fd);
client_dcb->fd);
return;
} }
else else
{ {
// Move the rest of the initialization process to the owning worker
mxs::RoutingWorker* worker = static_cast<mxs::RoutingWorker*>(client_dcb->owner);
worker->execute([=]() {
client_dcb->protocol = mysql_protocol_init(client_dcb, client_dcb->fd);
MXS_ABORT_IF_NULL(client_dcb->protocol);
MySQLSendHandshake(client_dcb); MySQLSendHandshake(client_dcb);
}, mxs::RoutingWorker::EXECUTE_AUTO);
MXS_DEBUG("Added dcb %p for fd %d to epoll set.",
client_dcb,
client_dcb->fd);
} }
return; }, mxs::RoutingWorker::EXECUTE_AUTO);
} }
static int gw_error_client_event(DCB* dcb) static int gw_error_client_event(DCB* dcb)