summaryrefslogtreecommitdiff
path: root/src/helpers/MonitorFrameScheduler.cpp
diff options
context:
space:
mode:
authorvaxerski <vaxry@vaxry.net>2025-08-16 16:52:28 +0200
committervaxerski <vaxry@vaxry.net>2025-08-16 16:52:40 +0200
commit78c9e2080c800e9da0792b73ca436ef49384bfb7 (patch)
tree29fb029e91650aa00e26bd3c6a2f01f20b1d3137 /src/helpers/MonitorFrameScheduler.cpp
parent1cbb62ed6a3d9232448a89fe569d253794e5f114 (diff)
framescheduler: fix edge case crashes
rare UAFs because renderMonitor can call onDisconnect (ugh, that should be changed...) fixes #11073
Diffstat (limited to 'src/helpers/MonitorFrameScheduler.cpp')
-rw-r--r--src/helpers/MonitorFrameScheduler.cpp22
1 files changed, 20 insertions, 2 deletions
diff --git a/src/helpers/MonitorFrameScheduler.cpp b/src/helpers/MonitorFrameScheduler.cpp
index 1ab4f19b..877e486f 100644
--- a/src/helpers/MonitorFrameScheduler.cpp
+++ b/src/helpers/MonitorFrameScheduler.cpp
@@ -36,7 +36,16 @@ void CMonitorFrameScheduler::onSyncFired() {
m_renderAtFrame = false; // block frame rendering, we already scheduled
m_lastRenderBegun = hrc::now();
+
+ // get a ref to ourselves. renderMonitor can destroy this scheduler if it decides to perform a monitor reload
+ // FIXME: this is horrible. "renderMonitor" should not be able to do that.
+ auto self = m_self;
+
g_pHyprRenderer->renderMonitor(m_monitor.lock(), false);
+
+ if (!self)
+ return;
+
onFinishRender();
}
@@ -99,14 +108,23 @@ void CMonitorFrameScheduler::onFrame() {
Debug::log(TRACE, "CMonitorFrameScheduler: {} -> frame event, render = true, rendering normally.", m_monitor->m_name);
m_lastRenderBegun = hrc::now();
+
+ // get a ref to ourselves. renderMonitor can destroy this scheduler if it decides to perform a monitor reload
+ // FIXME: this is horrible. "renderMonitor" should not be able to do that.
+ auto self = m_self;
+
g_pHyprRenderer->renderMonitor(m_monitor.lock());
+
+ if (!self)
+ return;
+
onFinishRender();
}
void CMonitorFrameScheduler::onFinishRender() {
m_sync = CEGLSync::create(); // this destroys the old sync
- g_pEventLoopManager->doOnReadable(m_sync->fd().duplicate(), [this, mon = m_monitor] {
- if (!mon) // might've gotten destroyed
+ g_pEventLoopManager->doOnReadable(m_sync->fd().duplicate(), [this, self = m_self] {
+ if (!self) // might've gotten destroyed
return;
onSyncFired();
});