Exemple #1
0
void Connection::afterWriteIntoIOVector(sp_int32 simulWrites, ssize_t numWritten) {
  mNumOutstandingBytes -= numWritten;

  for (sp_int32 i = 0; i < simulWrites; ++i) {
    auto pr = mOutstandingPackets.front();
    if (numWritten >= (ssize_t)mIOVector[i].iov_len) {
      // This iov structure was completely written as instructed
      sp_uint32 bytesLeftForThisPacket = PacketHeader::get_packet_size(pr->get_header()) +
                                         PacketHeader::header_size() - pr->position_;
      bytesLeftForThisPacket -= mIOVector[i].iov_len;
      if (bytesLeftForThisPacket == 0) {
        // This whole packet has been consumed
        mSentPackets.push(pr);
        mOutstandingPackets.pop_front();
      } else {
        pr->position_ += mIOVector[i].iov_len;
      }
      numWritten -= mIOVector[i].iov_len;
    } else {
      // This iov structure has been partially sent out
      pr->position_ += numWritten;
      numWritten = 0;
    }
    if (numWritten <= 0) break;
  }

  // Check if we reduced the write buffer to something below the back
  // pressure threshold
  if (hasCausedBackPressure()) {
    // Signal pipe free
    if (mNumOutstandingBytes <= mOptions->low_watermark_) {
      mOnConnectionBufferEmpty(this);
    }
  }
}
Exemple #2
0
Connection::~Connection() {
  if (hasCausedBackPressure()) {
    mOnConnectionBufferEmpty(this);
  }
  delete mIncomingPacket;
  {
    for (auto iter = mOutstandingPackets.begin(); iter != mOutstandingPackets.end(); ++iter) {
      delete iter->first;
    }
    for (auto iter = mSentPackets.begin(); iter != mSentPackets.end(); ++iter) {
      delete iter->first;
    }
  }
  for (auto iter = mReceivedPackets.begin(); iter != mReceivedPackets.end(); ++iter) {
    delete *iter;
  }
  delete[] mIOVector;
}
Exemple #3
0
sp_int32 Connection::sendPacket(OutgoingPacket* packet) {
  packet->PrepareForWriting();
  if (registerForWrite() != 0) return -1;
  mOutstandingPackets.push_back(packet);
  mNumOutstandingBytes += packet->GetTotalPacketSize();

  if (!hasCausedBackPressure()) {
    // Are we above the threshold?
    if (mNumOutstandingBytes >= mOptions->high_watermark_) {
      // Have we been above the threshold enough number of times?
      if (++mNumEnqueuesWithBufferFull > __SYSTEM_MIN_NUM_ENQUEUES_WITH_BUFFER_FULL__) {
        mNumEnqueuesWithBufferFull = 0;
        if (mOnConnectionBufferFull) {
          mOnConnectionBufferFull(this);
        }
      }
    } else {
      mNumEnqueuesWithBufferFull = 0;
    }
  }
  return 0;
}
Exemple #4
0
sp_int32 Connection::sendPacket(OutgoingPacket* packet, VCallback<NetworkErrorCode> cb) {
  packet->PrepareForWriting();
  if (registerForWrite() != 0) return -1;
  mOutstandingPackets.push_back(std::make_pair(packet, std::move(cb)));
  mNumOutstandingPackets++;
  mNumOutstandingBytes += packet->GetTotalPacketSize();

  if (!hasCausedBackPressure()) {
    // Are we above the threshold?
    if (mNumOutstandingBytes >= systemHWMOutstandingBytes) {
      // Have we been above the threshold enough number of times?
      if (++mNumEnqueuesWithBufferFull > __SYSTEM_MIN_NUM_ENQUEUES_WITH_BUFFER_FULL__) {
        mNumEnqueuesWithBufferFull = 0;
        if (mOnConnectionBufferFull) {
          mOnConnectionBufferFull(this);
        }
      }
    } else {
      mNumEnqueuesWithBufferFull = 0;
    }
  }
  return 0;
}
Exemple #5
0
Connection::~Connection() {
  if (hasCausedBackPressure()) {
    mOnConnectionBufferEmpty(this);
  }
  delete mIncomingPacket;
  {
    while (!mOutstandingPackets.empty()) {
      auto p = mOutstandingPackets.front();
      delete p;
      mOutstandingPackets.pop_front();
    }
    while (!mSentPackets.empty()) {
      auto p = mSentPackets.front();
      delete p;
      mSentPackets.pop();
    }
  }
  while (!mReceivedPackets.empty()) {
    auto p = mReceivedPackets.front();
    delete p;
    mReceivedPackets.pop();
  }
  delete[] mIOVector;
}