From 273e7f249c60a38f043d7b495e513f0d63de7e64 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Sun, 25 Feb 2024 23:54:12 +0000 Subject: Remove duplicate suffix from socketengine file names. --- src/CMakeLists.txt | 8 +- src/socketengines/epoll.cpp | 121 ++++++++++++++++++++++++ src/socketengines/kqueue.cpp | 123 +++++++++++++++++++++++++ src/socketengines/poll.cpp | 148 ++++++++++++++++++++++++++++++ src/socketengines/select.cpp | 148 ++++++++++++++++++++++++++++++ src/socketengines/socketengine_epoll.cpp | 121 ------------------------ src/socketengines/socketengine_kqueue.cpp | 123 ------------------------- src/socketengines/socketengine_poll.cpp | 148 ------------------------------ src/socketengines/socketengine_select.cpp | 148 ------------------------------ 9 files changed, 544 insertions(+), 544 deletions(-) create mode 100644 src/socketengines/epoll.cpp create mode 100644 src/socketengines/kqueue.cpp create mode 100644 src/socketengines/poll.cpp create mode 100644 src/socketengines/select.cpp delete mode 100644 src/socketengines/socketengine_epoll.cpp delete mode 100644 src/socketengines/socketengine_kqueue.cpp delete mode 100644 src/socketengines/socketengine_poll.cpp delete mode 100644 src/socketengines/socketengine_select.cpp (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f4c3dfb92..9ca613eda 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,13 +10,13 @@ if(WIN32) endif() if(HAVE_EPOLL) - list(APPEND SRC_SRCS socketengines/socketengine_epoll.cpp) + list(APPEND SRC_SRCS socketengines/epoll.cpp) elseif(HAVE_KQUEUE) - list(APPEND SRC_SRCS socketengines/socketengine_kqueue.cpp) + list(APPEND SRC_SRCS socketengines/kqueue.cpp) elseif(HAVE_POLL) - list(APPEND SRC_SRCS socketengines/socketengine_poll.cpp) + list(APPEND SRC_SRCS socketengines/poll.cpp) else() - list(APPEND SRC_SRCS socketengines/socketengine_select.cpp) + list(APPEND SRC_SRCS socketengines/select.cpp) endif() list(SORT SRC_SRCS) diff --git a/src/socketengines/epoll.cpp b/src/socketengines/epoll.cpp new file mode 100644 index 000000000..e67745096 --- /dev/null +++ b/src/socketengines/epoll.cpp @@ -0,0 +1,121 @@ +/* + * + * (C) 2003-2024 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +#include "services.h" +#include "anope.h" +#include "sockets.h" +#include "socketengine.h" +#include "config.h" + +#include +#include +#include + +static int EngineHandle; +static std::vector events; + +void SocketEngine::Init() +{ + EngineHandle = epoll_create(4); + + if (EngineHandle == -1) + throw SocketException("Could not initialize epoll socket engine: " + Anope::LastError()); + + events.resize(DefaultSize); +} + +void SocketEngine::Shutdown() +{ + while (!Sockets.empty()) + delete Sockets.begin()->second; +} + +void SocketEngine::Change(Socket *s, bool set, SocketFlag flag) +{ + if (set == s->flags[flag]) + return; + + bool before_registered = s->flags[SF_READABLE] || s->flags[SF_WRITABLE]; + + s->flags[flag] = set; + + bool now_registered = s->flags[SF_READABLE] || s->flags[SF_WRITABLE]; + + epoll_event ev; + + memset(&ev, 0, sizeof(ev)); + + ev.events = (s->flags[SF_READABLE] ? EPOLLIN : 0u) | (s->flags[SF_WRITABLE] ? EPOLLOUT : 0u); + ev.data.fd = s->GetFD(); + + int mod; + if (!before_registered && now_registered) + mod = EPOLL_CTL_ADD; + else if (before_registered && !now_registered) + mod = EPOLL_CTL_DEL; + else if (before_registered && now_registered) + mod = EPOLL_CTL_MOD; + else + return; + + if (epoll_ctl(EngineHandle, mod, ev.data.fd, &ev) == -1) + throw SocketException("Unable to epoll_ctl() fd " + stringify(ev.data.fd) + " to epoll: " + Anope::LastError()); +} + +void SocketEngine::Process() +{ + if (Sockets.size() > events.size()) + events.resize(events.size() * 2); + + int total = epoll_wait(EngineHandle, &events.front(), events.size(), Config->ReadTimeout * 1000); + Anope::CurTime = time(NULL); + + /* EINTR can be given if the read timeout expires */ + if (total == -1) + { + if (errno != EINTR) + Log() << "SockEngine::Process(): error: " << Anope::LastError(); + return; + } + + for (int i = 0; i < total; ++i) + { + epoll_event &ev = events[i]; + + std::map::iterator it = Sockets.find(ev.data.fd); + if (it == Sockets.end()) + continue; + Socket *s = it->second; + + if (ev.events & (EPOLLHUP | EPOLLERR)) + { + s->ProcessError(); + delete s; + continue; + } + + if (!s->Process()) + { + if (s->flags[SF_DEAD]) + delete s; + continue; + } + + if ((ev.events & EPOLLIN) && !s->ProcessRead()) + s->flags[SF_DEAD] = true; + + if ((ev.events & EPOLLOUT) && !s->ProcessWrite()) + s->flags[SF_DEAD] = true; + + if (s->flags[SF_DEAD]) + delete s; + } +} diff --git a/src/socketengines/kqueue.cpp b/src/socketengines/kqueue.cpp new file mode 100644 index 000000000..c57ab1b7d --- /dev/null +++ b/src/socketengines/kqueue.cpp @@ -0,0 +1,123 @@ +/* + * + * (C) 2003-2024 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +#include "services.h" +#include "anope.h" +#include "sockets.h" +#include "socketengine.h" +#include "logger.h" +#include "config.h" + +#include +#include +#include +#include + +static int kq_fd; +static std::vector change_events, event_events; +static unsigned change_count; + +static inline struct kevent *GetChangeEvent() +{ + if (change_count == change_events.size()) + change_events.resize(change_count * 2); + + return &change_events[change_count++]; +} + +void SocketEngine::Init() +{ + kq_fd = kqueue(); + + if (kq_fd < 0) + throw SocketException("Unable to create kqueue engine: " + Anope::LastError()); + + change_events.resize(DefaultSize); + event_events.resize(DefaultSize); +} + +void SocketEngine::Shutdown() +{ + while (!Sockets.empty()) + delete Sockets.begin()->second; +} + +void SocketEngine::Change(Socket *s, bool set, SocketFlag flag) +{ + if (set == s->flags[flag]) + return; + + s->flags[flag] = set; + + int mod; + if (flag == SF_READABLE) + mod = EVFILT_READ; + else if (flag == SF_WRITABLE) + mod = EVFILT_WRITE; + else + return; + + struct kevent *event = GetChangeEvent(); + EV_SET(event, s->GetFD(), mod, set ? EV_ADD : EV_DELETE, 0, 0, NULL); +} + +void SocketEngine::Process() +{ + if (Sockets.size() > event_events.size()) + event_events.resize(event_events.size() * 2); + + static timespec kq_timespec = { Config->ReadTimeout, 0 }; + int total = kevent(kq_fd, &change_events.front(), change_count, &event_events.front(), event_events.size(), &kq_timespec); + change_count = 0; + Anope::CurTime = time(NULL); + + /* EINTR can be given if the read timeout expires */ + if (total == -1) + { + if (errno != EINTR) + Log() << "SockEngine::Process(): error: " << Anope::LastError(); + return; + } + + for (int i = 0; i < total; ++i) + { + struct kevent &event = event_events[i]; + if (event.flags & EV_ERROR) + continue; + + std::map::iterator it = Sockets.find(event.ident); + if (it == Sockets.end()) + continue; + Socket *s = it->second; + + if (event.flags & EV_EOF) + { + s->ProcessError(); + delete s; + continue; + } + + if (!s->Process()) + { + if (s->flags[SF_DEAD]) + delete s; + continue; + } + + if (event.filter == EVFILT_READ && !s->ProcessRead()) + s->flags[SF_DEAD] = true; + else if (event.filter == EVFILT_WRITE && !s->ProcessWrite()) + s->flags[SF_DEAD] = true; + + if (s->flags[SF_DEAD]) + delete s; + } +} diff --git a/src/socketengines/poll.cpp b/src/socketengines/poll.cpp new file mode 100644 index 000000000..e9a81933b --- /dev/null +++ b/src/socketengines/poll.cpp @@ -0,0 +1,148 @@ +/* + * + * (C) 2003-2024 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +#include "services.h" +#include "anope.h" +#include "sockets.h" +#include "socketengine.h" +#include "config.h" + +#include + +#ifndef _WIN32 +# include +# include +# include +# include +# include +# ifndef POLLRDHUP +# define POLLRDHUP 0 +# endif +#else +# define poll WSAPoll +# define POLLRDHUP POLLHUP +#endif + +static std::vector events; +static std::map socket_positions; + +void SocketEngine::Init() +{ + events.resize(DefaultSize); +} + +void SocketEngine::Shutdown() +{ + while (!Sockets.empty()) + delete Sockets.begin()->second; +} + +void SocketEngine::Change(Socket *s, bool set, SocketFlag flag) +{ + if (set == s->flags[flag]) + return; + + bool before_registered = s->flags[SF_READABLE] || s->flags[SF_WRITABLE]; + + s->flags[flag] = set; + + bool now_registered = s->flags[SF_READABLE] || s->flags[SF_WRITABLE]; + + if (!before_registered && now_registered) + { + pollfd ev; + memset(&ev, 0, sizeof(ev)); + + ev.fd = s->GetFD(); + ev.events = (s->flags[SF_READABLE] ? POLLIN : 0) | (s->flags[SF_WRITABLE] ? POLLOUT : 0); + + socket_positions[ev.fd] = events.size(); + events.push_back(ev); + } + else if (before_registered && !now_registered) + { + std::map::iterator pos = socket_positions.find(s->GetFD()); + if (pos == socket_positions.end()) + throw SocketException("Unable to remove fd " + stringify(s->GetFD()) + " from poll, it does not exist?"); + + if (pos->second != events.size() - 1) + { + pollfd &ev = events[pos->second], + &last_ev = events[events.size() - 1]; + + ev = last_ev; + + socket_positions[ev.fd] = pos->second; + } + + socket_positions.erase(pos); + events.pop_back(); + } + else if (before_registered && now_registered) + { + std::map::iterator pos = socket_positions.find(s->GetFD()); + if (pos == socket_positions.end()) + throw SocketException("Unable to modify fd " + stringify(s->GetFD()) + " in poll, it does not exist?"); + + pollfd &ev = events[pos->second]; + ev.events = (s->flags[SF_READABLE] ? POLLIN : 0) | (s->flags[SF_WRITABLE] ? POLLOUT : 0); + } +} + +void SocketEngine::Process() +{ + int total = poll(&events.front(), events.size(), Config->ReadTimeout * 1000); + Anope::CurTime = time(NULL); + + /* EINTR can be given if the read timeout expires */ + if (total < 0) + { + if (errno != EINTR) + Log() << "SockEngine::Process(): error: " << Anope::LastError(); + return; + } + + for (unsigned i = 0, processed = 0; i < events.size() && processed != static_cast(total); ++i) + { + pollfd *ev = &events[i]; + + if (ev->revents != 0) + ++processed; + + std::map::iterator it = Sockets.find(ev->fd); + if (it == Sockets.end()) + continue; + Socket *s = it->second; + + if (ev->revents & (POLLERR | POLLRDHUP)) + { + s->ProcessError(); + delete s; + continue; + } + + if (!s->Process()) + { + if (s->flags[SF_DEAD]) + delete s; + continue; + } + + if ((ev->revents & POLLIN) && !s->ProcessRead()) + s->flags[SF_DEAD] = true; + + if ((ev->revents & POLLOUT) && !s->ProcessWrite()) + s->flags[SF_DEAD] = true; + + if (s->flags[SF_DEAD]) + delete s; + } +} diff --git a/src/socketengines/select.cpp b/src/socketengines/select.cpp new file mode 100644 index 000000000..9a8582e5d --- /dev/null +++ b/src/socketengines/select.cpp @@ -0,0 +1,148 @@ +/* + * + * (C) 2003-2024 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +#include "services.h" +#include "anope.h" +#include "sockets.h" +#include "socketengine.h" +#include "logger.h" +#include "config.h" + +#ifdef _AIX +# undef FD_ZERO +# define FD_ZERO(p) memset((p), 0, sizeof(*(p))) +#endif /* _AIX */ + +static int MaxFD; +static unsigned FDCount; +static fd_set ReadFDs; +static fd_set WriteFDs; + +void SocketEngine::Init() +{ + FD_ZERO(&ReadFDs); + FD_ZERO(&WriteFDs); +} + +void SocketEngine::Shutdown() +{ + while (!Sockets.empty()) + delete Sockets.begin()->second; +} + +void SocketEngine::Change(Socket *s, bool set, SocketFlag flag) +{ + if (set == s->flags[flag]) + return; + + bool before_registered = s->flags[SF_READABLE] || s->flags[SF_WRITABLE]; + + s->flags[flag] = set; + + bool now_registered = s->flags[SF_READABLE] || s->flags[SF_WRITABLE]; + + if (!before_registered && now_registered) + { + if (s->GetFD() > MaxFD) + MaxFD = s->GetFD(); + if (s->flags[SF_READABLE]) + FD_SET(s->GetFD(), &ReadFDs); + if (s->flags[SF_WRITABLE]) + FD_SET(s->GetFD(), &WriteFDs); + ++FDCount; + } + else if (before_registered && !now_registered) + { + if (s->GetFD() == MaxFD) + --MaxFD; + FD_CLR(s->GetFD(), &ReadFDs); + FD_CLR(s->GetFD(), &WriteFDs); + --FDCount; + } + else if (before_registered && now_registered) + { + if (s->flags[SF_READABLE]) + FD_SET(s->GetFD(), &ReadFDs); + else + FD_CLR(s->GetFD(), &ReadFDs); + + if (s->flags[SF_WRITABLE]) + FD_SET(s->GetFD(), &WriteFDs); + else + FD_CLR(s->GetFD(), &WriteFDs); + } +} + +void SocketEngine::Process() +{ + fd_set rfdset = ReadFDs, wfdset = WriteFDs, efdset = ReadFDs; + timeval tval; + tval.tv_sec = Config->ReadTimeout; + tval.tv_usec = 0; + +#ifdef _WIN32 + /* We can use the socket engine to "sleep" services for a period of + * time between connections to the uplink, which allows modules, + * timers, etc to function properly. Windows, being as useful as it is, + * does not allow to select() on 0 sockets and will immediately return error. + * Thus: + */ + if (FDCount == 0) + { + sleep(tval.tv_sec); + return; + } +#endif + + int sresult = select(MaxFD + 1, &rfdset, &wfdset, &efdset, &tval); + Anope::CurTime = time(NULL); + + if (sresult == -1) + { + Log() << "SockEngine::Process(): error: " << Anope::LastError(); + } + else if (sresult) + { + int processed = 0; + for (std::map::const_iterator it = Sockets.begin(), it_end = Sockets.end(); it != it_end && processed != sresult;) + { + Socket *s = it->second; + ++it; + + bool has_read = FD_ISSET(s->GetFD(), &rfdset), has_write = FD_ISSET(s->GetFD(), &wfdset), has_error = FD_ISSET(s->GetFD(), &efdset); + if (has_read || has_write || has_error) + ++processed; + + if (has_error) + { + s->ProcessError(); + delete s; + continue; + } + + if (!s->Process()) + { + if (s->flags[SF_DEAD]) + delete s; + continue; + } + + if (has_read && !s->ProcessRead()) + s->flags[SF_DEAD] = true; + + if (has_write && !s->ProcessWrite()) + s->flags[SF_DEAD] = true; + + if (s->flags[SF_DEAD]) + delete s; + } + } +} diff --git a/src/socketengines/socketengine_epoll.cpp b/src/socketengines/socketengine_epoll.cpp deleted file mode 100644 index e67745096..000000000 --- a/src/socketengines/socketengine_epoll.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - * - * (C) 2003-2024 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -#include "services.h" -#include "anope.h" -#include "sockets.h" -#include "socketengine.h" -#include "config.h" - -#include -#include -#include - -static int EngineHandle; -static std::vector events; - -void SocketEngine::Init() -{ - EngineHandle = epoll_create(4); - - if (EngineHandle == -1) - throw SocketException("Could not initialize epoll socket engine: " + Anope::LastError()); - - events.resize(DefaultSize); -} - -void SocketEngine::Shutdown() -{ - while (!Sockets.empty()) - delete Sockets.begin()->second; -} - -void SocketEngine::Change(Socket *s, bool set, SocketFlag flag) -{ - if (set == s->flags[flag]) - return; - - bool before_registered = s->flags[SF_READABLE] || s->flags[SF_WRITABLE]; - - s->flags[flag] = set; - - bool now_registered = s->flags[SF_READABLE] || s->flags[SF_WRITABLE]; - - epoll_event ev; - - memset(&ev, 0, sizeof(ev)); - - ev.events = (s->flags[SF_READABLE] ? EPOLLIN : 0u) | (s->flags[SF_WRITABLE] ? EPOLLOUT : 0u); - ev.data.fd = s->GetFD(); - - int mod; - if (!before_registered && now_registered) - mod = EPOLL_CTL_ADD; - else if (before_registered && !now_registered) - mod = EPOLL_CTL_DEL; - else if (before_registered && now_registered) - mod = EPOLL_CTL_MOD; - else - return; - - if (epoll_ctl(EngineHandle, mod, ev.data.fd, &ev) == -1) - throw SocketException("Unable to epoll_ctl() fd " + stringify(ev.data.fd) + " to epoll: " + Anope::LastError()); -} - -void SocketEngine::Process() -{ - if (Sockets.size() > events.size()) - events.resize(events.size() * 2); - - int total = epoll_wait(EngineHandle, &events.front(), events.size(), Config->ReadTimeout * 1000); - Anope::CurTime = time(NULL); - - /* EINTR can be given if the read timeout expires */ - if (total == -1) - { - if (errno != EINTR) - Log() << "SockEngine::Process(): error: " << Anope::LastError(); - return; - } - - for (int i = 0; i < total; ++i) - { - epoll_event &ev = events[i]; - - std::map::iterator it = Sockets.find(ev.data.fd); - if (it == Sockets.end()) - continue; - Socket *s = it->second; - - if (ev.events & (EPOLLHUP | EPOLLERR)) - { - s->ProcessError(); - delete s; - continue; - } - - if (!s->Process()) - { - if (s->flags[SF_DEAD]) - delete s; - continue; - } - - if ((ev.events & EPOLLIN) && !s->ProcessRead()) - s->flags[SF_DEAD] = true; - - if ((ev.events & EPOLLOUT) && !s->ProcessWrite()) - s->flags[SF_DEAD] = true; - - if (s->flags[SF_DEAD]) - delete s; - } -} diff --git a/src/socketengines/socketengine_kqueue.cpp b/src/socketengines/socketengine_kqueue.cpp deleted file mode 100644 index c57ab1b7d..000000000 --- a/src/socketengines/socketengine_kqueue.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * - * (C) 2003-2024 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -#include "services.h" -#include "anope.h" -#include "sockets.h" -#include "socketengine.h" -#include "logger.h" -#include "config.h" - -#include -#include -#include -#include - -static int kq_fd; -static std::vector change_events, event_events; -static unsigned change_count; - -static inline struct kevent *GetChangeEvent() -{ - if (change_count == change_events.size()) - change_events.resize(change_count * 2); - - return &change_events[change_count++]; -} - -void SocketEngine::Init() -{ - kq_fd = kqueue(); - - if (kq_fd < 0) - throw SocketException("Unable to create kqueue engine: " + Anope::LastError()); - - change_events.resize(DefaultSize); - event_events.resize(DefaultSize); -} - -void SocketEngine::Shutdown() -{ - while (!Sockets.empty()) - delete Sockets.begin()->second; -} - -void SocketEngine::Change(Socket *s, bool set, SocketFlag flag) -{ - if (set == s->flags[flag]) - return; - - s->flags[flag] = set; - - int mod; - if (flag == SF_READABLE) - mod = EVFILT_READ; - else if (flag == SF_WRITABLE) - mod = EVFILT_WRITE; - else - return; - - struct kevent *event = GetChangeEvent(); - EV_SET(event, s->GetFD(), mod, set ? EV_ADD : EV_DELETE, 0, 0, NULL); -} - -void SocketEngine::Process() -{ - if (Sockets.size() > event_events.size()) - event_events.resize(event_events.size() * 2); - - static timespec kq_timespec = { Config->ReadTimeout, 0 }; - int total = kevent(kq_fd, &change_events.front(), change_count, &event_events.front(), event_events.size(), &kq_timespec); - change_count = 0; - Anope::CurTime = time(NULL); - - /* EINTR can be given if the read timeout expires */ - if (total == -1) - { - if (errno != EINTR) - Log() << "SockEngine::Process(): error: " << Anope::LastError(); - return; - } - - for (int i = 0; i < total; ++i) - { - struct kevent &event = event_events[i]; - if (event.flags & EV_ERROR) - continue; - - std::map::iterator it = Sockets.find(event.ident); - if (it == Sockets.end()) - continue; - Socket *s = it->second; - - if (event.flags & EV_EOF) - { - s->ProcessError(); - delete s; - continue; - } - - if (!s->Process()) - { - if (s->flags[SF_DEAD]) - delete s; - continue; - } - - if (event.filter == EVFILT_READ && !s->ProcessRead()) - s->flags[SF_DEAD] = true; - else if (event.filter == EVFILT_WRITE && !s->ProcessWrite()) - s->flags[SF_DEAD] = true; - - if (s->flags[SF_DEAD]) - delete s; - } -} diff --git a/src/socketengines/socketengine_poll.cpp b/src/socketengines/socketengine_poll.cpp deleted file mode 100644 index e9a81933b..000000000 --- a/src/socketengines/socketengine_poll.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - * - * (C) 2003-2024 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -#include "services.h" -#include "anope.h" -#include "sockets.h" -#include "socketengine.h" -#include "config.h" - -#include - -#ifndef _WIN32 -# include -# include -# include -# include -# include -# ifndef POLLRDHUP -# define POLLRDHUP 0 -# endif -#else -# define poll WSAPoll -# define POLLRDHUP POLLHUP -#endif - -static std::vector events; -static std::map socket_positions; - -void SocketEngine::Init() -{ - events.resize(DefaultSize); -} - -void SocketEngine::Shutdown() -{ - while (!Sockets.empty()) - delete Sockets.begin()->second; -} - -void SocketEngine::Change(Socket *s, bool set, SocketFlag flag) -{ - if (set == s->flags[flag]) - return; - - bool before_registered = s->flags[SF_READABLE] || s->flags[SF_WRITABLE]; - - s->flags[flag] = set; - - bool now_registered = s->flags[SF_READABLE] || s->flags[SF_WRITABLE]; - - if (!before_registered && now_registered) - { - pollfd ev; - memset(&ev, 0, sizeof(ev)); - - ev.fd = s->GetFD(); - ev.events = (s->flags[SF_READABLE] ? POLLIN : 0) | (s->flags[SF_WRITABLE] ? POLLOUT : 0); - - socket_positions[ev.fd] = events.size(); - events.push_back(ev); - } - else if (before_registered && !now_registered) - { - std::map::iterator pos = socket_positions.find(s->GetFD()); - if (pos == socket_positions.end()) - throw SocketException("Unable to remove fd " + stringify(s->GetFD()) + " from poll, it does not exist?"); - - if (pos->second != events.size() - 1) - { - pollfd &ev = events[pos->second], - &last_ev = events[events.size() - 1]; - - ev = last_ev; - - socket_positions[ev.fd] = pos->second; - } - - socket_positions.erase(pos); - events.pop_back(); - } - else if (before_registered && now_registered) - { - std::map::iterator pos = socket_positions.find(s->GetFD()); - if (pos == socket_positions.end()) - throw SocketException("Unable to modify fd " + stringify(s->GetFD()) + " in poll, it does not exist?"); - - pollfd &ev = events[pos->second]; - ev.events = (s->flags[SF_READABLE] ? POLLIN : 0) | (s->flags[SF_WRITABLE] ? POLLOUT : 0); - } -} - -void SocketEngine::Process() -{ - int total = poll(&events.front(), events.size(), Config->ReadTimeout * 1000); - Anope::CurTime = time(NULL); - - /* EINTR can be given if the read timeout expires */ - if (total < 0) - { - if (errno != EINTR) - Log() << "SockEngine::Process(): error: " << Anope::LastError(); - return; - } - - for (unsigned i = 0, processed = 0; i < events.size() && processed != static_cast(total); ++i) - { - pollfd *ev = &events[i]; - - if (ev->revents != 0) - ++processed; - - std::map::iterator it = Sockets.find(ev->fd); - if (it == Sockets.end()) - continue; - Socket *s = it->second; - - if (ev->revents & (POLLERR | POLLRDHUP)) - { - s->ProcessError(); - delete s; - continue; - } - - if (!s->Process()) - { - if (s->flags[SF_DEAD]) - delete s; - continue; - } - - if ((ev->revents & POLLIN) && !s->ProcessRead()) - s->flags[SF_DEAD] = true; - - if ((ev->revents & POLLOUT) && !s->ProcessWrite()) - s->flags[SF_DEAD] = true; - - if (s->flags[SF_DEAD]) - delete s; - } -} diff --git a/src/socketengines/socketengine_select.cpp b/src/socketengines/socketengine_select.cpp deleted file mode 100644 index 9a8582e5d..000000000 --- a/src/socketengines/socketengine_select.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - * - * (C) 2003-2024 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - */ - -#include "services.h" -#include "anope.h" -#include "sockets.h" -#include "socketengine.h" -#include "logger.h" -#include "config.h" - -#ifdef _AIX -# undef FD_ZERO -# define FD_ZERO(p) memset((p), 0, sizeof(*(p))) -#endif /* _AIX */ - -static int MaxFD; -static unsigned FDCount; -static fd_set ReadFDs; -static fd_set WriteFDs; - -void SocketEngine::Init() -{ - FD_ZERO(&ReadFDs); - FD_ZERO(&WriteFDs); -} - -void SocketEngine::Shutdown() -{ - while (!Sockets.empty()) - delete Sockets.begin()->second; -} - -void SocketEngine::Change(Socket *s, bool set, SocketFlag flag) -{ - if (set == s->flags[flag]) - return; - - bool before_registered = s->flags[SF_READABLE] || s->flags[SF_WRITABLE]; - - s->flags[flag] = set; - - bool now_registered = s->flags[SF_READABLE] || s->flags[SF_WRITABLE]; - - if (!before_registered && now_registered) - { - if (s->GetFD() > MaxFD) - MaxFD = s->GetFD(); - if (s->flags[SF_READABLE]) - FD_SET(s->GetFD(), &ReadFDs); - if (s->flags[SF_WRITABLE]) - FD_SET(s->GetFD(), &WriteFDs); - ++FDCount; - } - else if (before_registered && !now_registered) - { - if (s->GetFD() == MaxFD) - --MaxFD; - FD_CLR(s->GetFD(), &ReadFDs); - FD_CLR(s->GetFD(), &WriteFDs); - --FDCount; - } - else if (before_registered && now_registered) - { - if (s->flags[SF_READABLE]) - FD_SET(s->GetFD(), &ReadFDs); - else - FD_CLR(s->GetFD(), &ReadFDs); - - if (s->flags[SF_WRITABLE]) - FD_SET(s->GetFD(), &WriteFDs); - else - FD_CLR(s->GetFD(), &WriteFDs); - } -} - -void SocketEngine::Process() -{ - fd_set rfdset = ReadFDs, wfdset = WriteFDs, efdset = ReadFDs; - timeval tval; - tval.tv_sec = Config->ReadTimeout; - tval.tv_usec = 0; - -#ifdef _WIN32 - /* We can use the socket engine to "sleep" services for a period of - * time between connections to the uplink, which allows modules, - * timers, etc to function properly. Windows, being as useful as it is, - * does not allow to select() on 0 sockets and will immediately return error. - * Thus: - */ - if (FDCount == 0) - { - sleep(tval.tv_sec); - return; - } -#endif - - int sresult = select(MaxFD + 1, &rfdset, &wfdset, &efdset, &tval); - Anope::CurTime = time(NULL); - - if (sresult == -1) - { - Log() << "SockEngine::Process(): error: " << Anope::LastError(); - } - else if (sresult) - { - int processed = 0; - for (std::map::const_iterator it = Sockets.begin(), it_end = Sockets.end(); it != it_end && processed != sresult;) - { - Socket *s = it->second; - ++it; - - bool has_read = FD_ISSET(s->GetFD(), &rfdset), has_write = FD_ISSET(s->GetFD(), &wfdset), has_error = FD_ISSET(s->GetFD(), &efdset); - if (has_read || has_write || has_error) - ++processed; - - if (has_error) - { - s->ProcessError(); - delete s; - continue; - } - - if (!s->Process()) - { - if (s->flags[SF_DEAD]) - delete s; - continue; - } - - if (has_read && !s->ProcessRead()) - s->flags[SF_DEAD] = true; - - if (has_write && !s->ProcessWrite()) - s->flags[SF_DEAD] = true; - - if (s->flags[SF_DEAD]) - delete s; - } - } -} -- cgit