diff options
-rw-r--r-- | include/socketengine.h | 21 | ||||
-rw-r--r-- | src/socketengine.cpp | 25 | ||||
-rw-r--r-- | src/socketengines/socketengine_epoll.cpp | 43 | ||||
-rw-r--r-- | src/socketengines/socketengine_kqueue.cpp | 41 | ||||
-rw-r--r-- | src/socketengines/socketengine_poll.cpp | 146 | ||||
-rw-r--r-- | src/socketengines/socketengine_ports.cpp | 80 | ||||
-rw-r--r-- | src/socketengines/socketengine_select.cpp | 22 |
7 files changed, 184 insertions, 194 deletions
diff --git a/include/socketengine.h b/include/socketengine.h index 4a2285a98..072ed9bde 100644 --- a/include/socketengine.h +++ b/include/socketengine.h @@ -230,13 +230,14 @@ class CoreExport EventHandler : public classbase */ class CoreExport SocketEngine { + /** Reference table, contains all current handlers + **/ + std::vector<EventHandler*> ref; + protected: /** Current number of descriptors in the engine */ size_t CurrentSetSize; - /** Reference table, contains all current handlers - */ - EventHandler** ref; /** List of handlers that want a trial read/write */ std::set<int> trials; @@ -251,6 +252,18 @@ class CoreExport SocketEngine virtual void OnSetEvent(EventHandler* eh, int old_mask, int new_mask) = 0; void SetEventMask(EventHandler* eh, int value); + + /** Add an event handler to the base socket engine. AddFd(EventHandler*, int) should call this. + */ + bool AddFd(EventHandler* eh); + + template <typename T> + void ResizeDouble(std::vector<T>& vect) + { + if (CurrentSetSize > vect.size()) + vect.resize(vect.size() * 2); + } + public: unsigned long TotalEvents; @@ -314,7 +327,7 @@ public: * required you must do this yourself. * @param eh The event handler object to remove */ - virtual void DelFd(EventHandler* eh) = 0; + virtual void DelFd(EventHandler* eh); /** Returns true if a file descriptor exists in * the socket engine's list. diff --git a/src/socketengine.cpp b/src/socketengine.cpp index 219d154f2..c2a357b38 100644 --- a/src/socketengine.cpp +++ b/src/socketengine.cpp @@ -94,16 +94,33 @@ void SocketEngine::DispatchTrialWrites() } } -bool SocketEngine::HasFd(int fd) +bool SocketEngine::AddFd(EventHandler* eh) { - if ((fd < 0) || (fd > GetMaxFds())) + int fd = eh->GetFd(); + if (HasFd(fd)) return false; - return (ref[fd] != NULL); + + while (static_cast<unsigned int>(fd) >= ref.size()) + ref.resize(ref.empty() ? 1 : (ref.size() * 2)); + ref[fd] = eh; + return true; +} + +void SocketEngine::DelFd(EventHandler *eh) +{ + int fd = eh->GetFd(); + if (GetRef(fd) == eh) + ref[fd] = NULL; +} + +bool SocketEngine::HasFd(int fd) +{ + return GetRef(fd) != NULL; } EventHandler* SocketEngine::GetRef(int fd) { - if ((fd < 0) || (fd > GetMaxFds())) + if (fd < 0 || static_cast<unsigned int>(fd) >= ref.size()) return 0; return ref[fd]; } diff --git a/src/socketengines/socketengine_epoll.cpp b/src/socketengines/socketengine_epoll.cpp index 099f793a1..8f5066c22 100644 --- a/src/socketengines/socketengine_epoll.cpp +++ b/src/socketengines/socketengine_epoll.cpp @@ -36,7 +36,7 @@ class EPollEngine : public SocketEngine private: /** These are used by epoll() to hold socket events */ - struct epoll_event* events; + std::vector<struct epoll_event> events; int EngineHandle; public: /** Create a new EPollEngine @@ -52,7 +52,7 @@ public: virtual std::string GetName(); }; -EPollEngine::EPollEngine() +EPollEngine::EPollEngine() : events(1) { int max = ulimit(4, 0); if (max > 0) @@ -77,18 +77,11 @@ EPollEngine::EPollEngine() std::cout << "ERROR: Your kernel probably does not have the proper features. This is a fatal error, exiting now." << std::endl; ServerInstance->QuickExit(EXIT_STATUS_SOCKETENGINE); } - - ref = new EventHandler* [GetMaxFds()]; - events = new struct epoll_event[GetMaxFds()]; - - memset(ref, 0, GetMaxFds() * sizeof(EventHandler*)); } EPollEngine::~EPollEngine() { this->Close(EngineHandle); - delete[] ref; - delete[] events; } static unsigned mask_to_epoll(int event_mask) @@ -123,7 +116,7 @@ bool EPollEngine::AddFd(EventHandler* eh, int event_mask) return false; } - if (ref[fd]) + if (!SocketEngine::AddFd(eh)) { ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "Attempt to add duplicate fd: %d", fd); return false; @@ -142,9 +135,10 @@ bool EPollEngine::AddFd(EventHandler* eh, int event_mask) ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "New file descriptor: %d", fd); - ref[fd] = eh; SocketEngine::SetEventMask(eh, event_mask); CurrentSetSize++; + ResizeDouble(events); + return true; } @@ -182,7 +176,7 @@ void EPollEngine::DelFd(EventHandler* eh) ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "epoll_ctl can't remove socket: %s", strerror(errno)); } - ref[fd] = NULL; + SocketEngine::DelFd(eh); ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "Remove file descriptor: %d", fd); CurrentSetSize--; @@ -192,39 +186,44 @@ int EPollEngine::DispatchEvents() { socklen_t codesize = sizeof(int); int errcode; - int i = epoll_wait(EngineHandle, events, GetMaxFds() - 1, 1000); + int i = epoll_wait(EngineHandle, &events[0], events.size(), 1000); ServerInstance->UpdateTime(); TotalEvents += i; for (int j = 0; j < i; j++) { - EventHandler* eh = ref[events[j].data.fd]; + struct epoll_event& ev = events[j]; + + EventHandler* eh = GetRef(ev.data.fd); if (!eh) { ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "Got event on unknown fd: %d", events[j].data.fd); epoll_ctl(EngineHandle, EPOLL_CTL_DEL, events[j].data.fd, &events[j]); continue; } - if (events[j].events & EPOLLHUP) + + if (ev.events & EPOLLHUP) { ErrorEvents++; eh->HandleEvent(EVENT_ERROR, 0); continue; } - if (events[j].events & EPOLLERR) + + if (ev.events & EPOLLERR) { ErrorEvents++; /* Get error number */ - if (getsockopt(events[j].data.fd, SOL_SOCKET, SO_ERROR, &errcode, &codesize) < 0) + if (getsockopt(ev.data.fd, SOL_SOCKET, SO_ERROR, &errcode, &codesize) < 0) errcode = errno; eh->HandleEvent(EVENT_ERROR, errcode); continue; } + int mask = eh->GetEventMask(); - if (events[j].events & EPOLLIN) + if (ev.events & EPOLLIN) mask &= ~FD_READ_WILL_BLOCK; - if (events[j].events & EPOLLOUT) + if (ev.events & EPOLLOUT) { mask &= ~FD_WRITE_WILL_BLOCK; if (mask & FD_WANT_SINGLE_WRITE) @@ -235,15 +234,15 @@ int EPollEngine::DispatchEvents() } } SetEventMask(eh, mask); - if (events[j].events & EPOLLIN) + if (ev.events & EPOLLIN) { ReadEvents++; eh->HandleEvent(EVENT_READ); - if (eh != ref[events[j].data.fd]) + if (eh != GetRef(ev.data.fd)) // whoa! we got deleted, better not give out the write event continue; } - if (events[j].events & EPOLLOUT) + if (ev.events & EPOLLOUT) { WriteEvents++; eh->HandleEvent(EVENT_WRITE); diff --git a/src/socketengines/socketengine_kqueue.cpp b/src/socketengines/socketengine_kqueue.cpp index 99ac51499..8c27b29b2 100644 --- a/src/socketengines/socketengine_kqueue.cpp +++ b/src/socketengines/socketengine_kqueue.cpp @@ -26,6 +26,7 @@ #include <sys/time.h> #include "socketengine.h" #include <iostream> +#include <sys/sysctl.h> /** A specialisation of the SocketEngine class, designed to use BSD kqueue(). */ @@ -35,7 +36,7 @@ private: int EngineHandle; /** These are used by kqueue() to hold socket events */ - struct kevent* ke_list; + std::vector<struct kevent> ke_list; /** This is a specialised time value used by kqueue() */ struct timespec ts; @@ -54,9 +55,7 @@ public: virtual void RecoverFromFork(); }; -#include <sys/sysctl.h> - -KQueueEngine::KQueueEngine() +KQueueEngine::KQueueEngine() : ke_list(1) { MAX_DESCRIPTORS = 0; int mib[2]; @@ -78,9 +77,6 @@ KQueueEngine::KQueueEngine() } this->RecoverFromFork(); - ke_list = new struct kevent[GetMaxFds()]; - ref = new EventHandler* [GetMaxFds()]; - memset(ref, 0, GetMaxFds() * sizeof(EventHandler*)); } void KQueueEngine::RecoverFromFork() @@ -105,8 +101,6 @@ void KQueueEngine::RecoverFromFork() KQueueEngine::~KQueueEngine() { this->Close(EngineHandle); - delete[] ref; - delete[] ke_list; } bool KQueueEngine::AddFd(EventHandler* eh, int event_mask) @@ -116,7 +110,7 @@ bool KQueueEngine::AddFd(EventHandler* eh, int event_mask) if ((fd < 0) || (fd > GetMaxFds() - 1)) return false; - if (ref[fd]) + if (!SocketEngine::AddFd(eh)) return false; // We always want to read from the socket... @@ -131,12 +125,13 @@ bool KQueueEngine::AddFd(EventHandler* eh, int event_mask) return false; } - ref[fd] = eh; + ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "New file descriptor: %d", fd); + SocketEngine::SetEventMask(eh, event_mask); OnSetEvent(eh, 0, event_mask); CurrentSetSize++; + ResizeDouble(ke_list); - ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "New file descriptor: %d", fd); return true; } @@ -167,8 +162,8 @@ void KQueueEngine::DelFd(EventHandler* eh) fd, strerror(errno)); } + SocketEngine::DelFd(eh); CurrentSetSize--; - ref[fd] = NULL; ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "Remove file descriptor: %d", fd); } @@ -215,23 +210,29 @@ int KQueueEngine::DispatchEvents() ts.tv_nsec = 0; ts.tv_sec = 1; - int i = kevent(EngineHandle, NULL, 0, &ke_list[0], GetMaxFds(), &ts); + int i = kevent(EngineHandle, NULL, 0, &ke_list[0], ke_list.size(), &ts); ServerInstance->UpdateTime(); + if (i < 0) + return i; + TotalEvents += i; for (int j = 0; j < i; j++) { - EventHandler* eh = ref[ke_list[j].ident]; + struct kevent& kev = ke_list[j]; + + EventHandler* eh = GetRef(kev.ident); if (!eh) continue; - if (ke_list[j].flags & EV_EOF) + + if (kev.flags & EV_EOF) { ErrorEvents++; - eh->HandleEvent(EVENT_ERROR, ke_list[j].fflags); + eh->HandleEvent(EVENT_ERROR, kev.fflags); continue; } - if (ke_list[j].filter == EVFILT_WRITE) + if (kev.filter == EVFILT_WRITE) { WriteEvents++; /* When mask is FD_WANT_FAST_WRITE or FD_WANT_SINGLE_WRITE, @@ -242,11 +243,11 @@ int KQueueEngine::DispatchEvents() SetEventMask(eh, eh->GetEventMask() & ~bits_to_clr); eh->HandleEvent(EVENT_WRITE); - if (eh != ref[ke_list[j].ident]) + if (eh != GetRef(kev.ident)) // whoops, deleted out from under us continue; } - if (ke_list[j].filter == EVFILT_READ) + if (kev.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 493b22630..0112b7d2f 100644 --- a/src/socketengines/socketengine_poll.cpp +++ b/src/socketengines/socketengine_poll.cpp @@ -1,6 +1,7 @@ /* * InspIRCd -- Internet Relay Chat Daemon * + * Copyright (C) 2014 Adam <Adam@anope.org> * Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org> * Copyright (C) 2009 Uli Schlachter <psychon@znc.in> * Copyright (C) 2009 Craig Edwards <craigedwards@brainbox.cc> @@ -52,20 +53,16 @@ class PollEngine : public SocketEngine private: /** These are used by poll() to hold socket events */ - struct pollfd *events; - /** This map maps fds to an index in the events array. + std::vector<struct pollfd> events; + /** This vector maps fds to an index in the events array. */ - std::map<int, unsigned int> fd_mappings; + std::vector<int> fd_mappings; public: /** Create a new PollEngine */ PollEngine(); - /** Delete a PollEngine - */ - virtual ~PollEngine(); virtual bool AddFd(EventHandler* eh, int event_mask); virtual void OnSetEvent(EventHandler* eh, int old_mask, int new_mask); - virtual EventHandler* GetRef(int fd); virtual void DelFd(EventHandler* eh); virtual int DispatchEvents(); virtual std::string GetName(); @@ -73,7 +70,7 @@ public: #endif -PollEngine::PollEngine() +PollEngine::PollEngine() : events(1), fd_mappings(1) { CurrentSetSize = 0; struct rlimit limits; @@ -87,19 +84,6 @@ PollEngine::PollEngine() std::cout << "ERROR: Can't determine maximum number of open sockets: " << strerror(errno) << std::endl; ServerInstance->QuickExit(EXIT_STATUS_SOCKETENGINE); } - - ref = new EventHandler* [GetMaxFds()]; - events = new struct pollfd[GetMaxFds()]; - - memset(events, 0, GetMaxFds() * sizeof(struct pollfd)); - memset(ref, 0, GetMaxFds() * sizeof(EventHandler*)); -} - -PollEngine::~PollEngine() -{ - // No destruction required, either. - delete[] ref; - delete[] events; } static int mask_to_poll(int event_mask) @@ -121,7 +105,13 @@ bool PollEngine::AddFd(EventHandler* eh, int event_mask) return false; } - if (fd_mappings.find(fd) != fd_mappings.end()) + if (static_cast<unsigned int>(fd) < fd_mappings.size() && fd_mappings[fd] != -1) + { + ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "Attempt to add duplicate fd: %d", fd); + return false; + } + + if (!SocketEngine::AddFd(eh)) { ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "Attempt to add duplicate fd: %d", fd); return false; @@ -129,35 +119,30 @@ bool PollEngine::AddFd(EventHandler* eh, int event_mask) unsigned int index = CurrentSetSize; + while (static_cast<unsigned int>(fd) >= fd_mappings.size()) + fd_mappings.resize(fd_mappings.size() * 2, -1); fd_mappings[fd] = index; - ref[index] = eh; + + ResizeDouble(events); events[index].fd = fd; events[index].events = mask_to_poll(event_mask); - ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "New file descriptor: %d (%d; index %d)", fd, events[fd].events, index); + ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "New file descriptor: %d (%d; index %d)", fd, events[index].events, index); SocketEngine::SetEventMask(eh, event_mask); CurrentSetSize++; return true; } -EventHandler* PollEngine::GetRef(int fd) -{ - std::map<int, unsigned int>::iterator it = fd_mappings.find(fd); - if (it == fd_mappings.end()) - return NULL; - return ref[it->second]; -} - void PollEngine::OnSetEvent(EventHandler* eh, int old_mask, int new_mask) { - std::map<int, unsigned int>::iterator it = fd_mappings.find(eh->GetFd()); - if (it == fd_mappings.end()) + int fd = eh->GetFd(); + if (fd < 0 || static_cast<unsigned int>(fd) >= fd_mappings.size() || fd_mappings[fd] == -1) { ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "SetEvents() on unknown fd: %d", eh->GetFd()); return; } - events[it->second].events = mask_to_poll(new_mask); + events[fd_mappings[fd]].events = mask_to_poll(new_mask); } void PollEngine::DelFd(EventHandler* eh) @@ -169,14 +154,13 @@ void PollEngine::DelFd(EventHandler* eh) return; } - std::map<int, unsigned int>::iterator it = fd_mappings.find(fd); - if (it == fd_mappings.end()) + if (static_cast<unsigned int>(fd) >= fd_mappings.size() || fd_mappings[fd] == -1) { ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "DelFd() on unknown fd: %d", fd); return; } - unsigned int index = it->second; + unsigned int index = fd_mappings[fd]; unsigned int last_index = CurrentSetSize - 1; int last_fd = events[last_index].fd; @@ -190,16 +174,15 @@ void PollEngine::DelFd(EventHandler* eh) // move last_fd from last_index into index events[index].fd = last_fd; events[index].events = events[last_index].events; - - ref[index] = ref[last_index]; } // Now remove all data for the last fd we got into out list. // Above code made sure this always is right - fd_mappings.erase(it); + fd_mappings[fd] = -1; events[last_index].fd = 0; events[last_index].events = 0; - ref[last_index] = NULL; + + SocketEngine::DelFd(eh); CurrentSetSize--; @@ -209,58 +192,55 @@ void PollEngine::DelFd(EventHandler* eh) int PollEngine::DispatchEvents() { - int i = poll(events, CurrentSetSize, 1000); + int i = poll(&events[0], CurrentSetSize, 1000); int index; socklen_t codesize = sizeof(int); int errcode; int processed = 0; ServerInstance->UpdateTime(); - if (i > 0) + for (index = 0; index < CurrentSetSize && processed < i; index++) { - for (index = 0; index < CurrentSetSize && processed != i; index++) - { - if (events[index].revents) - processed++; - EventHandler* eh = ref[index]; - if (!eh) - continue; + struct pollfd& pfd = events[index]; - if (events[index].revents & POLLHUP) - { - eh->HandleEvent(EVENT_ERROR, 0); - continue; - } + if (pfd.revents) + processed++; + + EventHandler* eh = GetRef(pfd.fd); + if (!eh) + continue; - if (events[index].revents & POLLERR) - { - // Get fd - int fd = events[index].fd; + if (pfd.revents & POLLHUP) + { + eh->HandleEvent(EVENT_ERROR, 0); + continue; + } - // Get error number - if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &errcode, &codesize) < 0) - errcode = errno; - eh->HandleEvent(EVENT_ERROR, errcode); + if (pfd.revents & POLLERR) + { + // Get error number + if (getsockopt(pfd.fd, SOL_SOCKET, SO_ERROR, &errcode, &codesize) < 0) + errcode = errno; + eh->HandleEvent(EVENT_ERROR, errcode); + continue; + } + + if (pfd.revents & POLLIN) + { + SetEventMask(eh, eh->GetEventMask() & ~FD_READ_WILL_BLOCK); + eh->HandleEvent(EVENT_READ); + if (eh != GetRef(pfd.fd)) + // whoops, deleted out from under us continue; - } - - if (events[index].revents & POLLIN) - { - SetEventMask(eh, eh->GetEventMask() & ~FD_READ_WILL_BLOCK); - eh->HandleEvent(EVENT_READ); - if (eh != ref[index]) - // whoops, deleted out from under us - continue; - } - - if (events[index].revents & POLLOUT) - { - int mask = eh->GetEventMask(); - mask &= ~(FD_WRITE_WILL_BLOCK | FD_WANT_SINGLE_WRITE); - SetEventMask(eh, mask); - events[index].events = mask_to_poll(mask); - eh->HandleEvent(EVENT_WRITE); - } + } + + if (pfd.revents & POLLOUT) + { + int mask = eh->GetEventMask(); + mask &= ~(FD_WRITE_WILL_BLOCK | FD_WANT_SINGLE_WRITE); + SetEventMask(eh, mask); + pfd.events = mask_to_poll(mask); + eh->HandleEvent(EVENT_WRITE); } } diff --git a/src/socketengines/socketengine_ports.cpp b/src/socketengines/socketengine_ports.cpp index ba4e8f2d7..936a8f6b9 100644 --- a/src/socketengines/socketengine_ports.cpp +++ b/src/socketengines/socketengine_ports.cpp @@ -42,9 +42,9 @@ class PortsEngine : public SocketEngine { private: - /** These are used by epoll() to hold socket events + /** These are used by ports to hold socket events */ - port_event_t* events; + std::vector<port_event_t> events; int EngineHandle; public: /** Create a new PortsEngine @@ -65,7 +65,7 @@ public: #include <ulimit.h> -PortsEngine::PortsEngine() +PortsEngine::PortsEngine() : events(1) { int max = ulimit(4, 0); if (max > 0) @@ -89,17 +89,11 @@ PortsEngine::PortsEngine() ServerInstance->QuickExit(EXIT_STATUS_SOCKETENGINE); } CurrentSetSize = 0; - - ref = new EventHandler* [GetMaxFds()]; - events = new port_event_t[GetMaxFds()]; - memset(ref, 0, GetMaxFds() * sizeof(EventHandler*)); } PortsEngine::~PortsEngine() { this->Close(EngineHandle); - delete[] ref; - delete[] events; } static int mask_to_events(int event_mask) @@ -118,15 +112,16 @@ bool PortsEngine::AddFd(EventHandler* eh, int event_mask) if ((fd < 0) || (fd > GetMaxFds() - 1)) return false; - if (ref[fd]) + if (!SocketEngine::AddFd(eh)) return false; - ref[fd] = eh; SocketEngine::SetEventMask(eh, event_mask); port_associate(EngineHandle, PORT_SOURCE_FD, fd, mask_to_events(event_mask), eh); ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "New file descriptor: %d", fd); CurrentSetSize++; + ResizeDouble(events); + return true; } @@ -145,7 +140,7 @@ void PortsEngine::DelFd(EventHandler* eh) port_dissociate(EngineHandle, PORT_SOURCE_FD, fd); CurrentSetSize--; - ref[fd] = NULL; + SocketEngine::DelFd(eh); ServerInstance->Logs->Log("SOCKET", LOG_DEBUG, "Remove file descriptor: %d", fd); } @@ -158,7 +153,7 @@ int PortsEngine::DispatchEvents() poll_time.tv_nsec = 0; unsigned int nget = 1; // used to denote a retrieve request. - int ret = port_getn(EngineHandle, this->events, GetMaxFds() - 1, &nget, &poll_time); + int ret = port_getn(EngineHandle, &events[0], events.size(), &nget, &poll_time); ServerInstance->UpdateTime(); // first handle an error condition @@ -170,38 +165,35 @@ int PortsEngine::DispatchEvents() unsigned int i; for (i = 0; i < nget; i++) { - switch (this->events[i].portev_source) + port_event_t& ev = events[i]; + + if (ev.portev_source != PORT_SOURCE_FD) + continue; + + int fd = ev.portev_object; + EventHandler* eh = GetRef(fd); + if (!eh) + continue; + + int mask = eh->GetEventMask(); + if (ev.portev_events & POLLWRNORM) + mask &= ~(FD_WRITE_WILL_BLOCK | FD_WANT_FAST_WRITE | FD_WANT_SINGLE_WRITE); + if (ev.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) + { + ReadEvents++; + eh->HandleEvent(EVENT_READ); + if (eh != GetRef(fd)) + continue; + } + if (ev.portev_events & POLLWRNORM) { - case PORT_SOURCE_FD: - { - int fd = this->events[i].portev_object; - EventHandler* eh = ref[fd]; - if (eh) - { - int mask = eh->GetEventMask(); - if (events[i].portev_events & POLLWRNORM) - mask &= ~(FD_WRITE_WILL_BLOCK | FD_WANT_FAST_WRITE | FD_WANT_SINGLE_WRITE); - if (events[i].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 (events[i].portev_events & POLLRDNORM) - { - ReadEvents++; - eh->HandleEvent(EVENT_READ); - if (eh != ref[fd]) - continue; - } - if (events[i].portev_events & POLLWRNORM) - { - WriteEvents++; - eh->HandleEvent(EVENT_WRITE); - } - } - } - default: - break; + WriteEvents++; + eh->HandleEvent(EVENT_WRITE); } } diff --git a/src/socketengines/socketengine_select.cpp b/src/socketengines/socketengine_select.cpp index f995b5472..39cfb7789 100644 --- a/src/socketengines/socketengine_select.cpp +++ b/src/socketengines/socketengine_select.cpp @@ -1,6 +1,7 @@ /* * InspIRCd -- Internet Relay Chat Daemon * + * Copyright (C) 2014 Adam <Adam@anope.org> * Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org> * Copyright (C) 2007-2008 Craig Edwards <craigedwards@brainbox.cc> * @@ -36,9 +37,6 @@ public: /** Create a new SelectEngine */ SelectEngine(); - /** Delete a SelectEngine - */ - virtual ~SelectEngine(); virtual bool AddFd(EventHandler* eh, int event_mask); virtual void DelFd(EventHandler* eh); void OnSetEvent(EventHandler* eh, int, int); @@ -51,31 +49,21 @@ SelectEngine::SelectEngine() MAX_DESCRIPTORS = FD_SETSIZE; CurrentSetSize = 0; - ref = new EventHandler* [GetMaxFds()]; - memset(ref, 0, GetMaxFds() * sizeof(EventHandler*)); - FD_ZERO(&ReadSet); FD_ZERO(&WriteSet); FD_ZERO(&ErrSet); MaxFD = 0; } -SelectEngine::~SelectEngine() -{ - delete[] ref; -} - bool SelectEngine::AddFd(EventHandler* eh, int event_mask) { int fd = eh->GetFd(); if ((fd < 0) || (fd > GetMaxFds() - 1)) return false; - if (ref[fd]) + if (!SocketEngine::AddFd(eh)) return false; - ref[fd] = eh; - SocketEngine::SetEventMask(eh, event_mask); OnSetEvent(eh, 0, event_mask); FD_SET(fd, &ErrSet); @@ -96,7 +84,7 @@ void SelectEngine::DelFd(EventHandler* eh) return; CurrentSetSize--; - ref[fd] = NULL; + SocketEngine::DelFd(eh); FD_CLR(fd, &ReadSet); FD_CLR(fd, &WriteSet); @@ -149,7 +137,7 @@ int SelectEngine::DispatchEvents() { --j; - EventHandler* ev = ref[i]; + EventHandler* ev = GetRef(i); if (!ev) continue; @@ -171,7 +159,7 @@ int SelectEngine::DispatchEvents() ReadEvents++; SetEventMask(ev, ev->GetEventMask() & ~FD_READ_WILL_BLOCK); ev->HandleEvent(EVENT_READ); - if (ev != ref[i]) + if (ev != GetRef(i)) continue; } if (has_write) |