summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author John Reck <jreck@google.com> 2019-04-04 15:49:40 -0700
committer John Reck <jreck@google.com> 2019-04-04 16:05:10 -0700
commit5ff61f32a78dca0c722c8ac2685874a26190ceed (patch)
treef795a2a4c2d8c4386a0be6840e0f0f96ad020c25
parentdd07ae579c291a2b6ffe09bd576fd908eb9e5ddd (diff)
Fix lifecycle issue in CommonPool
Destroy things more faster Fixes: 129250875 Test: hwui_unit_tests Change-Id: I7e060fcb61f5321dd9e68a3ee4a01868033b3fc3
-rw-r--r--libs/hwui/tests/unit/CommonPoolTests.cpp123
-rw-r--r--libs/hwui/thread/CommonPool.h6
2 files changed, 127 insertions, 2 deletions
diff --git a/libs/hwui/tests/unit/CommonPoolTests.cpp b/libs/hwui/tests/unit/CommonPoolTests.cpp
index c564ed632786..9c885ef0e29f 100644
--- a/libs/hwui/tests/unit/CommonPoolTests.cpp
+++ b/libs/hwui/tests/unit/CommonPoolTests.cpp
@@ -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);
} \ No newline at end of file
diff --git a/libs/hwui/thread/CommonPool.h b/libs/hwui/thread/CommonPool.h
index aef2990d6343..51628259d2a8 100644
--- a/libs/hwui/thread/CommonPool.h
+++ b/libs/hwui/thread/CommonPool.h
@@ -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: