drm_hwcomposer: fix null deref happening when clearing callback
The attempt at clearing the callback happens after the vsync worker has
been de-init-ed, the mutex is no longer valid and this causes a crash
when trying to guard_lock it.
This can be reproduced by unplugging an external monitor.
TEST: manual
Change-Id: I1eecdee84706683de1c953c17ce26ebfa3a24d9f
Signed-off-by: Lucas Berthou <berlu@google.com>
diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp
index 60861af..3469c85 100644
--- a/hwc2_device/HwcDisplay.cpp
+++ b/hwc2_device/HwcDisplay.cpp
@@ -1047,20 +1047,21 @@
if (type_ == HWC2::DisplayType::Virtual) {
return HWC2::Error::None;
}
+ if (!vsync_worker_) {
+ return HWC2::Error::NoResources;
+ }
vsync_event_en_ = HWC2_VSYNC_ENABLE == enabled;
-
+ std::optional<VSyncWorker::VsyncTimestampCallback> callback = std::nullopt;
if (vsync_event_en_) {
DrmHwc *hwc = hwc_;
hwc2_display_t id = handle_;
// Callback will be called from the vsync thread.
- auto callback = [hwc, id](int64_t timestamp, uint32_t period_ns) {
+ callback = [hwc, id](int64_t timestamp, uint32_t period_ns) {
hwc->SendVsyncEventToClient(id, timestamp, period_ns);
};
- vsync_worker_->SetTimestampCallback(callback);
- } else {
- vsync_worker_->SetTimestampCallback(std::nullopt);
}
+ vsync_worker_->SetTimestampCallback(std::move(callback));
return HWC2::Error::None;
}