zoukankan      html  css  js  c++  java
  • muduo网络库TcpConnection对象生存期管理

    为什么释放一个TcpConnection会如此复杂?

      首先要知道客户端关闭连接,在服务端TcpConnection对象所属的Channel对象返回的是可读事件。

      因此从TcpServer的map<string, shared_ptr<TcpConnection>>中移除这个TcpConnection对象都是在TcpConnectoin所属的Channel对象的Channel::handleEvent()函数内进行的。

      如果在这个TcpConnection对象的函数执行过程中释放了这个对象,那么就会造成不可预计的后果。(大概率就是coredump)

      因此待释放的TcpConnection对象的生命期一定要长于Channel::handleEvent()函数。

    如何做到正确释放一个TcpConnection对象的?

    最重要的是在每一个TcpConnection建立的时候将他的shared_ptr赋值给了他所属的Channel对象的weak_ptr。

    void TcpConnection::connectEstablished()
    {
      loop_->assertInLoopThread();
      assert(state_ == kConnecting);
      setState(kConnected);
      channel_->tie(shared_from_this());
      channel_->enableReading();
      connectionCallback_(shared_from_this());
    }

    这样当有TcpConnection所属的Channel有事件到来的时候就可以对TcpConnection的引用计数+1:此时TcpServer的map中有一个智能指针指向TcpConnection

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

    整一个流程为:

    简略的函数压栈情况:

  • 相关阅读:
    HDinsight 系列-使用证书登陆中国区Azure
    PowerBI 应用时间智能(生成日期表)
    Hadoop 常用命令之 HDFS命令
    Hadoop分布式集群安装
    DAX:New and returning customers
    Hadoop 安装过程中出现的问题
    ftp 报错 200 Type set to A
    LC.exe 已退出,代码为-1 问题解决
    C# 文件操作
    EfRepository
  • 原文地址:https://www.cnblogs.com/jialin0x7c9/p/12562981.html
Copyright © 2011-2022 走看看