博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
muduo源码分析 Channel类
阅读量:3941 次
发布时间:2019-05-24

本文共 4607 字,大约阅读时间需要 15 分钟。

文章目录

Channel 是单个文件描述符进行事件分发的类
中介绍了Channel在新连接到达时的作用。这里在源码中看一些Channel 处理了哪些东西。

头文件

//事件分发器,每个事件分发器对应一个文件描述符,监听该文件描述符上的所有的事件class Channel : noncopyable{
public: //两种回调函数的形式 typedef std::function
EventCallback; 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)); }}

update与remove

void Channel::update(){
addedToLoop_ = true; //调用事件循环的update 函数 //将该Channle 添加到事件循环中去 //在事件循环中 更新当前Channel loop_->updateChannel(this);}void Channel::remove(){
assert(isNoneEvent()); addedToLoop_ = false; //从事件循环中删除当前的Channel loop_->removeChannel(this);}

handleEvent 事件分发

void Channel::handleEvent(Timestamp receiveTime){
//采用智能指针管理 std::shared_ptr
guard; 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/

你可能感兴趣的文章
如何做事
查看>>
架构实践 - 1. 架构风格
查看>>
架构实践 - 3. 基于事件系统的demo
查看>>
架构实践 - 4. 架构设计之进程通信(独立构件风格)
查看>>
架构实践 - 5. 基于进程通信的demo
查看>>
sys/time.h 和 time.h的区别
查看>>
1、蓝牙概述
查看>>
2 系统架构师 - 知识框架
查看>>
Linux下 socket-tcp通信
查看>>
小米笔记本解决风扇异响
查看>>
Linux下 socket-udp通信
查看>>
Linux - 守护进程-1
查看>>
syslog 和 rsyslog
查看>>
Linux下,write/read,recv/send, recvfrom/sendto的区别
查看>>
ubuntu下 rc.local的脚本不运行
查看>>
Linux下简单Makefile文件的编写
查看>>
linux下配置JDK JAVA环境
查看>>
解决Ubuntu 14.04 grub选择启动项10秒等待时间
查看>>
Python函数操作集锦之字符串测试、判断函数
查看>>
Python字符串操作集锦之字符串映射表
查看>>