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