通道,封装了可以进行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状态,或是直接调用对应的函数对象。