diff options
| author | vaxerski <vaxry@vaxry.net> | 2025-08-16 16:52:28 +0200 |
|---|---|---|
| committer | vaxerski <vaxry@vaxry.net> | 2025-08-16 16:52:40 +0200 |
| commit | 78c9e2080c800e9da0792b73ca436ef49384bfb7 (patch) | |
| tree | 29fb029e91650aa00e26bd3c6a2f01f20b1d3137 /src/helpers/MonitorFrameScheduler.cpp | |
| parent | 1cbb62ed6a3d9232448a89fe569d253794e5f114 (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.cpp | 22 |
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(); }); |
