Channel类的数据成员
public: //两个可调用对象的类型别名 typedef std::function<void()> EventCallback; typedef std::function<void(Timestamp)> ReadEventCallback; private: //事件:POLLIN、POLLPRI、POLLOUT static const int kNoneEvent; static const int kReadEvent; static const int kWriteEvent; //这个Channel所属于哪个EventLoop对象指针 EventLoop* loop_; //关注这个文件描述符 const int fd_; //这个Channel注册关注了哪些事件:POLLIN、POLLPRI、POLLOUT等的组合 int events_; //当前激活的事件:POLLIN、POLLPRI、POLLOUT等的组合 int revents_; // it's the received event types of epoll or poll //在子类PollPoller类中:index代表轮询的fd数组的下标 //在子类EpollPoller类中:index代表三种状态:kNew(新的fd未被添加到epoll关注列表内)、kAdded(已添加)、kDeleted(已删除) int index_; // used by Poller. //???? bool logHup_; //???? std::weak_ptr<void> tie_; //???? bool tied_; //正在执行Channel的回调函数 bool eventHandling_; //Channel的文件描述符fd,或者说是否被添加进关注列表 bool addedToLoop_; //fd所属的Channel有事件到来调用的回调函数,由更上一层赋值 ReadEventCallback readCallback_; EventCallback writeCallback_; EventCallback closeCallback_; EventCallback errorCallback_;
Channel类的作用
1.存储了当fd_有事件到来以后需要回调上层的函数:readCallback_、writeCallback_、closeCallback_、errorCallback_
2.提升了某个对象的生命期??
3.将fd_(或者说Channel)添加到EventLoop的poll的关注列表里面。
一、将fd_(或者说Channel)添加(/删除/修改)到EventLoop的poll的关注列表里面
void enableReading() { events_ |= kReadEvent; update(); } void disableReading() { events_ &= ~kReadEvent; update(); } void enableWriting() { events_ |= kWriteEvent; update(); } void disableWriting() { events_ &= ~kWriteEvent; update(); } void disableAll() { events_ = kNoneEvent; update(); } bool isWriting() const { return events_ & kWriteEvent; } bool isReading() const { return events_ & kReadEvent; }
void Channel::update() { addedToLoop_ = true; loop_->updateChannel(this); }
最终其实调用的是Channel对象所属的EventLoop对象的updateChannel()函数。
流程图:
Channel对象并不拥有这个文件描述符fd,不会在析构对象的时候关闭文件描述符fd。
Channel会把不同的IO事件(监听可读或者可写)分发为不同的回调。
二、当fd_有事件到来以后回调上层的函数