void _eventloop()

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);
                }
            }
        }