事件分发器Channel的数据成员如下:
//定义事件类型变量
static const int kNoneEvent; //无事件
static const int kReadEvent; //可读事件
static const int kWriteEvent; //可写事件
EventLoop *loop_; //channel所属的loop
const int fd_; //channel负责的文件描述符
int events_; //注册的事件
int revents_; //poller设置的就绪的事件
int index_; //被poller使用的下标
bool logHup_; //是否生成某些日志
boost::weak_ptr tie_; //
bool tied_;
bool eventHandling_; //是否处于处理事件中
bool addedToLoop_;
ReadEventCallback readCallback_; //读事件回调
EventCallback writeCallback_; //写事件回调
EventCallback closeCallback_; //关闭事件回调
ReadEventCallback errorCallback_; //错误事件回调
其中EventCallback和ReadEventCallback的声明如下:
typedef boost::function EventCallback; //事件回调函数对象类型
typedef boost::function ReadEventCallback; //读事件回调函数对象类型
//处理事件
void handleEvent(Timestamp receiveTime);
//设置可读事件回调
void setReadCallback(const ReadEventCallback &cb)
{
readCallback_ = cb;
}
//设置可写事件回调
void setWriteCallback(const EventCallback &cb)
{
writeCallback_ = cb;
}
//设置关闭事件回调
void setCloseCallback(const EventCallback &cb)
{
closeCallback_ = cb;
}
//设置错误事件回调
void setErrorCallback(const EventCallback &cb)
{
errorCallback_ = cb;
}
void tie(const boost::shared_ptr&);
//返回注册的事件
int events()const
{
return events_;
}
//设置就绪的事件
void set_revents(int revt)
{
revents_ = revt;
}
//判断是否注册的事件
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;
}
Channel的主要功能为管理各种注册给poller的套接字描述符及其上发生的事件,以及事件发生了调用事件的回调函数。
Channel的主要作用如下:
1.首先我们给定Channel所属的loop以及其要处理的fd
2.接着我们开始注册fd_上需要监听的事件,如果是常用事件(读写等)的话,我们可以直接调用接口enable***来注册对应fd上的事件,与之对应的是disable***用来销毁特定的事件
3.再然后我们通过set***Callback来事件发生时的回调
Channel.h:
#ifndef MUDUO_NET_CHANNEL_H
#define MUDUO_NET_CHANNEL_H
#include
#include
#include
#include
#include
namespace muduo
{
namespace net
{
class EventLoop;
class Channel : boost::noncopyable
{
public:
typedef boost::function EventCallback; //事件回调
typedef boost::function ReadEventCallback; //读事件回调
Channel(EventLoop* loop, int fd);
~Channel();
void handleEvent(Timestamp receiveTime); //处理事件
void setReadCallback(const ReadEventCallback& cb) //设置可读事件回调
{ readCallback_ = cb; }
void setWriteCallback(const EventCallback& cb) //设置可写事件回调
{ writeCallback_ = cb; }
void setCloseCallback(const EventCallback& cb) //设置关闭事件回调
{ closeCallback_ = cb; }
void setErrorCallback(const EventCallback& cb) //设置错误事件回调
{ errorCallback_ = cb; }
void tie(const boost::shared_ptr&);
int fd() const { return fd_; }
int events() const { return events_; } //返回注册的事件
void set_revents(int revt) { revents_ = revt; } // 设置发生的事件:poller中调用
// 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
int index() { return index_; } //返回poll事件数组中的序号
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; //可写事件
EventLoop* loop_; //channel所属的EventLoop
const int fd_; //channel负责的文件描述符,但不负责关闭该文件描述符
int events_; //注册的事件
int revents_; //poller返回的就绪的事件
int index_; //表示在poll的事件数组中的序号
bool logHup_; //是否生成某些日志
boost::weak_ptr tie_;
bool tied_;
bool eventHandling_; //是否处于处理事件中
bool addedToLoop_;
ReadEventCallback readCallback_; //读事件回调
EventCallback writeCallback_; //写事件回调
EventCallback closeCallback_; //关闭事件回调
EventCallback errorCallback_; //错误事件回调
};
}
}
#endif // MUDUO_NET_CHANNEL_H
Channel.cc:
#include
#include
#include
#include
#include
using namespace muduo;
using namespace muduo::net;
const int Channel::kNoneEvent = 0;
const int Channel::kReadEvent = POLLIN | POLLPRI;
const int Channel::kWriteEvent = POLLOUT;
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::tie(const boost::shared_ptr& obj)
{
tie_ = obj;
tied_ = true;
}
void Channel::update() //添加事件分发器
{
addedToLoop_ = true;
loop_->updateChannel(this);
}
void Channel::remove() //移除事件分发器
{
assert(isNoneEvent());
addedToLoop_ = false;
loop_->removeChannel(this);
}
void Channel::handleEvent(Timestamp receiveTime) //核心:事件处理函数
{
boost::shared_ptr guard;
if (tied_)
{
guard = tie_.lock();
if (guard)
{
handleEventWithGuard(receiveTime); //调用handleEventWithGuard
}
}
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;
}
string Channel::reventsToString() const
{
return eventsToString(fd_, revents_);
}
string Channel::eventsToString() const
{
return eventsToString(fd_, events_);
}
string Channel::eventsToString(int fd, int ev)
{
std::ostringstream oss;
oss << fd << ": ";
if (ev & POLLIN)
oss << "IN ";
if (ev & POLLPRI)
oss << "PRI ";
if (ev & POLLOUT)
oss << "OUT ";
if (ev & POLLHUP)
oss << "HUP ";
if (ev & POLLRDHUP)
oss << "RDHUP ";
if (ev & POLLERR)
oss << "ERR ";
if (ev & POLLNVAL)
oss << "NVAL ";
return oss.str().c_str();
}