HTTPSession::runLoopCallback() noexcept {
  // We schedule this callback to run at the end of an event
  // loop iteration if either of two conditions has happened:
  //   * The session has generated some egress data (see scheduleWrite())
  //   * Reads have become unpaused (see resumeReads())
  DestructorGuard dg(this);
  inLoopCallback_ = true;
  auto scopeg = folly::makeGuard([this] {
      inLoopCallback_ = false;
      // This ScopeGuard needs to be under the above DestructorGuard
      if (pendingWriteSizeDelta_) {
        updateWriteBufSize(0);
      }
      checkForShutdown();
    });
  VLOG(5) << *this << " in loop callback";

  for (uint32_t i = 0; i < kMaxWritesPerLoop; ++i) {
    bodyBytesPerWriteBuf_ = 0;
    if (isPrioritySampled()) {
      invokeOnAllTransactions(
        &HTTPTransaction::updateContentionsCount,
        txnEgressQueue_.numPendingEgress());
    }

    bool cork = true;
    bool eom = false;
    unique_ptr<IOBuf> writeBuf = getNextToSend(&cork, &eom);

    if (!writeBuf) {
      break;
    }
    uint64_t len = writeBuf->computeChainDataLength();
    VLOG(11) << *this
             << " bytes of egress to be written: " << len
             << " cork:" << cork << " eom:" << eom;
    if (len == 0) {
      checkForShutdown();
      return;
    }

    if (isPrioritySampled()) {
      invokeOnAllTransactions(
        &HTTPTransaction::updateSessionBytesSheduled,
        bodyBytesPerWriteBuf_);
    }

    WriteSegment* segment = new WriteSegment(this, len);
    segment->setCork(cork);
    segment->setEOR(eom);

    pendingWrites_.push_back(*segment);
    if (!writeTimeout_.isScheduled()) {
      // Any performance concern here?
      timeout_.scheduleTimeout(&writeTimeout_);
    }
    numActiveWrites_++;
    VLOG(4) << *this << " writing " << len << ", activeWrites="
             << numActiveWrites_ << " cork=" << cork << " eom=" << eom;
    bytesScheduled_ += len;
    sock_->writeChain(segment, std::move(writeBuf), segment->getFlags());
    if (numActiveWrites_ > 0) {
      updateWriteCount();
      pendingWriteSizeDelta_ += len;
      // updateWriteBufSize called in scope guard
      break;
    }
    // writeChain can result in a writeError and trigger the shutdown code path
  }
  if (numActiveWrites_ == 0 && !writesShutdown() && hasMoreWrites() &&
      (!connFlowControl_ || connFlowControl_->getAvailableSend())) {
    scheduleWrite();
  }

  if (readsUnpaused()) {
    processReadData();

    // Install the read callback if necessary
    if (readsUnpaused() && !sock_->getReadCallback()) {
      sock_->setReadCB(this);
    }
  }
  // checkForShutdown is now in ScopeGuard
}
HTTPSession::runLoopCallback() noexcept {
   
   
   
   
  DestructorGuard dg(this);
  inLoopCallback_ = true;
  auto scopeg = folly::makeGuard([this] {
      inLoopCallback_ = false;
       
      if (pendingWriteSizeDelta_) {
        updateWriteBufSize(0);
      }
      checkForShutdown();
    });
  VLOG(5) << *this << " in loop callback";

  for (uint32_t i = 0; i < kMaxWritesPerLoop; ++i) {
    bodyBytesPerWriteBuf_ = 0;
    if (isPrioritySampled()) {
      invokeOnAllTransactions(
        &HTTPTransaction::updateContentionsCount,
        txnEgressQueue_.numPendingEgress());
    }

    bool cork = true;
    bool eom = false;
    unique_ptr<IOBuf> writeBuf = getNextToSend(&cork, &eom);

    if (!writeBuf) {
      break;
    }
    uint64_t len = writeBuf->computeChainDataLength();
    VLOG(11) << *this
             << " bytes of egress to be written: " << len
             << " cork:" << cork << " eom:" << eom;
    if (len == 0) {
      checkForShutdown();
      return;
    }

    if (isPrioritySampled()) {
      invokeOnAllTransactions(
        &HTTPTransaction::updateSessionBytesSheduled,
        bodyBytesPerWriteBuf_);
    }

    WriteSegment* segment = new WriteSegment(this, len);
    segment->setCork(cork);
    segment->setEOR(eom);

    pendingWrites_.push_back(*segment);
    if (!writeTimeout_.isScheduled()) {
       
      timeout_.scheduleTimeout(&writeTimeout_);
    }
    numActiveWrites_++;
    VLOG(4) << *this << " writing " << len << ", activeWrites="
             << numActiveWrites_ << " cork=" << cork << " eom=" << eom;
    bytesScheduled_ += len;
    sock_->writeChain(segment, std::move(writeBuf), segment->getFlags());
    if (numActiveWrites_ > 0) {
      updateWriteCount();
      pendingWriteSizeDelta_ += len;
       
      break;
    }
     
  }
  if (numActiveWrites_ == 0 && !writesShutdown() && hasMoreWrites() &&
      (!connFlowControl_ || connFlowControl_->getAvailableSend())) {
    scheduleWrite();
  }

  if (readsUnpaused()) {
    processReadData();

     
    if (readsUnpaused() && !sock_->getReadCallback()) {
      sock_->setReadCB(this);
    }
  }
   
}