forked from mirrors/gecko-dev
Bug 1445659 - Make it possible to store RefPtr<T> in AutoCleanLinkedList. r=froydnj
Add a trait method that AutoCleanLinkedList delegates to for calling delete on non-refcounted list elements. --HG-- extra : histedit_source : 5e8b05f348d734d9045621d858caed946853fc02
This commit is contained in:
parent
1ea5273b59
commit
b5730bd2b0
3 changed files with 105 additions and 2 deletions
|
|
@ -99,6 +99,11 @@ struct LinkedListElementTraits
|
|||
// to a list.
|
||||
static void enterList(LinkedListElement<T>* elt) {}
|
||||
static void exitList(LinkedListElement<T>* elt) {}
|
||||
|
||||
// This method is called when AutoCleanLinkedList cleans itself
|
||||
// during destruction. It can be used to call delete on elements if
|
||||
// the list is the sole owner.
|
||||
static void cleanElement(LinkedListElement<T>* elt) { delete elt->asT(); }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
|
@ -111,6 +116,7 @@ struct LinkedListElementTraits<RefPtr<T>>
|
|||
|
||||
static void enterList(LinkedListElement<RefPtr<T>>* elt) { elt->asT()->AddRef(); }
|
||||
static void exitList(LinkedListElement<RefPtr<T>>* elt) { elt->asT()->Release(); }
|
||||
static void cleanElement(LinkedListElement<RefPtr<T>>* elt) {}
|
||||
};
|
||||
|
||||
} /* namespace detail */
|
||||
|
|
@ -655,6 +661,9 @@ private:
|
|||
template <typename T>
|
||||
class AutoCleanLinkedList : public LinkedList<T>
|
||||
{
|
||||
private:
|
||||
using Traits = detail::LinkedListElementTraits<T>;
|
||||
using ClientType = typename detail::LinkedListElementTraits<T>::ClientType;
|
||||
public:
|
||||
~AutoCleanLinkedList()
|
||||
{
|
||||
|
|
@ -669,8 +678,8 @@ public:
|
|||
|
||||
void clear()
|
||||
{
|
||||
while (T* element = this->popFirst()) {
|
||||
delete element;
|
||||
while (ClientType element = this->popFirst()) {
|
||||
Traits::cleanElement(element);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
93
mfbt/tests/gtest/TestLinkedList.cpp
Normal file
93
mfbt/tests/gtest/TestLinkedList.cpp
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
using mozilla::AutoCleanLinkedList;
|
||||
using mozilla::LinkedList;
|
||||
using mozilla::LinkedListElement;
|
||||
|
||||
class PtrClass : public LinkedListElement<PtrClass>
|
||||
{
|
||||
public:
|
||||
bool* mResult;
|
||||
|
||||
explicit PtrClass(bool* result)
|
||||
: mResult(result)
|
||||
{
|
||||
EXPECT_TRUE(!*mResult);
|
||||
}
|
||||
|
||||
virtual ~PtrClass() {
|
||||
*mResult = true;
|
||||
}
|
||||
};
|
||||
|
||||
class InheritedPtrClass : public PtrClass {
|
||||
public:
|
||||
bool* mInheritedResult;
|
||||
|
||||
InheritedPtrClass(bool* result, bool* inheritedResult)
|
||||
: PtrClass(result)
|
||||
, mInheritedResult(inheritedResult)
|
||||
{
|
||||
EXPECT_TRUE(!*mInheritedResult);
|
||||
}
|
||||
|
||||
virtual ~InheritedPtrClass() {
|
||||
*mInheritedResult = true;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(LinkedList, AutoCleanLinkedList)
|
||||
{
|
||||
bool rv1 = false;
|
||||
bool rv2 = false;
|
||||
bool rv3 = false;
|
||||
{
|
||||
AutoCleanLinkedList<PtrClass> list;
|
||||
list.insertBack(new PtrClass(&rv1));
|
||||
list.insertBack(new InheritedPtrClass(&rv2, &rv3));
|
||||
}
|
||||
|
||||
EXPECT_TRUE(rv1);
|
||||
EXPECT_TRUE(rv2);
|
||||
EXPECT_TRUE(rv3);
|
||||
}
|
||||
|
||||
class CountedClass final : public LinkedListElement<RefPtr<CountedClass>>
|
||||
{
|
||||
public:
|
||||
int mCount;
|
||||
void AddRef() { mCount++; }
|
||||
void Release() { mCount--; }
|
||||
|
||||
CountedClass()
|
||||
: mCount(0)
|
||||
{
|
||||
}
|
||||
~CountedClass() { EXPECT_TRUE(mCount == 0); }
|
||||
};
|
||||
|
||||
TEST(LinkedList, AutoCleanLinkedListRefPtr)
|
||||
{
|
||||
RefPtr<CountedClass> elt1 = new CountedClass;
|
||||
CountedClass* elt2 = new CountedClass;
|
||||
{
|
||||
AutoCleanLinkedList<RefPtr<CountedClass>> list;
|
||||
list.insertBack(elt1);
|
||||
list.insertBack(elt2);
|
||||
|
||||
EXPECT_TRUE(elt1->mCount == 2);
|
||||
EXPECT_TRUE(elt2->mCount == 1);
|
||||
}
|
||||
|
||||
EXPECT_TRUE(elt1->mCount == 1);
|
||||
EXPECT_TRUE(elt2->mCount == 0);
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'TestLinkedList.cpp',
|
||||
'TestSpan.cpp',
|
||||
]
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue