muduo_net库源码分析


  • Channel是selectable IO channel,负责注册与响应IO 事件,它不拥有file descriptor。

  • Channel是Acceptor、Connector、EventLoop、TimerQueue、TcpConnection的成员,生命期由后者控制。




时序图








EventLoop头文件

eventloop.h

  1. // Copyright 2010, Shuo Chen.  All rights reserved.  
  2. // http://code.google.com/p/muduo/  
  3. //  
  4. // Use of this source code is governed by a BSD-style license  
  5. // that can be found in the License file.  
  6.   
  7. // Author: Shuo Chen (chenshuo at chenshuo dot com)  
  8. //  
  9. // This is a public header file, it must only include public header files.  
  10.   
  11. #ifndef MUDUO_NET_EVENTLOOP_H  
  12. #define MUDUO_NET_EVENTLOOP_H  
  13.   
  14. #include   
  15.   
  16. #include   
  17. #include   
  18.   
  19. #include   
  20. #include   
  21. #include   
  22.   
  23. namespace muduo  
  24. {  
  25. namespace net  
  26. {  
  27.   
  28. class Channel; //聚合  
  29. class Poller; //组合  
  30. ///  
  31. /// Reactor, at most one per thread.  
  32. ///  
  33. /// This is an interface class, so don't expose too much details.  
  34. class EventLoop : boost::noncopyable  
  35. {  
  36.  public:  
  37.   EventLoop();  
  38.   ~EventLoop();  // force out-line dtor, for scoped_ptr members.  
  39.   
  40.   ///  
  41.   /// Loops forever.  
  42.   ///  
  43.   /// Must be called in the same thread as creation of the object.  
  44.   ///  
  45.   void loop();  
  46.   
  47.   void quit();  
  48.   
  49.   ///  
  50.   /// Time when poll returns, usually means data arrivial.  
  51.   ///  
  52.   Timestamp pollReturnTime() const { return pollReturnTime_; }  
  53.   
  54.   // internal usage  
  55.   void updateChannel(Channel* channel);     // 在Poller中添加(注册)或者更新通道  
  56.   void removeChannel(Channel* channel);     // 从Poller中移除通道  
  57.   
  58.   /*断言是否在Loop 线程中*/  
  59.   void assertInLoopThread()  
  60.   {  
  61.       //如果不是在LoopThread中,终止程序  
  62.     if (!isInLoopThread())  
  63.     {  
  64.       abortNotInLoopThread();  
  65.     }  
  66.   }  
  67.   //判断是在当前线程是否在LoopThread中  
  68.   bool isInLoopThread() const { return threadId_ == CurrentThread::tid(); }  
  69.   
  70.   static EventLoop* getEventLoopOfCurrentThread();  
  71.   
  72.  private:  
  73.   void abortNotInLoopThread();  
  74.   
  75.   void printActiveChannels() const// DEBUG  
  76.   
  77.   typedef std::vector ChannelList;  
  78.   
  79.   bool looping_; /*是否处于循环状态 atomic */  
  80.   bool quit_; /*是否退出Loop atomic */  
  81.   bool eventHandling_; /*当前是否处于事件处理的状态 atomic */  
  82.   const pid_t threadId_;        // 当前对象所属线程ID  
  83.   Timestamp pollReturnTime_;    //调用poller时候的返回时间  
  84.   boost::scoped_ptr poller_; //poller对象,生命周期由EventLoop控制  
  85.   ChannelList activeChannels_;  // Poller返回的活动通道 ,  
  86.                                 //就是活动状态的socket///typedef std::vector ChannelList;  
  87.   Channel* currentActiveChannel_;   // 当前正在处理的活动通道  
  88. };  
  89.   
  90. }  
  91. }  
  92. #endif  // MUDUO_NET_EVENTLOOP_H  

EventLoop源文件

EventLoop.cc


  1. // Copyright 2010, Shuo Chen.  All rights reserved.  
  2. // http://code.google.com/p/muduo/  
  3. //  
  4. // Use of this source code is governed by a BSD-style license  
  5. // that can be found in the License file.  
  6.   
  7. // Author: Shuo Chen (chenshuo at chenshuo dot com)  
  8.   
  9. #include   
  10.   
  11. #include   
  12. #include   
  13. #include   
  14.   
  15. //#include   
  16.   
  17. using namespace muduo;  
  18. using namespace muduo::net;  
  19.   
  20. namespace  
  21. {  
  22. // 当前线程EventLoop对象指针  
  23. // 线程局部存储  
  24. __thread EventLoop* t_loopInThisThread = 0;  
  25.   
  26. const int kPollTimeMs = 10000;  
  27. }  
  28.   
  29. EventLoop* EventLoop::getEventLoopOfCurrentThread()  
  30. {  
  31.   return t_loopInThisThread;  
  32. }  
  33. /* 
  34. 事件循环,该函数不能夸线程调用 
  35. 只能在创建该对象的线程中调用 
  36. **/  
  37.   
  38. EventLoop::EventLoop()  
  39.   : looping_(false),  
  40.     quit_(false),  
  41.     eventHandling_(false),  
  42.     threadId_(CurrentThread::tid()),  
  43.     poller_(Poller::newDefaultPoller(this)),  
  44.     currentActiveChannel_(NULL)  
  45. {  
  46.   LOG_TRACE << "EventLoop created " << this << " in thread " << threadId_;  
  47.   // 如果当前线程已经创建了EventLoop对象,终止(LOG_FATAL)  
  48.   if (t_loopInThisThread)  
  49.   {  
  50.     LOG_FATAL << "Another EventLoop " << t_loopInThisThread  
  51.               << " exists in this thread " << threadId_;  
  52.   }  
  53.   //如果当前线程没有创建EventLoop对象,则创建EventLoop对象,并且进行绑定  
  54.   else  
  55.   {  
  56.     t_loopInThisThread = this;  
  57.   }  
  58. }  
  59.   
  60. EventLoop::~EventLoop()  
  61. {  
  62.   t_loopInThisThread = NULL;  
  63. }  
  64.  //这是IO线程  
  65. // 事件循环,该函数不能跨线程调用  
  66. // 只能在创建该对象的线程中调用  
  67. void EventLoop::loop()  
  68. {  
  69. //断言是否处于非循环状态  
  70.   assert(!looping_);  
  71.   // 断言当前处于创建该对象的线程中  
  72.   assertInLoopThread();  
  73.   looping_ = true;  
  74.   LOG_TRACE << "EventLoop " << this << " start looping";  
  75.   
  76.   //::poll(NULL, 0, 5*1000);  
  77.   //循环直到退出  
  78.   while (!quit_)  
  79.   {  
  80.   //先清除活动通道  
  81.     activeChannels_.clear();  
  82.     //调用poller_->poll返回活动的通道 &activeChannels_以及poll返回的时间  
  83.     pollReturnTime_ = poller_->poll(kPollTimeMs, &activeChannels_);  
  84.     //++iteration_;  
  85.     //输出 处于活动状态的channel 到日志中  
  86.     if (Logger::logLevel() <= Logger::TRACE)  
  87.     {  
  88.       printActiveChannels();  
  89.     }  
  90.     // TODO sort channel by priority  
  91.     //当前事件处理状态设为true   
  92.     eventHandling_ = true;  
  93.     //循环处理活动通道的事件  
  94.     for (ChannelList::iterator it = activeChannels_.begin();  
  95.         it != activeChannels_.end(); ++it)  
  96.     {  
  97.       currentActiveChannel_ = *it;  
  98.       currentActiveChannel_->handleEvent(pollReturnTime_);  
  99.     }  
  100.     //把当前的活动通道设为 NULL  
  101.     currentActiveChannel_ = NULL;  
  102.     //当前事件处理状态设为false  
  103.     eventHandling_ = false;  
  104.     //doPendingFunctors();  
  105.   }  
  106.   
  107.   LOG_TRACE << "EventLoop " << this << " stop looping";  
  108.   looping_ = false;  
  109. }  
  110.  //该函数可以跨线程调用,这也是防止程序  
  111. void EventLoop::quit()  
  112. {  
  113.   quit_ = true//由于是多线程访问这个变量,那么是否需要保护这个变量??,要的。但是quit_是布尔类型,是一种对布尔类型的变量操作是一种原子操作,所以我们不用显式的进行保护了  
  114.   if (!isInLoopThread())  
  115.   {  
  116.     //wakeup();  
  117.   }  
  118. }  
  119.   
  120. // 用于注册或者更新 channel的事件  
  121. void EventLoop::updateChannel(Channel* channel)  
  122. {  
  123.   // 断言Channel 是否属于当前的EventLoop对象  
  124.   assert(channel->ownerLoop() == this);  
  125.   // 断言EventLoop所属的线程是当前的线程  
  126.   assertInLoopThread();  
  127.   // 更新channel的事件  
  128.   poller_->updateChannel(channel);  
  129. }  
  130.   
  131. void EventLoop::removeChannel(Channel* channel)  
  132. {  
  133.   assert(channel->ownerLoop() == this);  
  134.   assertInLoopThread();  
  135.   if (eventHandling_)  
  136.   {  
  137.     assert(currentActiveChannel_ == channel ||  
  138.         std::find(activeChannels_.begin(), activeChannels_.end(), channel) == activeChannels_.end());  
  139.   }  
  140.   poller_->removeChannel(channel);  
  141. }  
  142.   
  143. //如果不是在LoopThread线程中将终止线程  
  144. void EventLoop::abortNotInLoopThread()  
  145. {  
  146.   LOG_FATAL << "EventLoop::abortNotInLoopThread - EventLoop " << this  
  147.             << " was created in threadId_ = " << threadId_  
  148.             << ", current thread id = " <<  CurrentThread::tid();  
  149. }  
  150.   
  151. /*打印处于活动状态的channel 到日志中*/  
  152. void EventLoop::printActiveChannels() const  
  153. {  
  154.   for (ChannelList::const_iterator it = activeChannels_.begin();  
  155.       it != activeChannels_.end(); ++it)  
  156.   {  
  157.     const Channel* ch = *it;  
  158.     LOG_TRACE << "{" << ch->reventsToString() << "} ";  
  159.   }  
  160. }  



Poller头文件

poller.h

  1. // Copyright 2010, Shuo Chen.  All rights reserved.  
  2. // http://code.google.com/p/muduo/  
  3. //  
  4. // Use of this source code is governed by a BSD-style license  
  5. // that can be found in the License file.  
  6.   
  7. // Author: Shuo Chen (chenshuo at chenshuo dot com)  
  8. //  
  9. // This is an internal header file, you should not include this.  
  10.   
  11. #ifndef MUDUO_NET_POLLER_H  
  12. #define MUDUO_NET_POLLER_H  
  13.   
  14. #include   
  15. #include   
  16.   
  17. #include   
  18. #include   
  19.   
  20. namespace muduo  
  21. {  
  22. namespace net  
  23. {  
  24.   
  25. class Channel;  
  26.   
  27. ///  
  28. /// Base class for IO Multiplexing  
  29. ///  
  30. /// This class doesn't own the Channel objects.  
  31. class Poller : boost::noncopyable  
  32. {  
  33.  public:  
  34.   typedef std::vector ChannelList;  
  35.   
  36.   Poller(EventLoop* loop);  
  37.   virtual ~Poller();  
  38.   
  39.   /// Polls the I/O events.  
  40.   /// Must be called in the loop thread.  
  41.   virtual Timestamp poll(int timeoutMs, ChannelList* activeChannels) = 0;  
  42.   
  43.   /// Changes the interested I/O events.  
  44.   /// Must be called in the loop thread.  
  45.   virtual void updateChannel(Channel* channel) = 0;  
  46.   
  47.   /// Remove the channel, when it destructs.  
  48.   /// Must be called in the loop thread.  
  49.   virtual void removeChannel(Channel* channel) = 0;  
  50.   
  51.   static Poller* newDefaultPoller(EventLoop* loop);  
  52.   
  53.   void assertInLoopThread()  
  54.   {  
  55.     ownerLoop_->assertInLoopThread();  
  56.   }  
  57.   
  58.  private:  
  59.   EventLoop* ownerLoop_;    // Poller所属EventLoop  
  60. };  
  61.   
  62. }  
  63. }  
  64. #endif  // MUDUO_NET_POLLER_H  

Poller源文件

poller.cc

  1. // Copyright 2010, Shuo Chen.  All rights reserved.  
  2. // http://code.google.com/p/muduo/  
  3. //  
  4. // Use of this source code is governed by a BSD-style license  
  5. // that can be found in the License file.  
  6.   
  7. // Author: Shuo Chen (chenshuo at chenshuo dot com)  
  8.   
  9. #include   
  10.   
  11. using namespace muduo;  
  12. using namespace muduo::net;  
  13.   
  14. Poller::Poller(EventLoop* loop)  
  15.   : ownerLoop_(loop)  
  16. {  
  17. }  
  18.   
  19. Poller::~Poller()  
  20. {  
  21. }  


PollPoller头文件

pollpoller.h

  1. // Copyright 2010, Shuo Chen.  All rights reserved.  
  2. // http://code.google.com/p/muduo/  
  3. //  
  4. // Use of this source code is governed by a BSD-style license  
  5. // that can be found in the License file.  
  6.   
  7. // Author: Shuo Chen (chenshuo at chenshuo dot com)  
  8. //  
  9. // This is an internal header file, you should not include this.  
  10.   
  11. #ifndef MUDUO_NET_POLLER_POLLPOLLER_H  
  12. #define MUDUO_NET_POLLER_POLLPOLLER_H  
  13.   
  14. #include   
  15.   
  16. #include   
  17. #include   
  18.   
  19. struct pollfd;  
  20.   
  21. namespace muduo  
  22. {  
  23. namespace net  
  24. {  
  25.   
  26. ///  
  27. /// IO Multiplexing with poll(2).  
  28. ///  
  29. class PollPoller : public Poller  
  30. {  
  31.  public:  
  32.   
  33.   PollPoller(EventLoop* loop);  
  34.   virtual ~PollPoller();  
  35.   
  36.   /*返回活动的通道列表*/  
  37.   virtual Timestamp poll(int timeoutMs, ChannelList* activeChannels);  
  38.   virtual void updateChannel(Channel* channel);  
  39.   virtual void removeChannel(Channel* channel);  
  40.   
  41.  private:  
  42.   void fillActiveChannels(int numEvents,  
  43.                           ChannelList* activeChannels) const;  
  44.   
  45.   typedef std::vector<struct pollfd> PollFdList;  
  46.   typedef std::map<int, Channel*> ChannelMap; // key是文件描述符,value是Channel*  
  47.   PollFdList pollfds_; // 事件结构  
  48.   /*被关注的通道列表 , 不是活动的通道列表*/  
  49.   ChannelMap channels_;  
  50. };  
  51.   
  52. }  
  53. }  
  54. #endif  // MUDUO_NET_POLLER_POLLPOLLER_H  

PollPoller源文件

pollpoller.cc

  1. // Copyright 2010, Shuo Chen.  All rights reserved.  
  2. // http://code.google.com/p/muduo/  
  3. //  
  4. // Use of this source code is governed by a BSD-style license  
  5. // that can be found in the License file.  
  6.   
  7. // Author: Shuo Chen (chenshuo at chenshuo dot com)  
  8.   
  9. #include   
  10.   
  11. #include   
  12. #include   
  13. #include   
  14.   
  15. #include   
  16. #include   
  17.   
  18. using namespace muduo;  
  19. using namespace muduo::net;  
  20.   
  21. PollPoller::PollPoller(EventLoop* loop)  
  22.   : Poller(loop)  
  23. {  
  24. }  
  25.   
  26. PollPoller::~PollPoller()  
  27. {  
  28. }  
  29.   
  30. /* 
  31. 真正的poll 函数,终于到主角了^<>^  /// 
  32. **/  
  33. Timestamp PollPoller::poll(int timeoutMs, ChannelList* activeChannels)  
  34. {  
  35.   // XXX pollfds_ shouldn't change  
  36.   int numEvents = ::poll(&*pollfds_.begin(), pollfds_.size(), timeoutMs);  
  37.   Timestamp now(Timestamp::now());  
  38.   //如果有活动事件 , 则填充到activeChannels 中去  
  39.   if (numEvents > 0)  
  40.   {  
  41.     LOG_TRACE << numEvents << " events happended";  
  42.     fillActiveChannels(numEvents, activeChannels);  
  43.   }  
  44.   else if (numEvents == 0)  
  45.   {  
  46.     LOG_TRACE << " nothing happended";  
  47.   }  
  48.   else  
  49.   {  
  50.     LOG_SYSERR << "PollPoller::poll()";  
  51.   }  
  52.   return now;  
  53. }  
  54.   
  55. //填充活动通道  
  56. // activeChannels 活动通道  
  57. // pollfds_       已注册的事件集合  
  58. /*被关注的通道列表 , 不是活动的通道列表*/  
  59. void PollPoller::fillActiveChannels(int numEvents,  
  60.                                     ChannelList* activeChannels) const  
  61. {  
  62.   for (PollFdList::const_iterator pfd = pollfds_.begin();  
  63.       pfd != pollfds_.end() && numEvents > 0; ++pfd)  
  64.   {  
  65.     //返回活动的文件描述符  
  66.     if (pfd->revents > 0)  
  67.     {  
  68.       --numEvents;  
  69.       // 从关注列表channels_中找出 已产生事件 的fd---》channel  
  70.       ChannelMap::const_iterator ch = channels_.find(pfd->fd);  
  71.       // 断言是否已近到了channels_的尾部  
  72.       assert(ch != channels_.end());  
  73.       // 获取活动channel  
  74.       Channel* channel = ch->second;   
  75.       // 断言channel的文件描述符是否和pfd 的描述符一致  
  76.       assert(channel->fd() == pfd->fd);  
  77.       // 设置channel的事件  
  78.       channel->set_revents(pfd->revents);  
  79.       // pfd->revents = 0;  
  80.       // 把活动channel 加入activeChannel容器  
  81.       activeChannels->push_back(channel);  
  82.     }  
  83.   }  
  84. }  
  85.   
  86. /* 
  87. 更行channel通道,  
  88. **/  
  89. void PollPoller::updateChannel(Channel* channel)  
  90. {  
  91.   //断言实在LoopThread 当中  
  92.   Poller::assertInLoopThread();  
  93.   LOG_TRACE << "fd = " << channel->fd() << " events = " << channel->events();  
  94.   //如果新的通道,还没有注册事件  
  95.   if (channel->index() < 0)  
  96.   {  
  97.     // index < 0说明是一个新的通道  
  98.     // a new one, add to pollfds_   
  99.     //断言是新的通道  
  100.     assert(channels_.find(channel->fd()) == channels_.end());  
  101.   
  102.     //注册事件  
  103.     struct pollfd pfd;  
  104.     pfd.fd = channel->fd();  
  105.     pfd.events = static_cast<short>(channel->events());  
  106.     pfd.revents = 0;  
  107.     pollfds_.push_back(pfd);  
  108.     //channel在pollfds中索引  
  109.     int idx = static_cast<int>(pollfds_.size())-1;  
  110.     //更新channel的索引  
  111.     channel->set_index(idx);  
  112.     //加入channels_ 的map中  
  113.     channels_[pfd.fd] = channel;  
  114.   }  
  115.   else  
  116.   {  
  117.     // update existing one  
  118.     //断言channel 已存在--》 channels_ ,index >0 < pollfds_.size()  
  119.     assert(channels_.find(channel->fd()) != channels_.end());  
  120.     assert(channels_[channel->fd()] == channel);  
  121.     int idx = channel->index();  
  122.     assert(0 <= idx && idx < static_cast<int>(pollfds_.size()));  
  123.     struct pollfd& pfd = pollfds_[idx];  
  124.   
  125.     assert(pfd.fd == channel->fd() || pfd.fd == -channel->fd()-1);  
  126.   
  127.     //下面才是真正的更新  
  128.     pfd.events = static_cast<short>(channel->events());  
  129.     //revents 貌似不用清零???  
  130.     pfd.revents = 0;  
  131.     // 将一个通道暂时更改为不关注事件,但不从Poller中移除该通道  
  132.     if (channel->isNoneEvent())  
  133.     {  
  134.       // ignore this pollfd  
  135.       // 暂时忽略该文件描述符的事件  
  136.       // 这里pfd.fd 可以直接设置为-1 , -1是为了排除0描述符的干扰  
  137.       pfd.fd = -channel->fd()-1; // 这样子设置是为了removeChannel优化  
  138.     }  
  139.   }  
  140. }  
  141.   
  142. // 把channel 真正的从pollfds 中移除  
  143. void PollPoller::removeChannel(Channel* channel)  
  144. {  
  145.   Poller::assertInLoopThread();  
  146.   LOG_TRACE << "fd = " << channel->fd();  
  147.   assert(channels_.find(channel->fd()) != channels_.end());  
  148.   assert(channels_[channel->fd()] == channel);  
  149.   //要移除的channel一定是没有关注事件了   
  150.   assert(channel->isNoneEvent());  
  151.   int idx = channel->index();  
  152.   assert(0 <= idx && idx < static_cast<int>(pollfds_.size()));  
  153.   const struct pollfd& pfd = pollfds_[idx]; (void)pfd;  
  154.   
  155.   assert(pfd.fd == -channel->fd()-1 && pfd.events == channel->events());  
  156.   
  157.   //1-----------》先把channel 从channels_中移除  
  158.   size_t n = channels_.erase(channel->fd());  
  159.   assert(n == 1); (void)n;  
  160.   //2-----------》如果是最后一个,则直接移除  
  161.   if (implicit_cast<size_t>(idx) == pollfds_.size()-1)  
  162.   {  
  163.     pollfds_.pop_back();  
  164.   }  
  165.   else  
  166.   {  
  167.     // 2----------》这里移除的算法复杂度是O(1),将待删除元素与最后一个元素交换再pop_back  
  168.     int channelAtEnd = pollfds_.back().fd;  
  169.     iter_swap(pollfds_.begin()+idx, pollfds_.end()-1);  
  170.   
  171.     //channelAtEnd 是从 pollfds_ 里面拿出来的,所以可能是负数  
  172.     if (channelAtEnd < 0)  
  173.     {  
  174.       channelAtEnd = -channelAtEnd-1;  
  175.     }  
  176.     channels_[channelAtEnd]->set_index(idx);  
  177.     pollfds_.pop_back();  
  178.   }  
  179. }  


Channel头文件

channel.h

  1. // Copyright 2010, Shuo Chen.  All rights reserved.  
  2. // http://code.google.com/p/muduo/  
  3. //  
  4. // Use of this source code is governed by a BSD-style license  
  5. // that can be found in the License file.  
  6.   
  7. // Author: Shuo Chen (chenshuo at chenshuo dot com)  
  8. //  
  9. // This is an internal header file, you should not include this.  
  10.   
  11. #ifndef MUDUO_NET_CHANNEL_H  
  12. #define MUDUO_NET_CHANNEL_H  
  13.   
  14. #include   
  15. #include   
  16. #include   
  17. #include   
  18.   
  19. #include   
  20.   
  21. namespace muduo  
  22. {  
  23. namespace net  
  24. {  
  25.   
  26. class EventLoop;  
  27.   
  28. ///  
  29. /// A selectable I/O channel.  
  30. ///  
  31. /// This class doesn't own the file descriptor.  
  32. /// The file descriptor could be a socket,  
  33. /// an eventfd, a timerfd, or a signalfd  
  34. class Channel : boost::noncopyable //不可拷贝的  
  35. {  
  36.  public:  
  37.   /*事件回调处理函数*/  
  38.   typedef boost::function<void()> EventCallback;   
  39.   /*读事件的回调处理*/  
  40.   typedef boost::function<void(Timestamp)> ReadEventCallback;  
  41.   /*一个EventLoop 包含多个Channel , 一个channel只属于一个EventLoop 
  42.   Channel(n)-----> EventLoop 
  43.   */  
  44.   Channel(EventLoop* loop, int fd);  
  45.   //虚构函数没干什么事^V^  
  46.   ~Channel();  
  47.   
  48.   void handleEvent(Timestamp receiveTime);  
  49.   
  50.   /*回调函数的注册*/  
  51.   // 读的回调函数  
  52.   void setReadCallback(const ReadEventCallback& cb)  
  53.   { readCallback_ = cb; }  
  54.   // 写的回调函数  
  55.   void setWriteCallback(const EventCallback& cb)  
  56.   { writeCallback_ = cb; }  
  57.   // 关闭的回调函数  
  58.   void setCloseCallback(const EventCallback& cb)  
  59.   { closeCallback_ = cb; }  
  60.   // 出错的回调函数  
  61.   void setErrorCallback(const EventCallback& cb)  
  62.   { errorCallback_ = cb; }  
  63. //  
  64.   
  65.   /* 
  66. 这个函数下一节才开始分析^V^ ... 
  67. 这个函数跟TcpConnection 生命周期是有关系的,为了防止在事件处理的时候 
  68.   **/  
  69.   /// Tie this channel to the owner object managed by shared_ptr,  
  70.   /// prevent the owner object being destroyed in handleEvent.  
  71.   void tie(const boost::shared_ptr<void>&);  
  72.   
  73.   //channel 的描述符  
  74.   int fd() const { return fd_; }  
  75.   // channel注册的事件(关注的事件)  
  76.   int events() const { return events_; }  
  77.   
  78.   // poller 实际返回的事件,  
  79.   void set_revents(int revt) { revents_ = revt; } // used by pollers  
  80.   
  81.   //清空channel的事件  
  82.   // int revents() const { return revents_; }  
  83.   bool isNoneEvent() const { return events_ == kNoneEvent; }  
  84.   
  85.   void enableReading() { events_ |= kReadEvent; update(); }  
  86.   // void disableReading() { events_ &= ~kReadEvent; update(); }  
  87.   void enableWriting() { events_ |= kWriteEvent; update(); }  
  88.   void disableWriting() { events_ &= ~kWriteEvent; update(); }  
  89.   void disableAll() { events_ = kNoneEvent; update(); }  
  90.   bool isWriting() const { return events_ & kWriteEvent; }  
  91.   
  92.   // for Poller ; 在Poller数组中的索引  
  93.   int index() { return index_; }  
  94.   // 设置channel在poller的索引  
  95.   void set_index(int idx) { index_ = idx; }  
  96.   
  97.   // for debug 事件的调试信息  
  98.   string reventsToString() const;  
  99.   
  100.   void doNotLogHup() { logHup_ = false; }  
  101.   
  102.   EventLoop* ownerLoop() { return loop_; }  
  103.   void remove();  
  104.   
  105.  private:  
  106.   void update();  
  107.   void handleEventWithGuard(Timestamp receiveTime);  
  108.   
  109.   //事件常量  
  110.   //没有事件就是说等于零  
  111.   static const int kNoneEvent;  
  112.   static const int kReadEvent;  
  113.   static const int kWriteEvent;  
  114.   
  115.   EventLoop* loop_;         // 所属EventLoop  
  116.   const int  fd_;           // 文件描述符,但不负责关闭该文件描述符  
  117.   int        events_;       // 关注的事件  
  118.   int        revents_;      // poll/epoll返回的事件  
  119.   int        index_;        // used by Poller.表示在poll的事件数组中的序号  
  120.   bool       logHup_;       // for POLLHUP  
  121.   
  122.   // 下面两个是负责生存期的控制  
  123.   boost::weak_ptr<void> tie_;  
  124.   bool tied_;  
  125.   
  126.   
  127.   bool eventHandling_;      // 是否处于处理事件中  
  128.   ReadEventCallback readCallback_;  
  129.   EventCallback writeCallback_;  
  130.   EventCallback closeCallback_;  
  131.   EventCallback errorCallback_;  
  132. };  
  133.   
  134. }  
  135. }  
  136. #endif  // MUDUO_NET_CHANNEL_H  

Channel源文件

channel.cc

  1. // Copyright 2010, Shuo Chen.  All rights reserved.  
  2. // http://code.google.com/p/muduo/  
  3. //  
  4. // Use of this source code is governed by a BSD-style license  
  5. // that can be found in the License file.  
  6.   
  7. // Author: Shuo Chen (chenshuo at chenshuo dot com)  
  8.   
  9. #include   
  10. #include   
  11. #include   
  12.   
  13. #include   
  14.   
  15. #include   
  16.   
  17. using namespace muduo;  
  18. using namespace muduo::net;  
  19.   
  20. const int Channel::kNoneEvent = 0; //没有事件  
  21. const int Channel::kReadEvent = POLLIN | POLLPRI; //产生量可读事件或者紧急数据  
  22. const int Channel::kWriteEvent = POLLOUT;  
  23.   
  24. Channel::Channel(EventLoop* loop, int fd__)  
  25.   : loop_(loop),  
  26.     fd_(fd__),  
  27.     events_(0),  
  28.     revents_(0),  
  29.     index_(-1),  //没加入poller是,channel的索引为 -1   
  30.     logHup_(true),  
  31.     tied_(false),  
  32.     eventHandling_(false)   //channel的事件处理状态初始化为 false  
  33. {  
  34. }  
  35.   
  36. Channel::~Channel()  
  37. {  
  38.   assert(!eventHandling_);  
  39. }  
  40.   
  41. void Channel::tie(const boost::shared_ptr<void>& obj)  
  42. {  
  43.   tie_ = obj;  
  44.   tied_ = true;  
  45. }  
  46.   
  47. //更新channel的事件  
  48. void Channel::update()  
  49. {  
  50.   loop_->updateChannel(this);  
  51. }  
  52.   
  53. // 调用这个函数之前确保调用disableAll  
  54. //  void disableAll() { events_ = kNoneEvent; update()-->assert(isNoneEvent()); }  
  55. void Channel::remove()  
  56. {  
  57.   assert(isNoneEvent());  
  58.   loop_->removeChannel(this);  
  59. }  
  60. /** 
  61.   当时到达时,调用事件处理函数handleEvent进行处理 
  62. */  
  63. void Channel::handleEvent(Timestamp receiveTime)  
  64. {  
  65.   boost::shared_ptr<void> guard;  
  66.   if (tied_)  
  67.   {  
  68.     guard = tie_.lock();  
  69.     if (guard)  
  70.     {  
  71.       handleEventWithGuard(receiveTime);  
  72.     }  
  73.   }  
  74.   else  
  75.   {  
  76.     handleEventWithGuard(receiveTime);  
  77.   }  
  78. }  
  79.   
  80. /** 
  81.  事件处理 
  82. **/  
  83. void Channel::handleEventWithGuard(Timestamp receiveTime)  
  84. {//把channel的事件处理状态设为 true  
  85.   eventHandling_ = true;  
  86.   //如果poller返回的channel 事件是pollhup挂断(写时才会产生),并且不是可读的   
  87.   if ((revents_ & POLLHUP) && !(revents_ & POLLIN))  
  88.   {  
  89.     // 如果挂断了  
  90.     if (logHup_)  
  91.     {  
  92.       LOG_WARN << "Channel::handle_event() POLLHUP";  
  93.     }  
  94.     //如果挂断了,就返回closeCallback  
  95.     if (closeCallback_) closeCallback_();  
  96.   }  
  97.   
  98.   //文件描述符不合法或者文件描述符没有打开  
  99.   if (revents_ & POLLNVAL)  
  100.   {  
  101.     LOG_WARN << "Channel::handle_event() POLLNVAL";  
  102.   }  
  103.   
  104.   if (revents_ & (POLLERR | POLLNVAL))  
  105.   {  
  106.     if (errorCallback_) errorCallback_();  
  107.   }  
  108.   //可读事件 ,   
  109.   //POLLRDHUP :stream socket peer closed connection ,or shutdown writing half of connection  
  110.   //POLLPRI : there is urgent data to read   
  111.   if (revents_ & (POLLIN | POLLPRI | POLLRDHUP))  
  112.   {  
  113.     if (readCallback_) readCallback_(receiveTime);  
  114.   }  
  115.   //可写事件  
  116.   if (revents_ & POLLOUT)  
  117.   {  
  118.     if (writeCallback_) writeCallback_();  
  119.   }  
  120.   //事件处理完后,把事件处理状态恢复为false状态  
  121.   eventHandling_ = false;  
  122. }  
  123.   
  124. string Channel::reventsToString() const  
  125. {  
  126.   std::ostringstream oss;  
  127.   oss << fd_ << ": ";  
  128.   if (revents_ & POLLIN)  
  129.     oss << "IN ";  
  130.   if (revents_ & POLLPRI)  
  131.     oss << "PRI ";  
  132.   if (revents_ & POLLOUT)  
  133.     oss << "OUT ";  
  134.   if (revents_ & POLLHUP)  
  135.     oss << "HUP ";  
  136.   if (revents_ & POLLRDHUP)  
  137.     oss << "RDHUP ";  
  138.   if (revents_ & POLLERR)  
  139.     oss << "ERR ";  
  140.   if (revents_ & POLLNVAL)  
  141.     oss << "NVAL ";  
  142.   
  143.   return oss.str().c_str();  
  144. }  

你可能感兴趣的:(moduo网络,linux并发网络编程相关)