chunks: fix aimd hanging with files less than chunk size
refs: #4439
Change-Id: Ie3ef5d81e6baf154ade97beda183bc6b16764085
diff --git a/tests/chunks/pipeline-interests-aimd.t.cpp b/tests/chunks/pipeline-interests-aimd.t.cpp
index 2deed18..19f1316 100644
--- a/tests/chunks/pipeline-interests-aimd.t.cpp
+++ b/tests/chunks/pipeline-interests-aimd.t.cpp
@@ -496,6 +496,27 @@
std::cerr.rdbuf(oldBuf); // reset
}
+BOOST_AUTO_TEST_CASE(StopsWhenFileSizeLessThanChunkSize)
+{
+ // test to see if the program doesn't hang,
+ // when transfer is complete, for files less than the chunk size
+ // (i.e. when only one segment is sent/received)
+
+ createPipeline();
+ nDataSegments = 1;
+
+ runWithData(*makeDataWithSegment(0));
+ advanceClocks(io, time::nanoseconds(1));
+
+ face.receive(*makeDataWithSegment(1));
+ advanceClocks(io, time::nanoseconds(1));
+
+ BOOST_CHECK_EQUAL(aimdPipeline->m_hasFinalBlockId, true);
+ BOOST_CHECK_EQUAL(aimdPipeline->m_segmentInfo.size(), 0);
+ BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
+}
+
+
BOOST_AUTO_TEST_SUITE_END() // TestPipelineInterestsAimd
BOOST_AUTO_TEST_SUITE_END() // Chunks
diff --git a/tools/chunks/catchunks/pipeline-interests-aimd.cpp b/tools/chunks/catchunks/pipeline-interests-aimd.cpp
index eac9dfd..961a064 100644
--- a/tools/chunks/catchunks/pipeline-interests-aimd.cpp
+++ b/tools/chunks/catchunks/pipeline-interests-aimd.cpp
@@ -70,6 +70,14 @@
void
PipelineInterestsAimd::doRun()
{
+ if (allSegmentsReceived()) {
+ cancel();
+ if (!m_options.isQuiet) {
+ printSummary();
+ }
+ return;
+ }
+
// schedule the event to check retransmission timer
m_checkRtoEvent = m_scheduler.scheduleEvent(m_options.rtoCheckInterval, [this] { checkRto(); });
@@ -121,7 +129,7 @@
if (isStopping())
return;
- if (m_hasFinalBlockId && segNo > m_lastSegmentNo && !isRetransmission)
+ if (m_hasFinalBlockId && segNo > m_lastSegmentNo)
return;
if (!isRetransmission && m_hasFailure)
@@ -291,8 +299,7 @@
}
BOOST_ASSERT(m_nReceived > 0);
- if (m_hasFinalBlockId &&
- static_cast<uint64_t>(m_nReceived - 1) >= m_lastSegmentNo) { // all segments have been received
+ if (allSegmentsReceived()) {
cancel();
if (!m_options.isQuiet) {
printSummary();
@@ -435,6 +442,12 @@
}
}
+bool
+PipelineInterestsAimd::allSegmentsReceived() const
+{
+ return m_hasFinalBlockId && static_cast<uint64_t>(m_nReceived - 1) >= m_lastSegmentNo;
+}
+
void
PipelineInterestsAimd::printSummary() const
{
@@ -442,7 +455,7 @@
std::cerr << "Total # of lost/retransmitted segments: " << m_nRetransmitted
<< " (caused " << m_nLossEvents << " window decreases)\n"
<< "Packet loss rate: "
- << (static_cast<double>(m_nRetransmitted) / static_cast<double>(m_nSent)) * 100 << "%\n"
+ << (m_nSent == 0 ? 0 : (static_cast<double>(m_nRetransmitted) / static_cast<double>(m_nSent) * 100)) << "%\n"
<< "Total # of received congestion marks: " << m_nCongMarks << "\n"
<< "RTT ";
diff --git a/tools/chunks/catchunks/pipeline-interests-aimd.hpp b/tools/chunks/catchunks/pipeline-interests-aimd.hpp
index 0257e7b..c2e5166 100644
--- a/tools/chunks/catchunks/pipeline-interests-aimd.hpp
+++ b/tools/chunks/catchunks/pipeline-interests-aimd.hpp
@@ -184,6 +184,9 @@
void
cancelInFlightSegmentsGreaterThan(uint64_t segNo);
+ bool
+ allSegmentsReceived() const;
+
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
void
printSummary() const final;