Merge "Revert "Revert "Fix lifecycle issue in CommonPool""" into qt-dev

am: 8bffd47f7a

Change-Id: I2ed2441c68abf1e8e3117f9ac3d75d5b405a11e6
This commit is contained in:
John Reck
2019-04-10 12:08:26 -07:00
committed by android-build-merger
3 changed files with 73 additions and 4 deletions

View File

@@ -135,4 +135,48 @@ TEST(CommonPool, fullQueue) {
for (auto& f : futures) { for (auto& f : futures) {
f.get(); f.get();
} }
}
class ObjectTracker {
static std::atomic_int sGlobalCount;
public:
ObjectTracker() {
sGlobalCount++;
}
ObjectTracker(const ObjectTracker&) {
sGlobalCount++;
}
ObjectTracker(ObjectTracker&&) {
sGlobalCount++;
}
~ObjectTracker() {
sGlobalCount--;
}
static int count() { return sGlobalCount.load(); }
};
std::atomic_int ObjectTracker::sGlobalCount{0};
TEST(CommonPool, asyncLifecycleCheck) {
ASSERT_EQ(0, ObjectTracker::count());
{
ObjectTracker obj;
ASSERT_EQ(1, ObjectTracker::count());
EXPECT_LT(1, CommonPool::async([obj] { return ObjectTracker::count(); }).get());
}
CommonPool::waitForIdle();
ASSERT_EQ(0, ObjectTracker::count());
}
TEST(CommonPool, syncLifecycleCheck) {
ASSERT_EQ(0, ObjectTracker::count());
{
ObjectTracker obj;
ASSERT_EQ(1, ObjectTracker::count());
EXPECT_LT(1, CommonPool::runSync([obj] { return ObjectTracker::count(); }));
}
CommonPool::waitForIdle();
ASSERT_EQ(0, ObjectTracker::count());
} }

View File

@@ -49,9 +49,13 @@ CommonPool::CommonPool() {
} }
} }
void CommonPool::post(Task&& task) { CommonPool& CommonPool::instance() {
static CommonPool pool; static CommonPool pool;
pool.enqueue(std::move(task)); return pool;
}
void CommonPool::post(Task&& task) {
instance().enqueue(std::move(task));
} }
void CommonPool::enqueue(Task&& task) { void CommonPool::enqueue(Task&& task) {
@@ -86,5 +90,18 @@ void CommonPool::workerLoop() {
} }
} }
void CommonPool::waitForIdle() {
instance().doWaitForIdle();
}
void CommonPool::doWaitForIdle() {
std::unique_lock lock(mLock);
while (mWaitingThreads != THREAD_COUNT) {
lock.unlock();
usleep(100);
lock.lock();
}
}
} // namespace uirenderer } // namespace uirenderer
} // namespace android } // namespace android

View File

@@ -57,11 +57,13 @@ public:
mHead = newHead; mHead = newHead;
} }
constexpr T&& pop() { constexpr T pop() {
LOG_ALWAYS_FATAL_IF(mTail == mHead, "empty"); LOG_ALWAYS_FATAL_IF(mTail == mHead, "empty");
int index = mTail; int index = mTail;
mTail = (mTail + 1) % SIZE; mTail = (mTail + 1) % SIZE;
return std::move(mBuffer[index]); T ret = std::move(mBuffer[index]);
mBuffer[index] = nullptr;
return ret;
} }
private: private:
@@ -95,11 +97,17 @@ public:
return task.get_future().get(); return task.get_future().get();
}; };
// For testing purposes only, blocks until all worker threads are parked.
static void waitForIdle();
private: private:
static CommonPool& instance();
CommonPool(); CommonPool();
~CommonPool() {} ~CommonPool() {}
void enqueue(Task&&); void enqueue(Task&&);
void doWaitForIdle();
void workerLoop(); void workerLoop();