Skip to content

Commit

Permalink
[core] Set ACK position based on RCV buffer first nonread seqno (#2931).
Browse files Browse the repository at this point in the history
  • Loading branch information
maxsharabayko authored Aug 2, 2024
1 parent ffdebd3 commit 968c9f9
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 0 deletions.
6 changes: 6 additions & 0 deletions srtcore/buffer_rcv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,12 @@ CRcvBuffer::PacketInfo CRcvBuffer::getFirstReadablePacketInfo(time_point time_no
return unreadableInfo;
}

int32_t CRcvBuffer::getFirstNonreadSeqNo() const
{
const int offset = offPos(m_iStartPos, m_iFirstNonreadPos);
return CSeqNo::incseq(m_iStartSeqNo, offset);
}

void CRcvBuffer::countBytes(int pkts, int bytes)
{
ScopedLock lock(m_BytesCountLock);
Expand Down
5 changes: 5 additions & 0 deletions srtcore/buffer_rcv.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@ class CRcvBuffer

PacketInfo getFirstReadablePacketInfo(time_point time_now) const;

/// @brief Get the sequence number of the first packet that can't be read
/// (either because it is missing, or because it is a part of a bigger message
/// that is not fully available yet).
int32_t getFirstNonreadSeqNo() const;

/// Get information on packets available to be read.
/// @returns a pair of sequence numbers (first available; first unavailable).
///
Expand Down
22 changes: 22 additions & 0 deletions srtcore/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8023,6 +8023,27 @@ void srt::CUDT::sendCtrl(UDTMessageType pkttype, const int32_t* lparam, void* rp
// [[using locked(m_RcvBufferLock)]]
bool srt::CUDT::getFirstNoncontSequence(int32_t& w_seq, string& w_log_reason)
{
if (m_config.bTSBPD || !m_config.bMessageAPI)
{
// The getFirstNonreadSeqNo() function retuens the sequence number of the first packet
// that cannot be read. In cases when a message can consist of several data packets,
// an existing packet of partially available message also cannot be read.
// If TSBPD mode is enabled, a message must consist of a single data packet only.
w_seq = m_pRcvBuffer->getFirstNonreadSeqNo();

const int32_t iNextSeqNo = CSeqNo::incseq(m_iRcvCurrSeqNo);
SRT_ASSERT(CSeqNo::seqcmp(w_seq, iNextSeqNo) <= 0);
w_log_reason = iNextSeqNo != w_seq ? "first lost" : "expected next";

if (CSeqNo::seqcmp(w_seq, iNextSeqNo) > 0)
{
LOGC(xtlog.Error, log << "IPE: NONCONT-SEQUENCE: RCV buffer first non-read %" << w_seq << ", RCV latest seqno %" << m_iRcvCurrSeqNo);
w_seq = iNextSeqNo;
}

return true;
}

{
ScopedLock losslock (m_RcvLossLock);
const int32_t seq = m_pRcvLossList->getFirstLostSeq();
Expand Down Expand Up @@ -8070,6 +8091,7 @@ int srt::CUDT::sendCtrlAck(CPacket& ctrlpkt, int size)
// since the last full ACK. It should unblock the sender to proceed further.
const bool bNeedFullAck = (m_bBufferWasFull && getAvailRcvBufferSizeNoLock() > 0);
int32_t ack; // First unacknowledged packet sequence number (acknowledge up to ack).

if (!getFirstNoncontSequence((ack), (reason)))
return nbsent;

Expand Down

0 comments on commit 968c9f9

Please sign in to comment.