Avoid unnecessary wake-ups in SocketEvents::ChangeEvents (part 2)

refs #11014
This commit is contained in:
Gunnar Beutner 2016-01-28 11:55:31 +01:00
parent 75f7fe10e1
commit 4237c6eaaa

View File

@ -41,6 +41,13 @@ struct SocketEventDescriptor
{ } { }
}; };
struct EventDescription
{
int REvents;
SocketEventDescriptor Descriptor;
Object::Ptr LifesupportReference;
};
static boost::thread l_SocketIOThread; static boost::thread l_SocketIOThread;
static boost::once_flag l_SocketIOOnceFlag = BOOST_ONCE_INIT; static boost::once_flag l_SocketIOOnceFlag = BOOST_ONCE_INIT;
static SOCKET l_SocketIOEventFDs[2]; static SOCKET l_SocketIOEventFDs[2];
@ -107,6 +114,8 @@ void SocketEvents::ThreadProc(void)
(void) poll(pfds, pfdcount, -1); (void) poll(pfds, pfdcount, -1);
#endif /* _WIN32 */ #endif /* _WIN32 */
std::vector<EventDescription> events;
{ {
boost::mutex::scoped_lock lock(l_SocketIOMutex); boost::mutex::scoped_lock lock(l_SocketIOMutex);
@ -115,40 +124,38 @@ void SocketEvents::ThreadProc(void)
pfds = NULL; pfds = NULL;
continue; continue;
} }
}
for (int i = 0; i < pfdcount; i++) { for (int i = 0; i < pfdcount; i++) {
if ((pfds[i].revents & (POLLIN | POLLOUT | POLLHUP | POLLERR)) == 0) if ((pfds[i].revents & (POLLIN | POLLOUT | POLLHUP | POLLERR)) == 0)
continue; continue;
if (pfds[i].fd == l_SocketIOEventFDs[0]) { if (pfds[i].fd == l_SocketIOEventFDs[0]) {
char buffer[512]; char buffer[512];
if (recv(l_SocketIOEventFDs[0], buffer, sizeof(buffer), 0) < 0) if (recv(l_SocketIOEventFDs[0], buffer, sizeof(buffer), 0) < 0)
Log(LogCritical, "SocketEvents", "Read from event FD failed."); Log(LogCritical, "SocketEvents", "Read from event FD failed.");
continue; continue;
} }
SocketEventDescriptor desc; EventDescription event;
Object::Ptr ltref; event.REvents = pfds[i].revents;
{
boost::mutex::scoped_lock lock(l_SocketIOMutex);
std::map<SOCKET, SocketEventDescriptor>::const_iterator it = l_SocketIOSockets.find(pfds[i].fd); std::map<SOCKET, SocketEventDescriptor>::const_iterator it = l_SocketIOSockets.find(pfds[i].fd);
if (it == l_SocketIOSockets.end()) if (it == l_SocketIOSockets.end())
continue; continue;
desc = it->second; event.Descriptor = it->second;
event.LifesupportReference = event.Descriptor.LifesupportObject;
VERIFY(event.LifesupportReference);
/* We must hold a ref-counted reference to the event object to keep it alive. */ events.push_back(event);
ltref = desc.LifesupportObject;
VERIFY(ltref);
} }
}
BOOST_FOREACH(const EventDescription& event, events) {
try { try {
desc.EventInterface->OnEvent(pfds[i].revents); event.Descriptor.EventInterface->OnEvent(event.REvents);
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
Log(LogCritical, "SocketEvents") Log(LogCritical, "SocketEvents")
<< "Exception thrown in socket I/O handler:\n" << "Exception thrown in socket I/O handler:\n"
@ -204,8 +211,11 @@ void SocketEvents::Register(Object *lifesupportObject)
VERIFY(m_FD != INVALID_SOCKET); VERIFY(m_FD != INVALID_SOCKET);
Log(LogWarning, "SocketEvents")
<< "Registered socket " << m_FD;
SocketEventDescriptor desc; SocketEventDescriptor desc;
desc.Events = POLLIN; desc.Events = 0;
desc.EventInterface = this; desc.EventInterface = this;
desc.LifesupportObject = lifesupportObject; desc.LifesupportObject = lifesupportObject;
@ -228,6 +238,9 @@ void SocketEvents::Unregister(void)
if (m_FD == INVALID_SOCKET) if (m_FD == INVALID_SOCKET)
return; return;
Log(LogWarning, "SocketEvents")
<< "Unregistered socket " << m_FD;
l_SocketIOSockets.erase(m_FD); l_SocketIOSockets.erase(m_FD);
l_SocketIOFDChanged = true; l_SocketIOFDChanged = true;