muduo库分析——net篇(1)EventLoop

类图:


可以看出大概的关系

Channel负责注册删除和响应的IO事件,具有IO当前状态,持有相关的回调函数

EventLoop具有事件循环能力,从Poller中不停的读取IO事件,反馈到Channel上,执行Channel的回调函数

Poller持有Channel的map结构,形式为<int fd,Channel*>,其派生类会新增相关文件描述符集合(用于从系统调用中读取相关IO事件)



EventLoop.cpp

  wakeupChannel_->setReadCallback(
      boost::bind(&EventLoop::handleRead, this));
  // we are always reading the wakeupfd
  wakeupChannel_->enableReading();

在构造函数中进行IO事件注册,wakeupChannel用于线程唤醒,当其他线程要关闭当前线程Loop时,调用quit函数,使用wakeupChannel发送数据,阻塞在poller_->poll(kPollTimeMs, &activeChannels_);时候就会获得返回并执行下去,退出while循环

while (!quit_)
  {
    activeChannels_.clear();	//清理活跃中的IO通道
    pollReturnTime_ = poller_->poll(kPollTimeMs, &activeChannels_);	//等待Poller将活跃的IO通道传送过来
    ++iteration_;
    if (Logger::logLevel() <= Logger::TRACE)
    {
      printActiveChannels();	//输出通道
    }
    // TODO sort channel by priority
    eventHandling_ = true;	//处理事件状态
    for (ChannelList::iterator it = activeChannels_.begin();	//遍历每个IO通道处理相关事件
        it != activeChannels_.end(); ++it)
    {
      currentActiveChannel_ = *it;
      currentActiveChannel_->handleEvent(pollReturnTime_);
    }
    currentActiveChannel_ = NULL;
    eventHandling_ = false;
    doPendingFunctors();
  }
void EventLoop::updateChannel(Channel* channel)	//更新Poller中Channel对应文件描述符状态
{
  assert(channel->ownerLoop() == this);
  assertInLoopThread();
  poller_->updateChannel(channel);
}

Channel.h和Channel.cpp

  EventLoop* loop_;	//持有事件循环指针
  const int  fd_;	//持有文件描述符ID
  int        events_;	//感兴趣的事件
  int        revents_; // it's the received event types of epoll or poll 获得的事件反馈
  int        index_; // used by Poller.	EPoller中代表当前IO活动状态,Poller中代表当前IO所在Poller文件描述符数组的下标位置
  bool       logHup_;

  boost::weak_ptr<void> tie_;	
  bool tied_;
  bool eventHandling_;
  bool addedToLoop_;
  ReadEventCallback readCallback_;	//事件回调函数
  EventCallback writeCallback_;
  EventCallback closeCallback_;
  EventCallback errorCallback_;
void Channel::handleEvent(Timestamp receiveTime)
{
  boost::shared_ptr<void> guard;
  if (tied_)
  {
    guard = tie_.lock();
    if (guard)
    {
      handleEventWithGuard(receiveTime);
    }
  }
  else
  {
    handleEventWithGuard(receiveTime);
  }
}
void Channel::handleEventWithGuard(Timestamp receiveTime)
上面是Channel调用函数的过程,根据revents的状态码执行响应的动作

Poller.h和Poller.cpp

 protected:
  typedef std::map<int, Channel*> ChannelMap;	
  ChannelMap channels_;		// fd,Channel 集合
  virtual Timestamp poll(int timeoutMs, ChannelList* activeChannels) = 0;

  /// Changes the interested I/O events.
  /// Must be called in the loop thread.
  virtual void updateChannel(Channel* channel) = 0;

  /// Remove the channel, when it destructs.
  /// Must be called in the loop thread.
  virtual void removeChannel(Channel* channel) = 0;

  virtual bool hasChannel(Channel* channel) const;

  static Poller* newDefaultPoller(EventLoop* loop);
几个派生类需要实现的函数,EventLoop通过基类指针调用派生类函数



猜你喜欢

转载自blog.csdn.net/renhaopeng/article/details/80230100