• handy源码阅读(四):Channel类


    通道,封装了可以进行epoll的一个fd。

    struct Channel: private noncopyable {
      Channel(EventBase* base, int fd, int events);
      ~Channel();
      EventBase* getBase() { return base_; }
      int fd() { return fd_; }
    
      //通道id
      int64_d id() {  return id_; }
      short events() {  return events_; }
      //关闭通道
      void close();
    
      void onRead(const Task& readcb) {  readcb_ = readcb;  }
      void onWrite(const Task& writecb) {  writecb_ = writecb;  }
      void onRead(Task&& readcb) {  readcb_ = std::move(readcb);  }
      void onWrite(Task&& writecb) {  writecb_ = std::move(writecb);  }
    
      //启动读写监听
      void enableRead(bool enable);
      void enableWrite(bool enable);
      void enableReadWrite(bool readable, bool writeable);
      bool readEnabled();
      bool writeEnabled();
    
      //处理读写事件
      void handleRead() {  readcb_();  }
      void handleWrite() {  writecb_();  }
    
    protected:
      EventBase* base_;
      PollerBase* poller_;
      int fd_;
      short events_;
      int64_t id_;
      std::function<void()> readcb_, writecb_, errorcb_;
    };

    其实现为:

    Channel::Channel(EventBase* base, int fd, int events): base_(base), fd_(fd), events_(events) {
      fatalif(net::setNonBlock(fd_) < 0, "channel set non block failed");
      static atomic<int64_t> id(0);
      id_ = ++id;
      poller_ = base->imp_->poller_;
      poller_->addChannel(this);
    }
    
    Channel::~Channel() {
      close();
    }
    
    void Channle::enableRead(bool enable) {
      if (enable) {
        events_ |= kReadEvent;
      } else {
        events_ &= ~KReadEvent;
      }
      poller_->updateChannel(this);
    }
    
    void Channel::enableWrite(bool enable) {
      if (enable) {
        events_ |= kWriteEvent;
      } else {
        events_ &= ~kWriteEvent;
      }
      poller_->updateChannel(this);
    }
    
    void Channel::enableReadWrite(bool readable, bool writable) {
      if (readable) {
        events_ |= kReadEvent;
      } else {
        events_ &= ~kReadEvent;
      }
      if (writable) {
        events_ |= kWriteEvent;
      } else {
        events_ &= ~kWriteEvent;
      }
      poller_->updateChannel(this);
    }
    
    void Channel::close() {
      if (fd_ >= 0) {
        trace("close channel %ld fd %d", (long)id_, fd_);
        poller_->removeChannel(this);
        ::close(fd_);
        fd_ = -1;
        handleRead();
      }
    }
    
    bool Channel::readEnabled() {
      return events_ & kReadEvent;
    }
    
    bool Channel::writeEnabled() {
      return events_ & kWriteEvent;
    }

     本类的核心在于使用poller类进行添加删除更新channel状态,或是直接调用对应的函数对象。

  • 相关阅读:
    透视表提取不反复记录(1)-出现值
    ORA-38760: This database instance failed to turn on flashback database
    Android蓝牙串口程序开发
    指尖上的电商---(5)schema.xml配置具体解释
    iOS-UIImage imageWithContentsOfFile 和 imageName 对照
    JSON-RPC轻量级远程调用协议介绍及使用
    POJ 2296 Map Labeler(2-sat)
    接口測试-HAR
    [Leetcode]Combination Sum II
    MarkDown、Vim双剑合璧
  • 原文地址:https://www.cnblogs.com/sssblog/p/11586775.html
Copyright © 2020-2023  润新知