فهرست منبع

2008-08-14 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

	Fixed occasional assertion failure in PieceSegment.
	Calling PieceStorage::getMissingPiece(size_t) was missing after
	canceling segments in SegmentMan::getSegment(int32_t). This 
resulted in
	creation of duplicate segments and one of the segment was 
finished then
	assertion failure was caused.
	* src/SegmentMan.cc
	* test/SegmentManTest.cc
Tatsuhiro Tsujikawa 17 سال پیش
والد
کامیت
326d11bc46
3فایلهای تغییر یافته به همراه45 افزوده شده و 1 حذف شده
  1. 10 0
      ChangeLog
  2. 7 1
      src/SegmentMan.cc
  3. 28 0
      test/SegmentManTest.cc

+ 10 - 0
ChangeLog

@@ -1,3 +1,13 @@
+2008-08-14  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
+
+	Fixed occasional assertion failure in PieceSegment.
+	Calling PieceStorage::getMissingPiece(size_t) was missing after
+	canceling segments in SegmentMan::getSegment(int32_t). This resulted in
+	creation of duplicate segments and one of the segment was finished then
+	assertion failure was caused.
+	* src/SegmentMan.cc
+	* test/SegmentManTest.cc
+
 2008-08-11  Tatsuhiro Tsujikawa  <tujikawa at rednoah dot com>
 
 	Added options to load/save the server's performance/status to a	file

+ 7 - 1
src/SegmentMan.cc

@@ -46,6 +46,7 @@
 #include "DownloadContext.h"
 #include "Piece.h"
 #include <algorithm>
+#include <cassert>
 
 namespace aria2 {
 
@@ -186,7 +187,12 @@ SegmentHandle SegmentMan::getSegment(int32_t cuid) {
       PeerStatHandle slowPeerStat = getPeerStat(slowSegmentEntry->cuid);
       slowPeerStat->requestIdle();
       cancelSegment(slowSegmentEntry->cuid);
-      return checkoutSegment(cuid, slowSegmentEntry->segment->getPiece());
+      
+      SharedHandle<Piece> piece =
+ 	_pieceStorage->getMissingPiece(slowSegmentEntry->segment->getIndex());
+      assert(!piece.isNull());
+
+      return checkoutSegment(cuid, piece);
     } else {
       return SharedHandle<Segment>();
     }

+ 28 - 0
test/SegmentManTest.cc

@@ -20,6 +20,7 @@ class SegmentManTest:public CppUnit::TestFixture {
   CPPUNIT_TEST(testNullBitfield);
   CPPUNIT_TEST(testCompleteSegment);
   CPPUNIT_TEST(testGetPeerStat);
+  CPPUNIT_TEST(testGetSegment_segmentForward);
   CPPUNIT_TEST_SUITE_END();
 private:
 
@@ -30,6 +31,7 @@ public:
   void testNullBitfield();
   void testCompleteSegment();
   void testGetPeerStat();
+  void testGetSegment_segmentForward();
 };
 
 
@@ -118,4 +120,30 @@ void SegmentManTest::testGetPeerStat()
   }
 }
 
+void SegmentManTest::testGetSegment_segmentForward()
+{
+  Option op;
+  size_t pieceLength = 1;
+  uint64_t totalLength = 1;
+  SharedHandle<SingleFileDownloadContext> dctx
+    (new SingleFileDownloadContext(pieceLength, totalLength, "aria2.tar.bz2"));
+  SharedHandle<PieceStorage> ps(new DefaultPieceStorage(dctx, &op));
+  SegmentMan segmentMan(&op, dctx, ps);
+
+  SharedHandle<Segment> segment = segmentMan.getSegment(1);
+  CPPUNIT_ASSERT(!segment.isNull());
+  CPPUNIT_ASSERT_EQUAL((size_t)0, segment->getIndex());
+
+  SharedHandle<PeerStat> cuid2_ps(new PeerStat(2));
+  CPPUNIT_ASSERT(segmentMan.registerPeerStat(cuid2_ps));
+
+  SharedHandle<Segment> segment_forwarded = segmentMan.getSegment(2);
+  CPPUNIT_ASSERT(!segment_forwarded.isNull());
+  CPPUNIT_ASSERT_EQUAL((size_t)0, segment_forwarded->getIndex());
+
+  // SegmentMan::getSegmetn(3) returns null because CUID#3's PeerStat is not
+  // registered and all segment(total 1 in this case) are used.
+  CPPUNIT_ASSERT(segmentMan.getSegment(3).isNull());
+}
+
 } // namespace aria2