]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/socketengines/socketengine_epoll.cpp
Fix noeol on socketengine_select
[user/henk/code/inspircd.git] / src / socketengines / socketengine_epoll.cpp
index 672ff4a7b9d3bb292e85cbbad652b5df5a8d1a23..c1b22ffbad12ce87d56df31855509e05cb9a9ccd 100644 (file)
  * ---------------------------------------------------
  */
 
+#include <vector>
+#include <string>
+#include <map>
 #include "inspircd.h"
 #include "exitcodes.h"
-#include "socketengines/socketengine_epoll.h"
+#include "socketengine.h"
+#include <sys/epoll.h>
 #include <ulimit.h>
+#define EP_DELAY 5
+
+/** A specialisation of the SocketEngine class, designed to use linux 2.6 epoll().
+ */
+class EPollEngine : public SocketEngine
+{
+private:
+       /** These are used by epoll() to hold socket events
+        */
+       struct epoll_event* events;
+       int EngineHandle;
+public:
+       /** Create a new EPollEngine
+        */
+       EPollEngine();
+       /** Delete an EPollEngine
+        */
+       virtual ~EPollEngine();
+       virtual bool AddFd(EventHandler* eh, int event_mask);
+       virtual void OnSetEvent(EventHandler* eh, int old_mask, int new_mask);
+       virtual bool DelFd(EventHandler* eh, bool force = false);
+       virtual int DispatchEvents();
+       virtual std::string GetName();
+};
 
 EPollEngine::EPollEngine()
 {
@@ -58,12 +86,12 @@ EPollEngine::~EPollEngine()
 static int mask_to_epoll(int event_mask)
 {
        int rv = 0;
-       if (event_mask & (FD_WANT_POLL_READ | FD_WANT_POLL_WRITE))
+       if (event_mask & (FD_WANT_POLL_READ | FD_WANT_POLL_WRITE | FD_WANT_SINGLE_WRITE))
        {
                // we need to use standard polling on this FD
                if (event_mask & (FD_WANT_POLL_READ | FD_WANT_FAST_READ))
                        rv |= EPOLLIN;
-               if (event_mask & (FD_WANT_POLL_WRITE | FD_WANT_FAST_WRITE))
+               if (event_mask & (FD_WANT_POLL_WRITE | FD_WANT_FAST_WRITE | FD_WANT_SINGLE_WRITE))
                        rv |= EPOLLOUT;
        }
        else
@@ -182,16 +210,28 @@ int EPollEngine::DispatchEvents()
                        eh->HandleEvent(EVENT_ERROR, errcode);
                        continue;
                }
+               int mask = eh->GetEventMask();
+               if (events[j].events & EPOLLIN)
+                       mask &= ~FD_READ_WILL_BLOCK;
+               if (events[j].events & EPOLLOUT)
+               {
+                       mask &= ~FD_WRITE_WILL_BLOCK;
+                       if (mask & FD_WANT_SINGLE_WRITE)
+                       {
+                               int nm = mask & ~FD_WANT_SINGLE_WRITE;
+                               OnSetEvent(eh, mask, nm);
+                               mask = nm;
+                       }
+               }
+               SetEventMask(eh, mask);
                if (events[j].events & EPOLLIN)
                {
                        ReadEvents++;
-                       SetEventMask(eh, eh->GetEventMask() & ~FD_READ_WILL_BLOCK);
                        eh->HandleEvent(EVENT_READ);
                }
                if (events[j].events & EPOLLOUT)
                {
                        WriteEvents++;
-                       SetEventMask(eh, eh->GetEventMask() & ~FD_WRITE_WILL_BLOCK);
                        eh->HandleEvent(EVENT_WRITE);
                }
        }
@@ -204,3 +244,7 @@ std::string EPollEngine::GetName()
        return "epoll";
 }
 
+SocketEngine* CreateSocketEngine()
+{
+       return new EPollEngine;
+}