From 56cec38f3e7d3447b40076481c15e6d4a7e278d0 Mon Sep 17 00:00:00 2001 From: brain Date: Fri, 18 Aug 2006 10:07:22 +0000 Subject: Get rid of SocketEngine::Wait and array-copy, change to SocketEngine::DispatchEvents git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@4944 e03df62e-2008-0410-955e-edbf42e46eb7 --- include/socketengine.h | 14 +++++--------- include/socketengine_epoll.h | 2 +- include/socketengine_kqueue.h | 2 +- include/socketengine_select.h | 2 +- src/inspircd.cpp | 25 ++++--------------------- src/socketengine.cpp | 2 +- src/socketengine_epoll.cpp | 11 ++++++----- src/socketengine_kqueue.cpp | 11 ++++++----- src/socketengine_select.cpp | 23 +++++++++++++++++++---- 9 files changed, 44 insertions(+), 48 deletions(-) diff --git a/include/socketengine.h b/include/socketengine.h index fd01b4cf8..1b68f1685 100644 --- a/include/socketengine.h +++ b/include/socketengine.h @@ -216,20 +216,16 @@ public: */ EventHandler* GetRef(int fd); - /** Waits for an event. + /** Waits for events and dispatches them to handlers. * Please note that this doesnt wait long, only - * a couple of milliseconds. It returns a list - * of active EventHandlers in the array fdlist - * which the core will then dispatch events to + * a couple of milliseconds. It returns the number of + * events which occured during this call. + * This method will dispatch events to their handlers * by calling their EventHandler::HandleEvent() * methods with the neccessary EventType value. - * @param fdlist A pointer to a set of EventHandler - * classes. You should ensure that the array you pass - * is at least MAX_DESCRIPTORS in size, to accomodate - * for the maximum number of events which can occur. * @return The number of events which have occured. */ - virtual int Wait(EventHandler** fdlist); + virtual int DispatchEvents(); /** Returns the socket engines name. * This returns the name of the engine for use diff --git a/include/socketengine_epoll.h b/include/socketengine_epoll.h index 04ede734d..8e4d6308f 100644 --- a/include/socketengine_epoll.h +++ b/include/socketengine_epoll.h @@ -49,7 +49,7 @@ public: virtual int GetMaxFds(); virtual int GetRemainingFds(); virtual bool DelFd(EventHandler* eh); - virtual int Wait(EventHandler** fdlist); + virtual int DispatchEvents(); virtual std::string GetName(); }; diff --git a/include/socketengine_kqueue.h b/include/socketengine_kqueue.h index 392843697..1d7becba0 100644 --- a/include/socketengine_kqueue.h +++ b/include/socketengine_kqueue.h @@ -53,7 +53,7 @@ public: virtual int GetMaxFds(); virtual int GetRemainingFds(); virtual bool DelFd(EventHandler* eh); - virtual int Wait(EventHandler** fdlist); + virtual int DispatchEvents(); virtual std::string GetName(); }; diff --git a/include/socketengine_select.h b/include/socketengine_select.h index d4b366b21..37a6fc1b6 100644 --- a/include/socketengine_select.h +++ b/include/socketengine_select.h @@ -51,7 +51,7 @@ public: virtual int GetMaxFds(); virtual int GetRemainingFds(); virtual bool DelFd(EventHandler* eh); - virtual int Wait(EventHandler** fdlist); + virtual int DispatchEvents(); virtual std::string GetName(); }; diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 41e0897b7..e58e8039b 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -663,9 +663,6 @@ bool InspIRCd::LoadModule(const char* filename) void InspIRCd::DoOneIteration(bool process_module_sockets) { - EventHandler* activefds[MAX_DESCRIPTORS]; - unsigned int numberactive; - /* time() seems to be a pretty expensive syscall, so avoid calling it too much. * Once per loop iteration is pleanty. */ @@ -697,29 +694,15 @@ void InspIRCd::DoOneIteration(bool process_module_sockets) Timers->TickMissedTimers(TIME); } } - + /* Call the socket engine to wait on the active * file descriptors. The socket engine has everything's * descriptors in its list... dns, modules, users, * servers... so its nice and easy, just one call. + * This will cause any read or write events to be + * dispatched to their handlers. */ - if (!(numberactive = SE->Wait(activefds))) - return; - - /** - * Now process each of the fd's. For users, we have a fast - * lookup table which can find a user by file descriptor, so - * processing them by fd isnt expensive. If we have a lot of - * listening ports or module sockets though, things could get - * ugly. - */ - this->Log(DEBUG,"There are %d fd's to process.",numberactive); - - for (unsigned int activefd = 0; activefd < numberactive; activefd++) - { - this->Log(DEBUG,"Handle %s event on fd %d",activefds[activefd]->Readable() ? "read" : "write", activefds[activefd]->GetFd()); - activefds[activefd]->HandleEvent(activefds[activefd]->Readable() ? EVENT_READ : EVENT_WRITE); - } + SE->DispatchEvents(); } bool InspIRCd::IsIdent(const char* n) diff --git a/src/socketengine.cpp b/src/socketengine.cpp index 71ae4fe9b..895f21306 100644 --- a/src/socketengine.cpp +++ b/src/socketengine.cpp @@ -83,7 +83,7 @@ int SocketEngine::GetRemainingFds() return 0; } -int SocketEngine::Wait(EventHandler** fdlist) +int SocketEngine::DispatchEvents() { return 0; } diff --git a/src/socketengine_epoll.cpp b/src/socketengine_epoll.cpp index 9057c6d65..be46451fa 100644 --- a/src/socketengine_epoll.cpp +++ b/src/socketengine_epoll.cpp @@ -111,15 +111,16 @@ int EPollEngine::GetRemainingFds() return MAX_DESCRIPTORS - CurrentSetSize; } -int EPollEngine::Wait(EventHandler** fdlist) +int EPollEngine::DispatchEvents() { - int result = 0; - int i = epoll_wait(EngineHandle, events, MAX_DESCRIPTORS, 50); for (int j = 0; j < i; j++) - fdlist[result++] = ref[events[j].data.fd]; + { + ServerInstance->Log(DEBUG,"Handle %s event on fd %d",ref[events[j].data.fd]->Readable() ? "read" : "write", ref[events[j].data.fd]->GetFd()); + ref[events[j].data.fd]->HandleEvent(ref[events[j].data.fd]->Readable() ? EVENT_READ : EVENT_WRITE); + } - return result; + return i; } std::string EPollEngine::GetName() diff --git a/src/socketengine_kqueue.cpp b/src/socketengine_kqueue.cpp index 14864da79..f10e6350e 100644 --- a/src/socketengine_kqueue.cpp +++ b/src/socketengine_kqueue.cpp @@ -112,17 +112,18 @@ int KQueueEngine::GetRemainingFds() return MAX_DESCRIPTORS - CurrentSetSize; } -int KQueueEngine::Wait(EventHandler** fdlist) +int KQueueEngine::DispatchEvents() { - int result = 0; - ts.tv_nsec = 5000L; ts.tv_sec = 0; int i = kevent(EngineHandle, NULL, 0, &ke_list[0], MAX_DESCRIPTORS, &ts); for (int j = 0; j < i; j++) - fdlist[result++] = ref[ke_list[j].ident]; + { + ServerInstance->Log(DEBUG,"Handle %s event on fd %d",ref[ke_list[j].ident]->Readable() ? "read" : "write", ref[ke_list[j].ident]->GetFd()); + ref[ke_list[j].ident]->HandleEvent(ref[ke_list[j].ident]->Readable() ? EVENT_READ : EVENT_WRITE); + } - return result; + return i; } std::string KQueueEngine::GetName() diff --git a/src/socketengine_select.cpp b/src/socketengine_select.cpp index ec242b76d..e0e47b8eb 100644 --- a/src/socketengine_select.cpp +++ b/src/socketengine_select.cpp @@ -92,14 +92,16 @@ int SelectEngine::GetRemainingFds() return FD_SETSIZE - CurrentSetSize; } -int SelectEngine::Wait(EventHandler** fdlist) +int SelectEngine::DispatchEvents() { int result = 0; + timeval tval; + int sresult = 0; + EventHandler* ev[MAX_DESCRIPTOR]; FD_ZERO(&wfdset); FD_ZERO(&rfdset); - timeval tval; - int sresult; + for (std::map::iterator a = fds.begin(); a != fds.end(); a++) { if (ref[a->second]->Readable()) @@ -120,10 +122,23 @@ int SelectEngine::Wait(EventHandler** fdlist) for (std::map::iterator a = fds.begin(); a != fds.end(); a++) { if ((FD_ISSET (a->second, &rfdset)) || (FD_ISSET (a->second, &wfdset))) - fdlist[result++] = ref[a->second]; + { + ev[result++] = ref[a->second]; + } } } + /** An event handler may remove its own descriptor from the list, therefore it is not + * safe to directly iterate over the list and dispatch events there with STL iterators. + * Thats a shame because it makes this code slower and more resource intensive, but maybe + * the user should stop using select(), as select() smells anyway. + */ + for (int i = 0; i < result; i++) + { + ServerInstance->Log(DEBUG,"Handle %s event on fd %d",ev[i]->Readable() ? "read" : "write", ev[i]->GetFd()); + ev[i]->HandleEvent(ev[i]->Readable() ? EVENT_READ : EVENT_WRITE); + } + return result; } -- cgit v1.2.3