more kqueue code
This commit is contained in:
parent
54573f3cd9
commit
8bd528aa50
@ -19,7 +19,7 @@ namespace ev
|
||||
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 int write(size_t avail) = 0;
|
||||
virtual bool keepalive() = 0;
|
||||
virtual void close()
|
||||
{
|
||||
|
@ -42,7 +42,7 @@ struct IServerConn : public ev::io
|
||||
IServerConn(int fd, Server *parent, IConnHandler *h);
|
||||
virtual ~IServerConn();
|
||||
virtual int read(char * buf, size_t sz);
|
||||
virtual int write();
|
||||
virtual int write(size_t avail);
|
||||
virtual void close();
|
||||
virtual void Greet() = 0;
|
||||
virtual bool IsTimedOut() = 0;
|
||||
@ -67,7 +67,7 @@ public:
|
||||
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 write(size_t) {return -1; };
|
||||
virtual int accept();
|
||||
virtual bool keepalive() { return true; };
|
||||
|
||||
|
@ -82,97 +82,97 @@ namespace ev
|
||||
idx = 0;
|
||||
while(idx < res)
|
||||
{
|
||||
errno = 0;
|
||||
ev = &evs[idx++];
|
||||
if(ev->data.fd == sfd)
|
||||
{
|
||||
read(sfd, readbuf, sizeof(readbuf));
|
||||
continue;
|
||||
}
|
||||
|
||||
handler = static_cast<ev::io *>(ev->data.ptr);
|
||||
errno = 0;
|
||||
ev = &evs[idx++];
|
||||
if(ev->data.fd == sfd)
|
||||
{
|
||||
read(sfd, readbuf, sizeof(readbuf));
|
||||
continue;
|
||||
}
|
||||
|
||||
handler = static_cast<ev::io *>(ev->data.ptr);
|
||||
|
||||
if(ev->events & EPOLLERR || ev->events & EPOLLHUP)
|
||||
{
|
||||
handler->close();
|
||||
delete handler;
|
||||
continue;
|
||||
}
|
||||
if(ev->events & EPOLLERR || ev->events & EPOLLHUP)
|
||||
{
|
||||
handler->close();
|
||||
delete handler;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (handler->acceptable())
|
||||
{
|
||||
int acceptfd;
|
||||
bool errored = false;
|
||||
while(true)
|
||||
if (handler->acceptable())
|
||||
{
|
||||
acceptfd = handler->accept();
|
||||
if(acceptfd == -1)
|
||||
{
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
int acceptfd;
|
||||
bool errored = false;
|
||||
while(true)
|
||||
{
|
||||
break;
|
||||
}
|
||||
perror("accept()");
|
||||
errored = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(errored)
|
||||
{
|
||||
handler->close();
|
||||
delete handler;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(ev->events & EPOLLIN && handler->readable())
|
||||
{
|
||||
bool errored = false;
|
||||
while(true)
|
||||
{
|
||||
int readed = handler->read(readbuf, sizeof(readbuf));
|
||||
if(readed == -1)
|
||||
{
|
||||
if(errno != EAGAIN)
|
||||
acceptfd = handler->accept();
|
||||
if(acceptfd == -1)
|
||||
{
|
||||
perror("read()");
|
||||
handler->close();
|
||||
delete handler;
|
||||
errored = true;
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
perror("accept()");
|
||||
errored = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(errored)
|
||||
{
|
||||
handler->close();
|
||||
delete handler;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (readed == 0)
|
||||
if(ev->events & EPOLLIN && handler->readable())
|
||||
{
|
||||
bool errored = false;
|
||||
while(true)
|
||||
{
|
||||
int readed = handler->read(readbuf, sizeof(readbuf));
|
||||
if(readed == -1)
|
||||
{
|
||||
if(errno != EAGAIN)
|
||||
{
|
||||
perror("read()");
|
||||
handler->close();
|
||||
delete handler;
|
||||
errored = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (readed == 0)
|
||||
{
|
||||
handler->close();
|
||||
delete handler;
|
||||
errored = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(errored) continue;
|
||||
}
|
||||
if(ev->events & EPOLLOUT && handler->writeable())
|
||||
{
|
||||
int written = handler->write(1024);
|
||||
if(written < 0)
|
||||
{
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
{
|
||||
// blocking
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("write()");
|
||||
handler->close();
|
||||
delete handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!handler->keepalive())
|
||||
{
|
||||
handler->close();
|
||||
delete handler;
|
||||
errored = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(errored) continue;
|
||||
}
|
||||
if(ev->events & EPOLLOUT && handler->writeable())
|
||||
{
|
||||
int written = handler->write();
|
||||
if(written < 0)
|
||||
{
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
{
|
||||
// blocking
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("write()");
|
||||
handler->close();
|
||||
delete handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!handler->keepalive())
|
||||
{
|
||||
handler->close();
|
||||
delete handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
while(res != -1 && conns);
|
||||
|
@ -7,9 +7,13 @@ typedef nntpchan::ev::EpollLoop LoopImpl;
|
||||
#include "kqueue.hpp"
|
||||
typedef nntpchan::ev::KqueueLoop LoopImpl;
|
||||
#else
|
||||
#ifdef __netbsd__
|
||||
typedef nntpchan::ev::KqueueLoop LoopImpl;
|
||||
#else
|
||||
#error "unsupported platform"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace nntpchan
|
||||
{
|
||||
@ -38,14 +42,20 @@ namespace nntpchan
|
||||
{
|
||||
return false;
|
||||
}
|
||||
handler->fd = fd;
|
||||
|
||||
if(bind(fd, addr, slen) == -1)
|
||||
{
|
||||
::close(fd);
|
||||
return false;
|
||||
|
||||
if (listen(fd, 5) == -1)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (listen(fd, 5) == -1)
|
||||
{
|
||||
::close(fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
handler->fd = fd;
|
||||
return TrackConn(handler);
|
||||
}
|
||||
|
||||
|
@ -22,11 +22,6 @@ namespace ev
|
||||
::close(kfd);
|
||||
}
|
||||
|
||||
virtual bool BindTCP(const sockaddr * addr, ev::io * handler)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual bool TrackConn(ev::io * handler)
|
||||
{
|
||||
kevent event;
|
||||
@ -133,7 +128,17 @@ namespace ev
|
||||
}
|
||||
if(ev->filter & EVFILT_WRITE && handler->writable())
|
||||
{
|
||||
int writespace = ev->data;
|
||||
int written = handler->write(writespace);
|
||||
if(written > 0)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
if(!handler->keepalive())
|
||||
{
|
||||
handler->close();
|
||||
delete handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ void Server::OnAccept(int f)
|
||||
{
|
||||
m_conns.push_back(conn);
|
||||
conn->Greet();
|
||||
conn->write();
|
||||
conn->write(1024);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -101,19 +101,20 @@ bool IServerConn::keepalive()
|
||||
return !m_handler->ShouldClose();
|
||||
}
|
||||
|
||||
int IServerConn::write()
|
||||
int IServerConn::write(size_t avail)
|
||||
{
|
||||
auto leftovers = m_writeLeftover.size();
|
||||
ssize_t written;
|
||||
if(leftovers)
|
||||
{
|
||||
if(leftovers > 1024)
|
||||
if(leftovers > avail)
|
||||
{
|
||||
leftovers = 1024;
|
||||
leftovers = avail;
|
||||
}
|
||||
written = ::write(fd, m_writeLeftover.c_str(), leftovers);
|
||||
if(written > 0)
|
||||
{
|
||||
avail -= written;
|
||||
m_writeLeftover = m_writeLeftover.substr(written);
|
||||
}
|
||||
else
|
||||
@ -126,13 +127,23 @@ int IServerConn::write()
|
||||
{
|
||||
if(!m_handler->HasNextLine())
|
||||
{
|
||||
return 0;
|
||||
return written;
|
||||
}
|
||||
auto line = m_handler->GetNextLine();
|
||||
written = ::write(fd, line.c_str(), line.size());
|
||||
if(written > 0)
|
||||
auto line = m_handler->GetNextLine();
|
||||
int wrote;
|
||||
if(line.size() <= avail)
|
||||
{
|
||||
m_writeLeftover = line.substr(written);
|
||||
wrote = ::write(fd, line.c_str(), line.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
auto subline = line.substr(0, avail);
|
||||
wrote = ::write(fd, subline.c_str(), subline.size());
|
||||
}
|
||||
if(wrote > 0)
|
||||
{
|
||||
written += wrote;
|
||||
m_writeLeftover = line.substr(wrote);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -140,8 +151,8 @@ int IServerConn::write()
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
while(written > 0);
|
||||
return 0;
|
||||
while(avail > 0);
|
||||
return written;
|
||||
}
|
||||
|
||||
void IServerConn::close()
|
||||
|
Reference in New Issue
Block a user