Poller描述符监控类实现(模块四)

目录

类功能

类设计

类实现

编译


类功能

Poller描述符监控类实现(模块四)_第1张图片

Poller描述符监控类实现(模块四)_第2张图片

Poller描述符监控类实现(模块四)_第3张图片

类设计

//Poller描述符监控类
#define MAX_EPOLLEVENTS
class Poller{
    private:
        int _epfd;
        struct epoll_event _evs[MAX_EPOLLEVENTS];
        std::unordered_map _channels;
    private:
        // 对epoll的直接操作
        void Update(Channel *channel, int op);
        bool HasChannel(Channel *Channel);
    public:
        Poller();
        // 添加或修改监控事件
        void UpdateEvent(Channel *channel);
        // 移除监控
        void RemoveEvent(Channel *channel);
        // 开始监控, 返回活跃连接
        void Poll(std::vector *active);
};

类实现

// Poller描述符监控类
#define MAX_EPOLLEVENTS 1024
class Poller
{
private:
    int _epfd;
    struct epoll_event _evs[MAX_EPOLLEVENTS];
    std::unordered_map _channels;

private:
    // 对epoll的直接操作
    void Update(Channel *channel, int op)
    {
        // int epoll_ctl(int epfd, int op, int fd, struct epoll_event *ev)
        int fd = channel->Fd();
        struct epoll_event ev;
        ev.data.fd = fd;
        ev.events = channel->Events();
        int ret = epoll_ctl(_epfd, op, fd, &ev);
    }
    // 判断一个Channel 是否已经添加了事件监控
    bool HasChannel(Channel *channel)
    {
        auto it = _channels.find(channel->Fd());
        if (it == _channels.end())
        {
            return false;
        }
        return true;
    }

public:
    Poller()
    {
        _epfd = epoll_create(MAX_EPOLLEVENTS); // 这个值大于0就行了,无用处
        if (_epfd < 0)
        {
            ERR_LOG("EPOLL CREATE FAILED!");
            abort(); // 退出程序
        }
    }
    // 添加或修改监控事件
    void UpdateEvent(Channel *channel)
    {
        bool ret = HasChannel(channel);
        if (ret == false)
        {
            // 不存在则添加
            _channels.insert(std::make_pair(channel->Fd(), channel));
            return Update(channel, EPOLL_CTL_ADD);
        }
        return Update(channel, EPOLL_CTL_MOD);
    }
    // 移除监控
    void RemoveEvent(Channel *channel)
    {
        auto it = _channels.find(channel->Fd());
        if (it != _channels.end())
        {
            _channels.erase(it);
        }
        Update(channel, EPOLL_CTL_DEL);
    }
    // 开始监控, 返回活跃连接
    void Poll(std::vector *active)
    {
        // int epoll_wait(int epfd, struct epoll_event *evs, int maxevents, int timeout);
        int nfds = epoll_wait(_epfd, _evs, MAX_EPOLLEVENTS, -1); // -1阻塞监控
        if (nfds < 0)
        {
            if (errno == EINTR) // 信号打断
            {
                return;
            }
            ERR_LOG("EPOLL WAIT ERROR:%s\n", strerror(errno));
            abort();
        }
        for (int i = 0; i < nfds; i++) // 添加活跃信息
        {
            auto it = _channels.find(_evs[i].data.fd); // 没找到就说明不在我们的管理之下,这是不正常的
            assert(it != _channels.end());
            it->second->SetREvents(_evs[i].events); // 设置实际就绪的事件
            active->push_back(it->second);
        }
        return;
    }
};

编译

Poller描述符监控类实现(模块四)_第4张图片

语法编译目前没问题,Poller模块与Channel模块整合在下一节介绍

你可能感兴趣的:(mudo,服务器,c++)