Skip to content

Fix invalid lock sequence: move LOCK_TIMERS_READ out of rendering path#64

Merged
MegaV0lt merged 1 commit intoMegaV0lt:masterfrom
dnehring7:master
Mar 5, 2026
Merged

Fix invalid lock sequence: move LOCK_TIMERS_READ out of rendering path#64
MegaV0lt merged 1 commit intoMegaV0lt:masterfrom
dnehring7:master

Conversation

@dnehring7
Copy link
Copy Markdown

TopBarUpdate() is called from Flush(), which VDR's cEITScanner::Process() invokes while already holding the Channels read lock. RecCountCache.UpdateIfNeeded() acquired LOCK_TIMERS_READ inside that call chain, producing the sequence:

Channels(R) held → Timers(R) acquired

VDR requires Timers to be locked before Channels (lower ordinal first), so this is an invalid lock sequence reported at runtime.

Move the UpdateIfNeeded() call to cPluginFlat::Housekeeping(), which VDR calls periodically from the main loop with no global state locks held. The render path now only reads the atomic s_NumRecordings — zero locking.

TopBarUpdate() is called from Flush(), which VDR's cEITScanner::Process()
invokes while already holding the Channels read lock. RecCountCache.UpdateIfNeeded()
acquired LOCK_TIMERS_READ inside that call chain, producing the sequence:

    Channels(R) held → Timers(R) acquired

VDR requires Timers to be locked *before* Channels (lower ordinal first),
so this is an invalid lock sequence reported at runtime.

Move the UpdateIfNeeded() call to cPluginFlat::Housekeeping(), which VDR
calls periodically from the main loop with no global state locks held.
The render path now only reads the atomic s_NumRecordings — zero locking.
@MegaV0lt MegaV0lt merged commit 23346d7 into MegaV0lt:master Mar 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants