本文共 4607 字,大约阅读时间需要 15 分钟。
//事件分发器,每个事件分发器对应一个文件描述符,监听该文件描述符上的所有的事件class Channel : noncopyable{ public: //两种回调函数的形式 typedef std::functionEventCallback; typedef std::function ReadEventCallback; Channel(EventLoop* loop, int fd); ~Channel(); void handleEvent(Timestamp receiveTime); //注册回调函数 void setReadCallback(ReadEventCallback cb) { readCallback_ = std::move(cb); } void setWriteCallback(EventCallback cb) { writeCallback_ = std::move(cb); } void setCloseCallback(EventCallback cb) { closeCallback_ = std::move(cb); } void setErrorCallback(EventCallback cb) { errorCallback_ = std::move(cb); } /// Tie this channel to the owner object managed by shared_ptr, /// prevent the owner object being destroyed in handleEvent. void tie(const std::shared_ptr &); int fd() const { return fd_; } //返回该channel 对应的文件描述符 int events() const { return events_; } //返回对应的监听的事件 //设置对应的到达的事件 void set_revents(int revt) { revents_ = revt; } // used by pollers // int revents() const { return revents_; } bool isNoneEvent() const { return events_ == kNoneEvent; } //注册读事件 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; } // for Poller //所有Channel 会在IO 复用类中用一个vector 管理起来, //index标识 当前的Channel 在那个vector 中的位置 int index() { return index_; } //设置index下标 void set_index(int idx) { index_ = idx; } // for debug string reventsToString() const; string eventsToString() const; void doNotLogHup() { logHup_ = false; } EventLoop* ownerLoop() { return loop_; } void remove(); private: static string eventsToString(int fd, int ev); void update(); void handleEventWithGuard(Timestamp receiveTime); static const int kNoneEvent; //没有事件 static const int kReadEvent; //读事件 static const int kWriteEvent; //写事件 //事件循环loop EventLoop* loop_; //文件描述符 const int fd_; //监听的事件 int events_; //就绪的事件 int revents_; // it's the received event types of epoll or poll //当前文件描述符在 文件描述符数组中的位置 int index_; // used by Poller. bool logHup_; std::weak_ptr tie_; bool tied_; bool eventHandling_; bool addedToLoop_; //注册的回调函数 ReadEventCallback readCallback_; EventCallback writeCallback_; EventCallback closeCallback_; EventCallback errorCallback_;};
//构造的时候传入一个事件循环器和一个文件描述符。Channel::Channel(EventLoop* loop, int fd__) //事件循环 : loop_(loop), fd_(fd__), //监听的事件 events_(0), //就绪的事件 revents_(0), index_(-1), logHup_(true), tied_(false), //事件正在处理 eventHandling_(false), //正在循环监听中 addedToLoop_(false){ }Channel::~Channel(){ assert(!eventHandling_); assert(!addedToLoop_); if (loop_->isInLoopThread()) { assert(!loop_->hasChannel(this)); }}
void Channel::update(){ addedToLoop_ = true; //调用事件循环的update 函数 //将该Channle 添加到事件循环中去 //在事件循环中 更新当前Channel loop_->updateChannel(this);}void Channel::remove(){ assert(isNoneEvent()); addedToLoop_ = false; //从事件循环中删除当前的Channel loop_->removeChannel(this);}
void Channel::handleEvent(Timestamp receiveTime){ //采用智能指针管理 std::shared_ptrguard; if (tied_) { guard = tie_.lock(); if (guard) { handleEventWithGuard(receiveTime); } } else { handleEventWithGuard(receiveTime); }}//具体处理到达的事件,通过回调函数进行事件的分发void Channel::handleEventWithGuard(Timestamp receiveTime){ eventHandling_ = true; //写入日志 LOG_TRACE << reventsToString(); //对具体的事件进行处理 if ((revents_ & POLLHUP) && !(revents_ & POLLIN)) { if (logHup_) { LOG_WARN << "fd = " << fd_ << " Channel::handle_event() POLLHUP"; } if (closeCallback_) closeCallback_(); } if (revents_ & POLLNVAL) { LOG_WARN << "fd = " << fd_ << " Channel::handle_event() POLLNVAL"; } if (revents_ & (POLLERR | POLLNVAL)) { if (errorCallback_) errorCallback_(); } if (revents_ & (POLLIN | POLLPRI | POLLRDHUP)) { if (readCallback_) readCallback_(receiveTime); } if (revents_ & POLLOUT) { if (writeCallback_) writeCallback_(); } eventHandling_ = false;}
转载地址:http://janwi.baihongyu.com/