EventManager: store event handlers in an unordered_map instead of a vector

If an event handler add or removes an event from the manager, it may then
be moved in the vector, and if after that it access any of it's members
(through this), it results in an invalid memory access.
This commit is contained in:
Maxime Coste 2012-11-06 13:34:58 +01:00
parent 3daac4883e
commit d347223e42
2 changed files with 5 additions and 4 deletions

View File

@ -15,7 +15,7 @@ void EventManager::watch(int fd, EventHandler handler)
throw runtime_error("fd already watched"); throw runtime_error("fd already watched");
m_events.push_back(pollfd{ fd, POLLIN | POLLPRI, 0 }); m_events.push_back(pollfd{ fd, POLLIN | POLLPRI, 0 });
m_handlers.push_back(std::move(handler)); m_handlers.emplace(fd, std::move(handler));
} }
void EventManager::unwatch(int fd) void EventManager::unwatch(int fd)
@ -25,7 +25,7 @@ void EventManager::unwatch(int fd)
if (m_events[i].fd == fd) if (m_events[i].fd == fd)
{ {
m_events.erase(m_events.begin() + i); m_events.erase(m_events.begin() + i);
m_handlers.erase(m_handlers.begin() + i); m_handlers.erase(fd);
return; return;
} }
} }
@ -39,7 +39,7 @@ void EventManager::handle_next_events()
{ {
if ((res > 0 and m_events[i].revents) or if ((res > 0 and m_events[i].revents) or
contains(m_forced, m_events[i].fd)) contains(m_forced, m_events[i].fd))
m_handlers[i](m_events[i].fd); m_handlers[m_events[i].fd](m_events[i].fd);
} }
m_forced.clear(); m_forced.clear();
} }

View File

@ -2,6 +2,7 @@
#define event_manager_hh_INCLUDED #define event_manager_hh_INCLUDED
#include <poll.h> #include <poll.h>
#include <unordered_map>
#include "utils.hh" #include "utils.hh"
@ -24,7 +25,7 @@ public:
private: private:
std::vector<pollfd> m_events; std::vector<pollfd> m_events;
std::vector<EventHandler> m_handlers; std::unordered_map<int, EventHandler> m_handlers;
std::vector<int> m_forced; std::vector<int> m_forced;
}; };