use epoll
This commit is contained in:
@@ -1,22 +1,53 @@
|
||||
#ifndef NNTPCHAN_EVENT_HPP
|
||||
#define NNTPCHAN_EVENT_HPP
|
||||
#include <uv.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <sys/socket.h>
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
namespace ev
|
||||
{
|
||||
struct io
|
||||
{
|
||||
int fd;
|
||||
|
||||
io(int f) : fd(f) {};
|
||||
virtual ~io() {};
|
||||
virtual bool readable() const { return true; };
|
||||
virtual int read(char * buf, size_t sz) = 0;
|
||||
virtual bool writeable() const { return true; };
|
||||
virtual int write() = 0;
|
||||
virtual bool keepalive() = 0;
|
||||
virtual void close()
|
||||
{
|
||||
if(fd!=-1)
|
||||
{
|
||||
::close(fd);
|
||||
}
|
||||
};
|
||||
virtual bool acceptable() const { return false; };
|
||||
virtual int accept() { return -1; };
|
||||
};
|
||||
}
|
||||
|
||||
class Mainloop
|
||||
{
|
||||
public:
|
||||
Mainloop();
|
||||
~Mainloop();
|
||||
|
||||
operator uv_loop_t *() const { return m_loop; }
|
||||
|
||||
void Run(uv_run_mode mode = UV_RUN_DEFAULT);
|
||||
void Stop();
|
||||
bool BindTCP(const sockaddr * addr, ev::io * handler);
|
||||
bool TrackConn(ev::io * handler);
|
||||
void UntrackConn(ev::io * handler);
|
||||
void Run();
|
||||
|
||||
private:
|
||||
uv_loop_t *m_loop;
|
||||
size_t conns;
|
||||
int epollfd;
|
||||
char readbuf[1024];
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -4,7 +4,6 @@
|
||||
#include "server.hpp"
|
||||
#include <deque>
|
||||
#include <string>
|
||||
#include <uv.h>
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
@@ -12,7 +11,7 @@ namespace nntpchan
|
||||
class NNTPServer : public Server
|
||||
{
|
||||
public:
|
||||
NNTPServer(uv_loop_t *loop);
|
||||
NNTPServer(Mainloop & loop);
|
||||
|
||||
virtual ~NNTPServer();
|
||||
|
||||
@@ -24,9 +23,7 @@ public:
|
||||
|
||||
std::string InstanceName() const;
|
||||
|
||||
void Close();
|
||||
|
||||
virtual IServerConn *CreateConn(uv_stream_t *s);
|
||||
virtual IServerConn *CreateConn(int fd);
|
||||
|
||||
virtual void OnAcceptError(int status);
|
||||
|
||||
@@ -43,13 +40,10 @@ private:
|
||||
class NNTPServerConn : public IServerConn
|
||||
{
|
||||
public:
|
||||
NNTPServerConn(uv_loop_t *l, uv_stream_t *s, Server *parent, IConnHandler *h) : IServerConn(l, s, parent, h) {}
|
||||
NNTPServerConn(int fd, Server *parent, IConnHandler *h) : IServerConn(fd, parent, h) {}
|
||||
|
||||
virtual bool IsTimedOut() { return false; };
|
||||
|
||||
/** @brief send next queued reply */
|
||||
virtual void SendNextReply();
|
||||
|
||||
virtual void Greet();
|
||||
};
|
||||
}
|
||||
|
@@ -3,7 +3,7 @@
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <uv.h>
|
||||
#include <nntpchan/event.hpp>
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
@@ -37,38 +37,45 @@ private:
|
||||
};
|
||||
|
||||
/** server connection handler interface */
|
||||
struct IServerConn
|
||||
struct IServerConn : public ev::io
|
||||
{
|
||||
IServerConn(uv_loop_t *l, uv_stream_t *s, Server *parent, IConnHandler *h);
|
||||
IServerConn(int fd, Server *parent, IConnHandler *h);
|
||||
virtual ~IServerConn();
|
||||
virtual void Close();
|
||||
virtual int read(char * buf, size_t sz);
|
||||
virtual int write();
|
||||
virtual void close();
|
||||
virtual void Greet() = 0;
|
||||
virtual void SendNextReply() = 0;
|
||||
virtual bool IsTimedOut() = 0;
|
||||
void SendString(const std::string &str);
|
||||
virtual bool keepalive() ;
|
||||
Server *Parent() { return m_parent; };
|
||||
IConnHandler *GetHandler() { return m_handler; };
|
||||
uv_loop_t *GetLoop() { return m_loop; };
|
||||
|
||||
private:
|
||||
uv_tcp_t m_conn;
|
||||
uv_loop_t *m_loop;
|
||||
Server *m_parent;
|
||||
IConnHandler *m_handler;
|
||||
std::string m_writeLeftover;
|
||||
};
|
||||
|
||||
class Server
|
||||
class Server : public ev::io
|
||||
{
|
||||
public:
|
||||
Server(uv_loop_t *loop);
|
||||
/** called after socket close, NEVER call directly */
|
||||
virtual ~Server() {}
|
||||
Server(Mainloop & loop);
|
||||
virtual ~Server() {};
|
||||
|
||||
virtual bool acceptable() const { return true; };
|
||||
virtual void close();
|
||||
virtual bool readable() const { return false; };
|
||||
virtual int read(char *,size_t) { return -1; };
|
||||
virtual bool writeable() const { return false; };
|
||||
virtual int write() {return -1; };
|
||||
virtual int accept();
|
||||
virtual bool keepalive() { return true; };
|
||||
|
||||
|
||||
/** create connection handler from open stream */
|
||||
virtual IServerConn *CreateConn(uv_stream_t *s) = 0;
|
||||
/** close all sockets and stop */
|
||||
void Close();
|
||||
virtual IServerConn *CreateConn(int fd) = 0;
|
||||
/** bind to address */
|
||||
void Bind(const std::string &addr);
|
||||
bool Bind(const std::string &addr);
|
||||
|
||||
typedef std::function<void(IServerConn *)> ConnVisitor;
|
||||
|
||||
@@ -79,18 +86,13 @@ public:
|
||||
void RemoveConn(IServerConn *conn);
|
||||
|
||||
protected:
|
||||
uv_loop_t *GetLoop() { return m_loop; }
|
||||
virtual void OnAcceptError(int status) = 0;
|
||||
|
||||
private:
|
||||
operator uv_handle_t *() { return (uv_handle_t *)&m_server; }
|
||||
operator uv_tcp_t *() { return &m_server; }
|
||||
operator uv_stream_t *() { return (uv_stream_t *)&m_server; }
|
||||
|
||||
void OnAccept(uv_stream_t *s, int status);
|
||||
void OnAccept(int fd, int status);
|
||||
Mainloop & m_Loop;
|
||||
std::deque<IServerConn *> m_conns;
|
||||
uv_tcp_t m_server;
|
||||
uv_loop_t *m_loop;
|
||||
};
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user