summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/socketengines/socketengine_epoll.cpp4
-rw-r--r--src/socketengines/socketengine_kqueue.cpp12
-rw-r--r--src/socketengines/socketengine_poll.cpp24
-rw-r--r--src/socketengines/socketengine_ports.cpp12
4 files changed, 33 insertions, 19 deletions
diff --git a/src/socketengines/socketengine_epoll.cpp b/src/socketengines/socketengine_epoll.cpp
index af58cb026..b9563ed2b 100644
--- a/src/socketengines/socketengine_epoll.cpp
+++ b/src/socketengines/socketengine_epoll.cpp
@@ -54,6 +54,7 @@ public:
EPollEngine::EPollEngine() : events(1)
{
+ CurrentSetSize = 0;
int max = ulimit(4, 0);
if (max > 0)
{
@@ -193,7 +194,8 @@ int EPollEngine::DispatchEvents()
for (int j = 0; j < i; j++)
{
- struct epoll_event& ev = events[j];
+ // Copy these in case the vector gets resized and ev invalidated
+ const epoll_event ev = events[j];
EventHandler* eh = GetRef(ev.data.fd);
if (!eh)
diff --git a/src/socketengines/socketengine_kqueue.cpp b/src/socketengines/socketengine_kqueue.cpp
index 81addd1c2..99d4236e9 100644
--- a/src/socketengines/socketengine_kqueue.cpp
+++ b/src/socketengines/socketengine_kqueue.cpp
@@ -219,7 +219,11 @@ int KQueueEngine::DispatchEvents()
{
struct kevent& kev = ke_list[j];
- EventHandler* eh = GetRef(kev.ident);
+ // Copy these in case the vector gets resized and kev invalidated
+ const int fd = kev.ident;
+ const short filter = kev.filter;
+
+ EventHandler* eh = GetRef(fd);
if (!eh)
continue;
@@ -229,7 +233,7 @@ int KQueueEngine::DispatchEvents()
eh->HandleEvent(EVENT_ERROR, kev.fflags);
continue;
}
- if (kev.filter == EVFILT_WRITE)
+ if (filter == EVFILT_WRITE)
{
WriteEvents++;
/* When mask is FD_WANT_FAST_WRITE or FD_WANT_SINGLE_WRITE,
@@ -240,11 +244,11 @@ int KQueueEngine::DispatchEvents()
SetEventMask(eh, eh->GetEventMask() & ~bits_to_clr);
eh->HandleEvent(EVENT_WRITE);
- if (eh != GetRef(kev.ident))
+ if (eh != GetRef(fd))
// whoops, deleted out from under us
continue;
}
- if (kev.filter == EVFILT_READ)
+ if (filter == EVFILT_READ)
{
ReadEvents++;
SetEventMask(eh, eh->GetEventMask() & ~FD_READ_WILL_BLOCK);
diff --git a/src/socketengines/socketengine_poll.cpp b/src/socketengines/socketengine_poll.cpp
index 722555510..2919988c0 100644
--- a/src/socketengines/socketengine_poll.cpp
+++ b/src/socketengines/socketengine_poll.cpp
@@ -196,43 +196,49 @@ int PollEngine::DispatchEvents()
{
struct pollfd& pfd = events[index];
- if (pfd.revents)
+ // Copy these in case the vector gets resized and pfd invalidated
+ const int fd = pfd.fd;
+ const short revents = pfd.revents;
+
+ if (revents)
processed++;
- EventHandler* eh = GetRef(pfd.fd);
+ EventHandler* eh = GetRef(fd);
if (!eh)
continue;
- if (pfd.revents & POLLHUP)
+ if (revents & POLLHUP)
{
eh->HandleEvent(EVENT_ERROR, 0);
continue;
}
- if (pfd.revents & POLLERR)
+ if (revents & POLLERR)
{
// Get error number
- if (getsockopt(pfd.fd, SOL_SOCKET, SO_ERROR, &errcode, &codesize) < 0)
+ if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &errcode, &codesize) < 0)
errcode = errno;
eh->HandleEvent(EVENT_ERROR, errcode);
continue;
}
- if (pfd.revents & POLLIN)
+ if (revents & POLLIN)
{
SetEventMask(eh, eh->GetEventMask() & ~FD_READ_WILL_BLOCK);
eh->HandleEvent(EVENT_READ);
- if (eh != GetRef(pfd.fd))
+ if (eh != GetRef(fd))
// whoops, deleted out from under us
continue;
}
- if (pfd.revents & POLLOUT)
+ if (revents & POLLOUT)
{
int mask = eh->GetEventMask();
mask &= ~(FD_WRITE_WILL_BLOCK | FD_WANT_SINGLE_WRITE);
SetEventMask(eh, mask);
- pfd.events = mask_to_poll(mask);
+
+ // The vector could've been resized, reference can be invalid by now; don't use it
+ events[index].events = mask_to_poll(mask);
eh->HandleEvent(EVENT_WRITE);
}
}
diff --git a/src/socketengines/socketengine_ports.cpp b/src/socketengines/socketengine_ports.cpp
index 569155021..098e75116 100644
--- a/src/socketengines/socketengine_ports.cpp
+++ b/src/socketengines/socketengine_ports.cpp
@@ -162,27 +162,29 @@ int PortsEngine::DispatchEvents()
if (ev.portev_source != PORT_SOURCE_FD)
continue;
- int fd = ev.portev_object;
+ // Copy these in case the vector gets resized and ev invalidated
+ const int fd = ev.portev_object;
+ const int portev_events = ev.portev_events;
EventHandler* eh = GetRef(fd);
if (!eh)
continue;
int mask = eh->GetEventMask();
- if (ev.portev_events & POLLWRNORM)
+ if (portev_events & POLLWRNORM)
mask &= ~(FD_WRITE_WILL_BLOCK | FD_WANT_FAST_WRITE | FD_WANT_SINGLE_WRITE);
- if (ev.portev_events & POLLRDNORM)
+ if (portev_events & POLLRDNORM)
mask &= ~FD_READ_WILL_BLOCK;
// reinsert port for next time around, pretending to be one-shot for writes
SetEventMask(eh, mask);
port_associate(EngineHandle, PORT_SOURCE_FD, fd, mask_to_events(mask), eh);
- if (ev.portev_events & POLLRDNORM)
+ if (portev_events & POLLRDNORM)
{
ReadEvents++;
eh->HandleEvent(EVENT_READ);
if (eh != GetRef(fd))
continue;
}
- if (ev.portev_events & POLLWRNORM)
+ if (portev_events & POLLWRNORM)
{
WriteEvents++;
eh->HandleEvent(EVENT_WRITE);