* ---------------------------------------------------
*/
+#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()
{
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
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);
}
}
return "epoll";
}
+SocketEngine* CreateSocketEngine()
+{
+ return new EPollEngine;
+}