drm_hwcomposer: Clean up VsyncWorker destruction
With VsyncWorker no longer acquiring the main lock, we can use
std::thread::join on the main thread to ensure that the vsync thread is
stopped cleanly in the VSyncWorker destructor.
- Don't pass a shared_ptr<> into VSyncWorker::ThreadFn to simplify
lifetime management
- Change to unique_ptr to simplify lifetime management
- Remove the hack to destroy the HwcDisplays in two stages when
destructing ComposerClient
- Add std::thread::join to VSyncWorker destructor
Change-Id: I25a34fd304c7b2ec48e43d538bf15794bdc9d68e
Signed-off-by: Drew Davenport <ddavenport@google.com>
diff --git a/drm/VSyncWorker.cpp b/drm/VSyncWorker.cpp
index ac80da4..64152ab 100644
--- a/drm/VSyncWorker.cpp
+++ b/drm/VSyncWorker.cpp
@@ -31,8 +31,8 @@
namespace android {
auto VSyncWorker::CreateInstance(std::shared_ptr<DrmDisplayPipeline> &pipe)
- -> std::shared_ptr<VSyncWorker> {
- auto vsw = std::shared_ptr<VSyncWorker>(new VSyncWorker());
+ -> std::unique_ptr<VSyncWorker> {
+ auto vsw = std::unique_ptr<VSyncWorker>(new VSyncWorker());
if (pipe) {
vsw->high_crtc_ = pipe->crtc->Get()->GetIndexInResArray()
@@ -40,11 +40,17 @@
vsw->drm_fd_ = pipe->device->GetFd();
}
- std::thread(&VSyncWorker::ThreadFn, vsw.get(), vsw).detach();
+ vsw->vswt_ = std::thread(&VSyncWorker::ThreadFn, vsw.get());
return vsw;
}
+VSyncWorker::~VSyncWorker() {
+ StopThread();
+
+ vswt_.join();
+}
+
void VSyncWorker::UpdateVSyncControl() {
{
const std::lock_guard<std::mutex> lock(mutex_);
@@ -143,17 +149,17 @@
return 0;
}
-void VSyncWorker::ThreadFn(const std::shared_ptr<VSyncWorker> &vsw) {
+void VSyncWorker::ThreadFn() {
int ret = 0;
for (;;) {
{
- std::unique_lock<std::mutex> lock(vsw->mutex_);
+ std::unique_lock<std::mutex> lock(mutex_);
if (thread_exit_)
break;
if (!enabled_)
- vsw->cv_.wait(lock);
+ cv_.wait(lock);
if (!enabled_)
continue;