in src/Trinity.C/src/Events/Events.cpp [180:311]
void _eventloop()
{
uint32_t szwork;
work_t* pwork;
work_t* pcont;
Network::sock_t* psock;
TrinityErrorCode eresult;
while (true)
{
// 1. work polling
while (TrinityErrorCode::E_SUCCESS != platform_poll(pwork, szwork)) { /* loop */ }
work_t* pwait = pwork->pwait_chain;
// 2. work processing
switch (pwork->type)
{
case worktype_t::Shutdown:
assert(pwait == nullptr);
free_work(pwork);
return;
case worktype_t::Receive:
psock = pwork->psock;
eresult = Network::process_recv(psock, szwork);
if (_work_check_error(eresult, pwork))
{
continue;
}
if (!psock->is_incoming)
{
assert(pwait != nullptr);
break;
}
/* is_incoming is true */
// the definitive behavior after incoming recv is handshake/messageproc,
// so it cannot have a wait chain.
assert(pwait == nullptr);
if (psock->wait_handshake)
{
eresult = Network::check_handshake(psock);
}
else
{
// switch to send mode
pwork->type = worktype_t::Send;
message_t* msg = (message_t*)psock;
__try_post_continuation(
s_message_handlers[*(uint16_t *)msg->buf](msg),
/* continue with sending the response */
pwork,
{ eresult = _post_work(pwork); }
);
}
if (_work_check_error(eresult, pwork))
{
continue;
}
// breaks to continuation handling
break;
case worktype_t::Send:
psock = pwork->psock;
eresult = Network::process_send(psock, szwork);
if (_work_check_error(eresult, pwork))
{
continue;
}
if (psock->is_incoming)
{
assert(pwait == nullptr);
pwork->type = worktype_t::Receive;
eresult = _post_work(pwork);
}
else /* is_outgoing */
{
// outgoing send finished.
// just wait for pwait_chain to run.
assert(pwait != nullptr);
}
if (_work_check_error(eresult, pwork))
{
continue;
}
// breaks to continuation handling
break;
case worktype_t::Compute:
__try_post_continuation(
pwork->pcompute(pwork->pcompute_data),
pwork->pwait_chain,
{
// no new continuation posted.
// computation terminated.
eresult = TrinityErrorCode::E_SUCCESS;
}
);
break;
case worktype_t::Continuation:
__try_post_continuation(
pwork->pcontinuation(pwork->pcontinuation_data, pwork->pdependency),
pwork->pwait_chain,
{
// no new continuation posted.
// computation terminated.
eresult = TrinityErrorCode::E_SUCCESS;
}
);
break;
default:
Diagnostics::WriteLine(Diagnostics::Error, "EventLoop: Async work type {0} is not recognized.", pwork->type);
continue;
}
// 3. wait chain processing
if (pwait != nullptr)
{
eresult = _post_work(pwait);
_work_check_error(eresult, pwait);
}
}
}