Acceptor类的函数调用过程

编写一小段代码测试Acceptor类的功能

#include <muduo/net/Acceptor.h>
#include <muduo/net/EventLoop.h>
#include <muduo/net/InetAddress.h>
#include <muduo/net/SocketsOps.h>

#include <stdio.h>

using namespace muduo;
using namespace muduo::net;

void newConnection(int sockfd, const InetAddress& peerAddr)
{
  printf("newConnection(): accepted a new connection from %s\n",
         peerAddr.toIpPort().c_str());
  ::write(sockfd, "How are you?\n", 13);
  sockets::close(sockfd);
}

int main()
{
  printf("main(): pid = %d\n", getpid());

  InetAddress listenAddr(8888);
  EventLoop loop;

  Acceptor acceptor(&loop, listenAddr);
  acceptor.setNewConnectionCallback(newConnection);
  acceptor.listen();

  loop.loop();
}

1.构造一个Acceptor

Acceptor acceptor(&loop, listenAddr)

构造函数创建监听套接字Acceptor::acceptSocket_,创建Channel_::acceptChannel_负责Acceptor::acceptSocket_的I/O事件分发,将Acceptor::handleRead()注册给Channel_::readCallback_,使在Acceptor::acceptSocket_可读时调用Acceptor::handleRead()。

2.注册连接建立时的回调函数

acceptor.setNewConnectionCallback(newConnection)

注册连接建立时的回调函数Acceptor::newConnectionCallback_=newConnection

3.Acceptor::listen()函数的调用过程

acceptor.listen();
void Acceptor::listen()
{
  loop_->assertInLoopThread();
  listenning_ = true;
  acceptSocket_.listen();
  acceptChannel_.enableReading();
}

Acceptor::listen()成员函数执行Socket::listen(),之后调用Channel::enableReading()设置通道Channel关注Acceptor::acceptSocket_可读事件,并调用Channel::update()维护和更新poller中的文件描述符列表PollPoller::pollfds_,用于注册或者更新通道所关注的事件。

函数调用过程如下:
Acceptor::listen()
.>>Socket::listen()
.>>Channel::enableReading()>>Channel::update()>>EventLoop::updateChannel(Channel* channel)>>PollPoller::updateChannel(Channel* channel)

4.运行事件循环函数EventLoop::loop()

loop.loop();
void EventLoop::loop()
{
  assert(!looping_);
  // 断言当前处于创建该对象的线程中
  assertInLoopThread();
  looping_ = true;
  quit_ = false;
  LOG_TRACE << "EventLoop " << this << " start looping";

  //::poll(NULL, 0, 5*1000);
  while (!quit_)
  {

	//清空vector<Channel*>即ChannelList的成员
    activeChannels_.clear();
	//调用poll()获得当前活动事件的channel列表activeChannels,并返回当前时间
    pollReturnTime_ = poller_->poll(kPollTimeMs, &activeChannels_);
    //++iteration_;
    if (Logger::logLevel() <= Logger::TRACE)
    {
      printActiveChannels();
    }
    // TODO sort channel by priority
    eventHandling_ = true;
	//依次调用activeChannels_中每个channel的handleEvent()函数
    for (ChannelList::iterator it = activeChannels_.begin();
        it != activeChannels_.end(); ++it)
    {
      currentActiveChannel_ = *it;
      currentActiveChannel_->handleEvent(pollReturnTime_);
    }
    currentActiveChannel_ = NULL;
    eventHandling_ = false;
	//调用pendingFunctors_里面的所有函数
    doPendingFunctors();
  }

  LOG_TRACE << "EventLoop " << this << " stop looping";
  looping_ = false;
}

EventLoop::loop()调用PollPoller::poll(int timeoutMs, ChannelList* activeChannels),之后调用::poll(&pollfds_.begin(), pollfds_.size(), timeoutMs),获得由PollPoller::updateChannel(Channel* channel)更新后pollfds_中的pollfd::revents_不为空的Channel,再调用PollPoller::fillActiveChannels(int numEvents,ChannelList* activeChannels)填充活动通道的列表EventLoop::activeChannels,并返回当前时间。
然后,在得到EventLoop::activeChannels后,依次调用EventLoop::activeChannels中每个Channel的Channel::handleEvent(Timestamp receiveTime),处理Channel的事件,Channel::handleEvent(Timestamp receiveTime)调用Channel_::readCallback_(receiveTime),而此前将Acceptor::handleRead()注册给了Channel_::readCallback_(receiveTime),因此回调Acceptor::handleRead(),之后调用Acceptor::newConnectionCallback_(int sockfd, const InetAddress& peerAddr),即newConnection(int sockfd, const InetAddress& peerAddr)。
最后,调用EventLoop::doPendingFunctors()把EventLoop::pendingFunctors_里的函数都执行掉。

函数调用过程如下:
EventLoop::loop()
.>>PollPoller::poll(int timeoutMs, ChannelList* activeChannels)>>::poll(&pollfds_.begin(), pollfds_.size(), timeoutMs)>>PollPoller::fillActiveChannels(int numEvents,ChannelList* activeChannels)
.>>Channel::handleEvent(Timestamp receiveTime)>>Channel_::readCallback_(receiveTime)>>Acceptor::handleRead()>>Acceptor::newConnectionCallback_(int sockfd, const InetAddress& peerAddr)>>newConnection(int sockfd, const InetAddress& peerAddr)
.>>EventLoop::doPendingFunctors()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值