头文件duye_epoll.h
/***********************************************************************************
**
* @copyright (c) 2010-2019, Technology Co., LTD. All Right Reserved.
*
************************************************************************************/
/**
* @file duye_epoll.h
* @version
* @brief
* @author
* @date 2013-03-29
* @note
*
* 1. 2013-03-29 Created this file
*/
#pragma once
#include <sys/epoll.h>
#include <stdio.h>
#include <list>
#include <duye_sys.h>
#include <duye_type.h>
namespace duye {
class EpollEvent {
public:
EpollEvent() : m_fd(-1), m_event(0){}
EpollEvent(const int32 fd, const uint32 event) : m_fd(fd), m_event(event) {}
~EpollEvent() {}
/**
* @brief get/set fd
* @return fd
*/
int32 fd() const { return m_fd; }
/**
* @brief get/set events
* @return events
*/
uint32 event() const { return m_event; }
/**
* @brief is received data, for network event
* @return true/false
*/
bool isRecv() { return m_event & EPOLLIN; }
bool isRecv() const { return m_event & EPOLLIN; }
/**
* @brief is sent data, for network event
* @return true/false
*/
bool isSend() { return m_event & EPOLLOUT; }
bool isSend() const { return m_event & EPOLLOUT; }
/**
* @brief is sent data, for network event
* @return true/false
*/
bool isClosed() { return (m_event & EPOLLERR) || (m_event & EPOLLHUP); }
bool isClosed() const { return (m_event & EPOLLERR) || (m_event & EPOLLHUP); }
/**
* @brief is disconnection, for network event
* @return true/false
*/
bool isDiscon() { return (m_event == EPOLLERR || m_event == EPOLLHUP) ? true : false; }
private:
int32 m_fd;
uint32 m_event;
};
/**
* @brief epoll socket server
*/
class Epoll {
public:
typedef struct epoll_event SysEvent;
typedef std::list<EpollEvent> EventList;
public:
Epoll();
~Epoll();
/**
* @brief open epoll
* @param [in] maxEvent : the number of the max events
* @return true/false
*/
bool open(const uint32 maxEvents = 1024);
/**
* @brief close epoll
* @return true/false
*/
bool close();
/**
* @brief add fd
* @param [in] fd : fd
* @param [in] epollMode : epoll events(EPOLLIN, EPOLLOUT, EPOLLPRI, EPOLLERR,
* EPOLLHUP, EPOLLET, EPOLLONESHOT), default is EPOLLIN | EPOLLOUT
* @return true/false
*/
bool addfd(const int32 fd, const uint32 epollMode = EPOLLIN | EPOLLOUT);
/**
* @brief modify fd
* @param [in] fd : fd
* @param [in] epollMode : epoll events(EPOLLIN, EPOLLOUT, EPOLLPRI, EPOLLERR,
* EPOLLHUP, EPOLLET, EPOLLONESHOT), default is EPOLLIN | EPOLLOUT
* @return true/false
*/
bool modfd(const int32 fd, const uint32 epollMode = EPOLLIN | EPOLLOUT);
/**
* @brief delete fd
* @param [in] fd : fd
* @return true/false
*/
bool delfd(const int32 fd);
/**
* @brief wait event
* @param [out] eventList : return event
* @param [in] timeout : wait time out, default is -1, indicate block, millisecond
* @return true/false
*/
bool wait(Epoll::EventList& eventList, const uint32 timeout = -1);
/**
* @brief get last error string
* @return error string
* @note
*/
uint8* error();
private:
// create epoll
bool create();
private:
int32 m_epollfd;
uint32 m_maxEvents;
SysEvent* m_sysEvents;
Error m_error;
};
}
cpp文件duye_epoll.h
/************************************************************************************
**
* @copyright (c) 2013-2100, Technology Co., LTD. All Right Reserved.
*
*************************************************************************************/
/**
* @file duye_epoll.cpp
* @version
* @brief
* @author
* @date 2013-03-29
* @note
*
* 1. 2013-03-29 Created this file
*/
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <duye_sys.h>
#include <duye_epoll.h>
namespace duye {
static const int8* DUYE_LOG_PREFIX = "duye.system.epoll";
Epoll::Epoll() : m_epollfd(-1)
, m_maxEvents(0)
, m_sysEvents(NULL) {
m_error.setPrefix(DUYE_LOG_PREFIX);
}
Epoll::~Epoll() {
close();
}
bool Epoll::open(const uint32 maxEvents) {
close();
m_maxEvents = maxEvents;
m_epollfd = epoll_create(m_maxEvents);
if (m_epollfd == -1) {
ERROR_DUYE_LOG("%s:%d > epoll_create failed \n", __FILE__, __LINE__);
return false;
}
m_sysEvents = (struct epoll_event*)calloc(m_maxEvents, sizeof(struct epoll_event));
if (m_sysEvents == NULL) {
ERROR_DUYE_LOG("%s:%d > calloc return NULL \n", __FILE__, __LINE__);
return false;
}
return true;
}
bool Epoll::close() {
m_maxEvents = 0;
if (m_epollfd != -1) {
::close(m_epollfd);
m_epollfd = -1;
}
if (m_sysEvents != NULL) {
free(m_sysEvents);
m_sysEvents = NULL;
}
return true;
}
bool Epoll::addfd(const int32 fd, const uint32 epollMode) {
if (m_epollfd == -1) {
ERROR_DUYE_LOG("%s:%d > m_epollfd == -1", __FILE__, __LINE__);
return false;
}
struct epoll_event epollEvent;
bzero(&epollEvent, sizeof(struct epoll_event));
epollEvent.data.fd = fd;
epollEvent.events = epollMode;
int32 ret = epoll_ctl(m_epollfd, EPOLL_CTL_ADD, fd, &epollEvent);
if (ret != 0) {
ERROR_DUYE_LOG("[%s:%d] epoll_ctl() return = %d", __FILE__, __LINE__, ret);
return false;
}
return true;
}
bool Epoll::modfd(const int32 fd, const uint32 epollMode) {
if (m_epollfd == -1) {
ERROR_DUYE_LOG("[%s:%d] m_epollfd == -1", __FILE__, __LINE__);
return false;
}
struct epoll_event epollEvent;
bzero(&epollEvent, sizeof(struct epoll_event));
epollEvent.data.fd = fd;
epollEvent.events = epollMode;
return epoll_ctl(m_epollfd, EPOLL_CTL_MOD, fd, &epollEvent) == 0 ? true : false;
}
bool Epoll::delfd(const int32 fd) {
if (m_epollfd == -1) {
ERROR_DUYE_LOG("[%s:%d] m_epollfd == -1", __FILE__, __LINE__);
return false;
}
return epoll_ctl(m_epollfd, EPOLL_CTL_DEL, fd, NULL) == 0 ? true : false;
}
bool Epoll::wait(Epoll::EventList& eventList, const uint32 timeout) {
if (m_epollfd == -1) {
ERROR_DUYE_LOG("[%s:%d] m_epollfd == -1", __FILE__, __LINE__);
return false;
}
int32 event_count = epoll_wait(m_epollfd, m_sysEvents, m_maxEvents, timeout);
if (event_count <= 0) {
return false;
}
for (uint32 i = 0; i < (uint32)event_count; i++) {
eventList.push_back(EpollEvent(m_sysEvents[i].data.fd, m_sysEvents[i].events));
// if ((m_sysEvents[i].events & EPOLLERR) ||
// (m_sysEvents[i].events & EPOLLHUP)) {
// ERROR_DUYE_LOG("[%s:%d] epoll error, close fd \n", __FILE__, __LINE__);
// delfd(m_sysEvents[i].data.fd);
// eventList.push_back(EpollEvent(m_sysEvents[i].data.fd, ERROR_FD));
// continue;
// } else if (m_sysEvents[i].events & EPOLLIN) {
// eventList.push_back(EpollEvent(m_sysEvents[i].data.fd, RECV_FD));
// } else if (m_sysEvents[i].events & EPOLLOUT) {
// eventList.push_back(EpollEvent(m_sysEvents[i].data.fd, SEND_FD));
// } else {
// eventList.push_back(EpollEvent(m_sysEvents[i].data.fd, m_sysEvents[i].events));
// }
}
return true;
}
uint8* Epoll::error() {
return m_error.error;
}
}