源码
// 绑定在 loop 上一个 fd 的管道,针对事件使用回调函数
// Copyright 2010, Shuo Chen. All rights reserved.
// http://code.google.com/p/muduo/
//
// Use of this source code is governed by a BSD-style license
// that can be found in the License file.
// Author: Shuo Chen (chenshuo at chenshuo dot com)
//
// This is an internal header file, you should not include this.
#ifndef MUDUO_NET_CHANNEL_H
#define MUDUO_NET_CHANNEL_H
#include "muduo/base/noncopyable.h"
#include "muduo/base/Timestamp.h"
#include <functional>
#include <memory>
namespace muduo
{
namespace net
{
class EventLoop;
/// 一个可以选择的 io 通道
/// A selectable I/O channel.
///
/// This class doesn't own the file descriptor.
/// The file descriptor could be a socket,
/// an eventfd, a timerfd, or a signalfd
class Channel : noncopyable
{
public:
// 事件回到函数,读取回调函数
typedef std::function<void()> EventCallback;
typedef std::function<void(Timestamp)> 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.
// 绑定 通道 数据 shared => weak
void tie(const std::shared_ptr<void>&);
int fd() const { return fd_; }
int events() const { return events_; }
void set_revents(int revt) { revents_ = revt; } // used by pollers
// int revents() const { return revents_; }
// 判断当前channel 是否没事件发生
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 在 poller 中 容器的序号
int index() { return index_; }
void set_index(int idx) { index_ = idx; }
// for debug
string reventsToString() const;
string eventsToString() const;
void doNotLogHup() { logHup_ = false; }
// 返回拥有的 loop
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_; // 绑定的 loop
const int fd_; // 初始化 file description
int events_;
int revents_; // it's the received event types of epoll or poll
int index_; // used by Poller.
bool logHup_;
std::weak_ptr<void> tie_; // 使用弱指针绑定 共享指针,可以从 tie 使用 lock
bool tied_;
bool eventHandling_; // 状态;表示是否正在执行事件处理
bool addedToLoop_;
ReadEventCallback readCallback_;
EventCallback writeCallback_;
EventCallback closeCallback_;
EventCallback errorCallback_;
};
} // namespace net
} // namespace muduo
#endif // MUDUO_NET_CHANNEL_H
构造函数
Channel(EventLoop* loop, int fd);
首先来确定一下 channel 和 loop 之间的关系,loop在muduo 中的实现是 poll 或者 epoll 用于多路复用的io。其中每个loop 上都有一个map container 用于存储这些 channel。
每个channel 对一个一个 fd 文件描述符。
每一个client 客户端都对应一个channel,来自客户端的数据包或者关闭等事件都通过channel进行处理。
channel 类中有一个index 属性,表示当前channel在loop中的编号位置。
回调函数
// 事件回到函数,读取回调函数
typedef std::function<void()> EventCallback;
typedef std::function<void(Timestamp)> ReadEventCallback;
定义了两种类型的回调函数,使用cpp11后的 std::function 来保存函数。
其中 ReadEventCallback 用于处理接受客户端的数据包,参数Timestamp 表示处理的时间。