#include "event_dispatcher.h"
#include <sys/epoll.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include "io_handler.h"
#include "socket_utils.h"
event_dispatcher::event_dispatcher()
: epoll_fd_(-1),
epoll_ev_capacity_(256),
events_(NULL),
io_capacity_(1024),
io_handlers_(NULL)
{ }
int event_dispatcher::init()
{
if ((this->epoll_fd_ = ::epoll_create(32000)) == -1)
return -1;
this->events_ = new epoll_event[this->epoll_ev_capacity_];
this->io_handlers_ = new io_handler* [this->io_capacity_];
if (!this->events_ || !this->io_handlers_)
return -1;
::memset(this->events_, 0, sizeof(epoll_event) * this->epoll_ev_capacity_);
::memset(this->io_handlers_, 0, sizeof(io_handler*) * this->io_capacity_);
return 0;
}
int event_dispatcher::reg_io_event(io_handler *handler, int ev)
{
if (!handler)
return -1;
while (handler->get_sock_fd() >= this->io_capacity_)
{
int new_io_capacity = this->io_capacity_ * 2;
io_handler **new_io_handlers = new io_handler* [new_io_capacity];
if (!new_io_handlers)
return -1;
::memset(new_io_handlers, 0, sizeof(io_handler*) * new_io_capacity);
::memcpy(new_io_handlers, this->io_handlers_, sizeof(io_handler*) * this->io_capacity_);
delete []this->io_handlers_;
this->io_handlers_ = new_io_handlers;
this->io_capacity_ = new_io_capacity;
}
int new_had_ev = handler->get_had_ev();
int op = new_had_ev ? EPOLL_CTL_MOD : EPOLL_CTL_ADD;
new_had_ev |= ev;
epoll_event ee;
::memset(&ee, 0, sizeof(ee));
ee.events = new_had_ev;
ee.data.fd = handler->get_sock_fd();
int ret = ::epoll_ctl(this->epoll_fd_, op, handler->get_sock_fd(), &ee);
if (ret == 0) //success
{
handler->set_had_ev(new_had_ev);
this->io_handlers_[handler->get_sock_fd()] = handler;
}
return ret;
}
int event_dispatcher::del_io_event(io_handler *handler, int ev)
{
if (!handler || handler->get_sock_fd() < 0 || handler->get_sock_fd()> this->io_capacity_)
return -1;
int new_had_ev = handler->get_had_ev();
if (!(new_had_ev & ev))
return -1;
new_had_ev &= ~ev;
int op = new_had_ev ? EPOLL_CTL_MOD : EPOLL_CTL_DEL;
epoll_event ee;
::memset(&ee, 0, sizeof(ee));
ee.events = new_had_ev;
ee.data.fd = handler->get_sock_fd();
int ret = ::epoll_ctl(this->epoll_fd_, op, handler->get_sock_fd(), &ee);
if (ret == 0) //success
{
handler->set_had_ev(new_had_ev);
}
return ret;
}
void event_dispatcher::run()
{
while (1)
{
int nfds = 0;
do
{
nfds = ::epoll_wait(this->epoll_fd_, this->events_, this->epoll_ev_capacity_, -1);
} while (nfds == -1 && errno == EINTR);
for (int i = 0; i < nfds; ++i)
{
int fd = this->events_[i].data.fd;
int what = this->events_[i].events;
io_handler *handler = this->io_handlers_[fd];
int ret = -1;
if (what &(EPOLLIN | EPOLLHUP | EPOLLERR))
ret = handler->handle_input();
else if (what & EPOLLOUT)
ret = handler->handle_output();
if (ret != 0) //error
{
handler->on_destroy();
delete handler;
}
}
}
}
int event_dispatcher::add_io_listener(io_listener_base *listener, int port)
{
if (!listener)
return -1;
int fd = ::socket(AF_INET, SOCK_STREAM, 0);
socket_utils::set_nonblock(fd);
if (fd == -1)
return -1;
socket_utils::set_reuse_addr(fd);
if (socket_utils::bind(fd, port) == -1)
{
socket_utils::close(fd);
return -1;
}
io_handler *handler = listener;
handler->set_sock_fd(fd);
handler->set_dispatcher(this);
::listen(fd, 1024);
return this->reg_io_event(handler, EPOLLIN);
}
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
webserver.tar.gz (9个子文件)
net
event_dispatcher.h 614B
test.cpp 1KB
io_handler.h 1KB
event_dispatcher.cpp 4KB
tags 5KB
socket_utils.h 383B
socket_utils.cpp 1KB
makefile 279B
io_handler.cpp 1KB
共 9 条
- 1
资源评论
- z9131479142016-07-05值得学习 借鉴了
- JokerYourMemory2021-10-29还可以,不错
- lys079620002014-06-03不能接收浏览器的HTP请求
coderchenjingui
- 粉丝: 110
- 资源: 31
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功