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); } } }
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; }
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; }
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; }
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; }