Channel

 Channel是IO时间的分发器,负责注册和响应IO事件。每个Channel对象自始至终只负责一个文件描述符的IO事件分发,但它并不拥有这个fd,也不会在析构的时候关闭这个fd。

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 std::shared_ptr<void>& obj)
{
  tie_ = obj;
  tied_ = true;
}

 Channel::kReadEvent和Channel::kWriteEvent也就是muduo库所关心的读写事件,POLLOUT---普通数据可写;POLLIN---可读取非高优先级的数据;POLLPRI---可读取高优先级数据。event_是它关心的IO事件,revents_是目前活动的事件。

Channel中的tie_实现的功能貌似只在TcpConnection中使用。对于TcpConnection,如果在Channel中调用Channel::handleEvent()时,执行closeCallback_,有可能引发TcpConnection析构,继而把当前Channel对象也析构了,引起程序崩溃。所以在执行Channel::handleEvent()时,获取一份TcpConnection的shared_ptr,防止TcpConnection析构。

void Channel::handleEvent(Timestamp receiveTime)
{
  std::shared_ptr<void> guard;
  if (tied_)
  {
    guard = tie_.lock();
    if (guard)
    {
      handleEventWithGuard(receiveTime);
    }
  }
  else
  {
    handleEventWithGuard(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); }

这部分代码就是用来注册回调函数的,这些回调函数会在Channel::handleEventWithGuard()中使用,关于Channel::handleEventWithGuard()涉及的各种事件类型参考https://blog.csdn.net/qu1993/article/details/109517303 。这里不再说Channel::handleEventWithGuard()函数。因为Channel的事件处理功能,也就是Channel::handleEvent()需要由EventLoop来调用,所以需要将Channel添加到EventLoop,当关心的事件类型修改后,也要随时更新到EventLoop。当然,实际上这些操作都是EventLoop通过Poller实现的。

  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; }
void Channel::update()
{
  addedToLoop_ = true;
  loop_->updateChannel(this);
}

通过Channel的index_标志来确定更新的方式是添加还是修改。

void Channel::remove()
{
  assert(isNoneEvent());
  addedToLoop_ = false;
  loop_->removeChannel(this);
}

将添加到EventLoop的Channel移除。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值