From f1b52167c0b7f6f1a443d4cbff54e949aacf13d3 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Tue, 22 Jul 2025 21:10:00 +0200 Subject: [PATCH] Fixed an 'invalid lock sequence' when deleting the timeshift timer --- HISTORY | 3 ++- menu.c | 30 ++++++++++++++++++------------ menu.h | 4 +++- vdr.c | 4 +++- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/HISTORY b/HISTORY index 4c1e8662..e1cc0868 100644 --- a/HISTORY +++ b/HISTORY @@ -10138,7 +10138,7 @@ Video Disk Recorder Revision History - Fixed an invalid lock sequence when pressing the Channel+/Channel- keys while in the "What's on..." menu in live view. -2025-07-21: +2025-07-22: - Fixed cPoller::Poll() to allow negative timeout values again. - When regenerating the index of a recording, PID changes are now taken into account @@ -10173,3 +10173,4 @@ Video Disk Recorder Revision History - If an SVDRP peer connection is lost, the connection in the opposite direction is now also closed (reported by Markus Ehrnsperger). - Shutdown now takes into account the VPS margin (reported by Christoph Haubrich). +- Fixed an 'invalid lock sequence' when deleting the timeshift timer. diff --git a/menu.c b/menu.c index d03b2c0d..c0dd9901 100644 --- a/menu.c +++ b/menu.c @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.c 5.31 2025/07/06 15:06:55 kls Exp $ + * $Id: menu.c 5.32 2025/07/22 21:10:00 kls Exp $ */ #include "menu.h" @@ -5725,6 +5725,7 @@ int cAdaptiveSkipper::GetValue(eKeys Key) // --- cReplayControl -------------------------------------------------------- +cTimer *cReplayControl::timeshiftTimer = NULL; cReplayControl *cReplayControl::currentReplayControl = NULL; cString cReplayControl::fileName; @@ -5760,6 +5761,18 @@ cReplayControl::~cReplayControl() currentReplayControl = NULL; } +void cReplayControl::DelTimeshiftTimer(void) +{ + if (timeshiftTimer) { + LOCK_TIMERS_WRITE; + Timers->SetExplicitModify(); + Timers->Del(timeshiftTimer); + Timers->SetModified(); + isyslog("deleted timer %s", *timeshiftTimer->ToDescr()); + timeshiftTimer = NULL; + } +} + void cReplayControl::Stop(void) { Hide(); @@ -5769,17 +5782,10 @@ void cReplayControl::Stop(void) if (rc && rc->InstantId()) { if (Active()) { if (Setup.DelTimeshiftRec == 2 || Interface->Confirm(tr("Delete timeshift recording?"))) { - { - LOCK_TIMERS_WRITE; - Timers->SetExplicitModify(); - cTimer *Timer = rc->Timer(); - rc->Stop(false); // don't execute user command - if (Timer) { - Timers->Del(Timer); - Timers->SetModified(); - isyslog("deleted timer %s", *Timer->ToDescr()); - } - } + // At this point somewhere up the call stack there may be a lock on the Channels, so we can't + // lock the Timers here and have to delete this timer later: + timeshiftTimer = rc->Timer(); + rc->Stop(false); // don't execute user command cDvbPlayerControl::Stop(); bool Error = false; { diff --git a/menu.h b/menu.h index 9b5dc883..a95d6b42 100644 --- a/menu.h +++ b/menu.h @@ -4,7 +4,7 @@ * See the main source file 'vdr.c' for copyright information and * how to reach the author. * - * $Id: menu.h 5.6 2025/03/02 11:03:35 kls Exp $ + * $Id: menu.h 5.7 2025/07/22 21:10:00 kls Exp $ */ #ifndef __MENU_H @@ -292,6 +292,7 @@ public: class cReplayControl : public cDvbPlayerControl { private: + static cTimer *timeshiftTimer; cSkinDisplayReplay *displayReplay; cAdaptiveSkipper adaptiveSkipper; cMarks marks; @@ -322,6 +323,7 @@ private: public: cReplayControl(bool PauseLive = false); virtual ~cReplayControl() override; + static void DelTimeshiftTimer(void); void Stop(void); virtual cOsdObject *GetInfo(void) override; virtual const cRecording *GetRecording(void) override; diff --git a/vdr.c b/vdr.c index f3d36f6b..6e8fe787 100644 --- a/vdr.c +++ b/vdr.c @@ -22,7 +22,7 @@ * * The project's page is at https://www.tvdr.de * - * $Id: vdr.c 5.20 2025/07/06 15:06:55 kls Exp $ + * $Id: vdr.c 5.21 2025/07/22 21:10:00 kls Exp $ */ #include @@ -1594,6 +1594,8 @@ int main(int argc, char *argv[]) } } + cReplayControl::DelTimeshiftTimer(); + ReportEpgBugFixStats(); // Main thread hooks of plugins: