Fix invalid iterator handling when deleting RequestGroup

pull/46/head
Tatsuhiro Tsujikawa 2013-02-03 18:08:39 +09:00
parent 0a4b21e33b
commit 1c9cfccac4
3 changed files with 40 additions and 8 deletions

View File

@ -158,7 +158,7 @@ public:
// Removes |key| from the list. If the element is not found, this // Removes |key| from the list. If the element is not found, this
// function fails. This function returns true if it // function fails. This function returns true if it
// succeeds. Complexity: O(N) // succeeds. Complexity: O(N)
bool erase(KeyType key) bool remove(KeyType key)
{ {
typename IndexType::iterator i = index_.find(key); typename IndexType::iterator i = index_.find(key);
if(i == index_.end()) { if(i == index_.end()) {
@ -175,6 +175,16 @@ public:
return true; return true;
} }
// Removes element pointed by iterator |k| from the list. If the
// iterator must be valid. This function returns the iterator
// pointing to the element following the erased element. Complexity:
// O(N)
typename SeqType::iterator erase(typename SeqType::iterator k)
{
index_.erase((*k).first);
return seq_.erase(k);
}
// Removes element at the front of the list. If the list is empty, // Removes element at the front of the list. If the list is empty,
// this function fails. This function returns true if it // this function fails. This function returns true if it
// succeeds. Complexity: O(logN) // succeeds. Complexity: O(logN)

View File

@ -207,7 +207,7 @@ size_t RequestGroupMan::changeReservedGroupPosition
bool RequestGroupMan::removeReservedGroup(a2_gid_t gid) bool RequestGroupMan::removeReservedGroup(a2_gid_t gid)
{ {
return reservedGroups_.erase(gid); return reservedGroups_.remove(gid);
} }
namespace { namespace {
@ -440,9 +440,8 @@ void RequestGroupMan::removeStoppedGroup(DownloadEngine* e)
eoi = requestGroups_.end(); i != eoi;) { eoi = requestGroups_.end(); i != eoi;) {
const SharedHandle<RequestGroup>& rg = (*i).second; const SharedHandle<RequestGroup>& rg = (*i).second;
if(rg->getNumCommand() == 0) { if(rg->getNumCommand() == 0) {
++i; i = requestGroups_.erase(i);
requestGroups_.erase(rg->getGID()); eoi = requestGroups_.end();
// rg is invalid here.
} else { } else {
++i; ++i;
} }
@ -875,7 +874,7 @@ RequestGroupMan::findDownloadResult(a2_gid_t gid) const
bool RequestGroupMan::removeDownloadResult(a2_gid_t gid) bool RequestGroupMan::removeDownloadResult(a2_gid_t gid)
{ {
return downloadResults_.erase(gid); return downloadResults_.remove(gid);
} }
void RequestGroupMan::addDownloadResult(const SharedHandle<DownloadResult>& dr) void RequestGroupMan::addDownloadResult(const SharedHandle<DownloadResult>& dr)

View File

@ -17,6 +17,7 @@ class IndexedListTest:public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(IndexedListTest); CPPUNIT_TEST_SUITE(IndexedListTest);
CPPUNIT_TEST(testPushBack); CPPUNIT_TEST(testPushBack);
CPPUNIT_TEST(testPushFront); CPPUNIT_TEST(testPushFront);
CPPUNIT_TEST(testRemove);
CPPUNIT_TEST(testErase); CPPUNIT_TEST(testErase);
CPPUNIT_TEST(testPopFront); CPPUNIT_TEST(testPopFront);
CPPUNIT_TEST(testMove); CPPUNIT_TEST(testMove);
@ -30,6 +31,7 @@ public:
void testPushBack(); void testPushBack();
void testPushFront(); void testPushFront();
void testRemove();
void testErase(); void testErase();
void testPopFront(); void testPopFront();
void testMove(); void testMove();
@ -74,7 +76,7 @@ void IndexedListTest::testPushFront()
} }
} }
void IndexedListTest::testErase() void IndexedListTest::testRemove()
{ {
int a[] = {1,2,3,4,5}; int a[] = {1,2,3,4,5};
IndexedList<int, int*> list; IndexedList<int, int*> list;
@ -82,7 +84,7 @@ void IndexedListTest::testErase()
list.push_back(i, &a[i]); list.push_back(i, &a[i]);
} }
for(int i = 0; i < 5; ++i) { for(int i = 0; i < 5; ++i) {
CPPUNIT_ASSERT(list.erase(i)); CPPUNIT_ASSERT(list.remove(i));
CPPUNIT_ASSERT_EQUAL((size_t)5-i-1, list.size()); CPPUNIT_ASSERT_EQUAL((size_t)5-i-1, list.size());
for(int j = i+1; j < 5; ++j) { for(int j = i+1; j < 5; ++j) {
CPPUNIT_ASSERT_EQUAL(a[j], *list.get(j)); CPPUNIT_ASSERT_EQUAL(a[j], *list.get(j));
@ -90,6 +92,27 @@ void IndexedListTest::testErase()
} }
} }
void IndexedListTest::testErase()
{
int a[] = {1,2,3,4,5};
IndexedList<int, int*> list;
for(int i = 0; i < 5; ++i) {
list.push_back(i, &a[i]);
}
int* p = a;
for(IndexedList<int, int*>::SeqType::iterator i = list.begin();
i != list.end();) {
i = list.erase(i);
CPPUNIT_ASSERT_EQUAL((size_t)(std::distance(i, list.end())), list.size());
int* pp = ++p;
for(IndexedList<int, int*>::SeqType::iterator j = list.begin();
j != list.end(); ++j, ++pp) {
CPPUNIT_ASSERT_EQUAL(*pp, *(*j).second);
}
}
}
void IndexedListTest::testPopFront() void IndexedListTest::testPopFront()
{ {
int a[] = {1,2,3,4,5}; int a[] = {1,2,3,4,5};