diff options
Diffstat (limited to 'src/event')
-rw-r--r-- | src/event/Loop.cxx | 9 | ||||
-rw-r--r-- | src/event/Loop.hxx | 7 | ||||
-rw-r--r-- | src/event/SocketMonitor.cxx | 13 | ||||
-rw-r--r-- | src/event/SocketMonitor.hxx | 5 |
4 files changed, 32 insertions, 2 deletions
diff --git a/src/event/Loop.cxx b/src/event/Loop.cxx index 665dfa500..5aa24aea2 100644 --- a/src/event/Loop.cxx +++ b/src/event/Loop.cxx @@ -58,13 +58,18 @@ EventLoop::Break() AddCall([this]() { Break(); }); } -bool -EventLoop::RemoveFD(int _fd, SocketMonitor &m) +void +EventLoop::Abandon(SocketMonitor &m) { for (unsigned i = 0, n = n_events; i < n; ++i) if (events[i].data.ptr == &m) events[i].events = 0; +} +bool +EventLoop::RemoveFD(int _fd, SocketMonitor &m) +{ + Abandon(m); return epoll.Remove(_fd); } diff --git a/src/event/Loop.hxx b/src/event/Loop.hxx index 859ce2733..62e733747 100644 --- a/src/event/Loop.hxx +++ b/src/event/Loop.hxx @@ -121,6 +121,13 @@ public: return epoll.Modify(_fd, flags, &m); } + /** + * Remove the given #SocketMonitor after the file descriptor + * has been closed. This is like RemoveFD(), but does not + * attempt to use #EPOLL_CTL_DEL. + */ + void Abandon(SocketMonitor &m); + bool RemoveFD(int fd, SocketMonitor &m); void AddIdle(IdleMonitor &i); diff --git a/src/event/SocketMonitor.cxx b/src/event/SocketMonitor.cxx index 7c118cfd6..2b97059f7 100644 --- a/src/event/SocketMonitor.cxx +++ b/src/event/SocketMonitor.cxx @@ -152,6 +152,19 @@ SocketMonitor::Steal() } void +SocketMonitor::Abandon() +{ + assert(IsDefined()); + +#ifdef USE_EPOLL + fd = -1; + loop.Abandon(*this); +#else + Steal(); +#endif +} + +void SocketMonitor::Close() { close_socket(Steal()); diff --git a/src/event/SocketMonitor.hxx b/src/event/SocketMonitor.hxx index d6efeac17..5369ddb8a 100644 --- a/src/event/SocketMonitor.hxx +++ b/src/event/SocketMonitor.hxx @@ -118,6 +118,11 @@ public: */ int Steal(); + /** + * Somebody has closed the socket. Unregister this object. + */ + void Abandon(); + void Close(); unsigned GetScheduledFlags() const { |