Fix lifecycle issue in CommonPool

Destroy things more faster

Fixes: 129250875
Test: hwui_unit_tests
Change-Id: I7e060fcb61f5321dd9e68a3ee4a01868033b3fc3
This commit is contained in:
John Reck
2019-04-04 15:49:40 -07:00
parent dd07ae579c
commit 5ff61f32a7
2 changed files with 127 additions and 2 deletions

View File

@@ -135,4 +135,127 @@ TEST(CommonPool, fullQueue) {
for (auto& f : futures) {
f.get();
}
}
struct DestructorObserver {
DestructorObserver(int* destroyCount) : mDestroyCount(destroyCount) {}
DestructorObserver(const DestructorObserver& other) : mDestroyCount(other.mDestroyCount) {}
DestructorObserver(DestructorObserver&& other) {
mDestroyCount = other.mDestroyCount;
other.mDestroyCount = nullptr;
}
~DestructorObserver() {
if (mDestroyCount) {
(*mDestroyCount)++;
}
}
DestructorObserver& operator=(DestructorObserver&& other) {
mDestroyCount = other.mDestroyCount;
other.mDestroyCount = nullptr;
return *this;
}
int* mDestroyCount;
};
struct CopyObserver {
CopyObserver(int* copyCount) : mCopyCount(copyCount) {}
CopyObserver(CopyObserver&& other) = default;
CopyObserver& operator=(CopyObserver&& other) = default;
CopyObserver(const CopyObserver& other) {
mCopyCount = other.mCopyCount;
if (mCopyCount) {
(*mCopyCount)++;
}
}
CopyObserver& operator=(const CopyObserver& other) {
mCopyCount = other.mCopyCount;
if (mCopyCount) {
(*mCopyCount)++;
}
return *this;
}
int* mCopyCount;
};
TEST(CommonPool, asyncLifecycleCheck) {
std::vector<std::future<void>> mFrameFences;
int destroyCount = 0;
int runCount = 0;
{
DestructorObserver observer{&destroyCount};
auto func = [observer = std::move(observer), count = &runCount]() {
if (observer.mDestroyCount) {
(*count)++;
}
};
mFrameFences.push_back(CommonPool::async(std::move(func)));
}
for (auto& fence : mFrameFences) {
EXPECT_TRUE(fence.valid());
fence.get();
EXPECT_FALSE(fence.valid());
}
mFrameFences.clear();
EXPECT_EQ(1, runCount);
EXPECT_EQ(1, destroyCount);
}
TEST(CommonPool, asyncCopyCheck) {
std::vector<std::future<void>> mFrameFences;
int copyCount = 0;
int runCount = 0;
{
CopyObserver observer{&copyCount};
auto func = [observer = std::move(observer), count = &runCount]() {
if (observer.mCopyCount) {
(*count)++;
}
};
mFrameFences.push_back(CommonPool::async(std::move(func)));
}
for (auto& fence : mFrameFences) {
EXPECT_TRUE(fence.valid());
fence.get();
EXPECT_FALSE(fence.valid());
}
mFrameFences.clear();
EXPECT_EQ(1, runCount);
// We expect std::move all the way
EXPECT_EQ(0, copyCount);
}
TEST(CommonPool, syncLifecycleCheck) {
int destroyCount = 0;
int runCount = 0;
{
DestructorObserver observer{&destroyCount};
auto func = [observer = std::move(observer), count = &runCount]() {
if (observer.mDestroyCount) {
(*count)++;
}
};
CommonPool::runSync(std::move(func));
}
EXPECT_EQ(1, runCount);
EXPECT_EQ(1, destroyCount);
}
TEST(CommonPool, syncCopyCheck) {
int copyCount = 0;
int runCount = 0;
{
CopyObserver observer{&copyCount};
auto func = [observer = std::move(observer), count = &runCount]() {
if (observer.mCopyCount) {
(*count)++;
}
};
CommonPool::runSync(std::move(func));
}
EXPECT_EQ(1, runCount);
// We expect std::move all the way
EXPECT_EQ(0, copyCount);
}

View File

@@ -57,11 +57,13 @@ public:
mHead = newHead;
}
constexpr T&& pop() {
constexpr T pop() {
LOG_ALWAYS_FATAL_IF(mTail == mHead, "empty");
int index = mTail;
mTail = (mTail + 1) % SIZE;
return std::move(mBuffer[index]);
T ret = std::move(mBuffer[index]);
mBuffer[index] = nullptr;
return ret;
}
private: