Archived
1
0

use epoll

This commit is contained in:
Jeff Becker
2018-05-03 11:47:20 -04:00
parent 6eba2d4653
commit 34fdc0a154
9 changed files with 376 additions and 157 deletions

View File

@@ -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];
};
}

View File

@@ -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();
};
}

View File

@@ -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;
};
}