int Select::poll_descriptors()

in common/select.cpp [91:164]


int Select::poll_descriptors(Selectable **c, unsigned int timeout, bool interrupt_on_signal = false)
{
    int sz_selectables = static_cast<int>(m_objects.size());
    std::vector<struct epoll_event> events(sz_selectables);
    int ret;

    while(true)
    {
        ret = ::epoll_wait(m_epoll_fd, events.data(), sz_selectables, timeout);
        // on signal interrupt check if we need to return
        if (ret == -1 && errno == EINTR)
        {
            if (interrupt_on_signal)
            {
                return Select::SIGNALINT;
            }
        }
        // on all other errors break the loop
        else
        {
            break;
        }
    }

    if (ret < 0)
    {
        return Select::ERROR;
    }

    for (int i = 0; i < ret; ++i)
    {
        int fd = events[i].data.fd;
        Selectable* sel = m_objects[fd];
        try
        {
            sel->readData();
        }
        catch (const std::runtime_error& ex)
        {
            SWSS_LOG_ERROR("readData error: %s", ex.what());
            return Select::ERROR;
        }
        m_ready.insert(sel);
    }

    while (!m_ready.empty())
    {
        auto sel = *m_ready.begin();

        m_ready.erase(sel);
        // we must update clock only when the selector out of the m_ready
        // otherwise we break invariant of the m_ready
        sel->updateLastUsedTime();

        if (!sel->hasData())
        {
            continue;
        }

        *c = sel;

        if (sel->hasCachedData())
        {
            // reinsert Selectable back to the m_ready set, when there're more messages in the cache
            m_ready.insert(sel);
        }

        sel->updateAfterRead();

        return Select::OBJECT;
    }

    return Select::TIMEOUT;
}