Linux epoll 实现封装

头文件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;
}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

道知极限编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值