zoukankan      html  css  js  c++  java
  • handy源码阅读(五):PollerBase类

    使用poll内核函数等待事件发生:

    struct PollerBase: private noncopyable {
      int64_t id_;
      int lastActive_;
      PollerBase(): lastActive_(-1) {
        static std::atomic<int64_t> id(0);
        id_ = ++id;
      }
    
      virtual void addChannel(Channel* ch) = 0;
      virtual void removeChannel(Channel* ch) = 0;
      virtual void updateChannel(Channel* ch) = 0;
      virtual ~PollerBase() {};
    };

    struct PollerEpoll : public PollerBase {
    int fd_;
    std::set<Channel*> liveChannels_;
    struct epoll_event activeEvs_[kMaxEvents];

    PollerEpoll();
    ~PollerEpoll();
    void addChannel(Channel* ch) override;
    void removeChannel(Channel* ch) override;
    void updateChannel(Channel* ch) override;
    void loop_once(int waitMs) override;
    };

     pollerEpoll的实现主要是使用了epoll类函数。

    PollerBase* createPoller() {
      return new PollerEpoll();
    }
    
    PollerEpoll::PollerEpoll() {
      fd_ = epoll_create1(EPOLL_CLOEXEC);  //创建一个epoll文件描述符
    }

    PollerEpoll::~PollerEpoll() {
    while (liveChannels_.size()) {
    (*liveChannels_.begin())->close(); //从poller中移除该通道,关闭通道上的文件描述符并处理该通道上的读事件。
    }
    ::close(fd_); //关闭epoll文件描述符
    }

    void PollerEpoll::addChannel(Channel* ch) {
    struct epoll_event ev;
    memset(&ev, 0, sizeof(ev));
    ev.events = ch->events();
    ev.data.ptr = ch;
    int r = epoll_ctl(fd_, EPOLL_CTL_ADD, ch->fd(), &ev); //将通道内的文件描述符和其关心的事件添加到epoll监听中。
     liveChannels_.insert(ch);
    }

    void PollerEpoll::updateChannel(Channel* ch) {
    struct epoll_event ev;
    memset(&ev, 0, sizeof(ev));
    ev.events = ch->events();
    ev.data.ptr = ch;
    int r = epoll_ctl(fd_, EPOLL_CTL_MOD, ch->fd(), &ev);
    }

    void PollerEpoll::removeChannel(Channel* ch) {
    liveChannels_.erase(ch);
    for (int i = lastActive_; i >= 0; i--) {
    if (ch == activeEvs_[i].data.ptr) {
    activeEvs_[i].data.ptr = NULL;
    break;
    }
    }
    }

    //核心函数
    void PollerEpoll::loop_once(int waitMs) {
    lastActive_ = epoll_wait(fd_, activeEvs_, kMaxEvents, waitMs);
    while (--lastActive_ >= 0) {
    int i = lastActive_;
    Channel* ch = (Channel*)activeEvs_[i].data.ptr;
    int events = activeEvs_[i].events;
    if (ch) {
    if (events & kWriteEvent) {
    ch->handleWrite();
    }
    if (events & (kReadEvent | POLLERR)) {
    ch->handleRead();
    }
    if (!(events & (kReadEvent | kWriteEvent | POLLERR))) {
    fatal("unexpected poller events");
    }
    }
    }
    }
  • 相关阅读:
    艰苦的RAW格式数据恢复之旅
    smarty小技巧之6个标签
    smarty制作留言板的学习和思考
    ul 下的li 添加背景
    php.ini 配置详细选项
    fck与smarty的结合使用
    excel VBA 公式计算结果引用问题
    excel 统计字数公式
    bcp命令详解转载
    CTRL+C和CTRL+V不能使用的解决办法
  • 原文地址:https://www.cnblogs.com/sssblog/p/11612562.html
Copyright © 2011-2022 走看看