From d380b57d2849d0df66c14995130dcbbfadbc9d1f Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Sun, 6 May 2018 09:41:03 +0200 Subject: [PATCH] Fixed locking the Channels list in cDisplayChannel, where the lock was still held when Flush() was called --- CONTRIBUTORS | 2 ++ HISTORY | 4 ++- menu.c | 71 ++++++++++++++++++++++++++++------------------------ 3 files changed, 43 insertions(+), 34 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 1875defc..73162045 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -3316,6 +3316,8 @@ Matthias Senzel after starting the editing process for reporting a problem with setting the initial offset of the cursor in a list menu for reporting a high CPU load during replay with active progress display + for reporting that the lock on the Channels list in cDisplayChannel was still held + when Flush() was called Marek Nazarko for translating OSD texts to the Polish language diff --git a/HISTORY b/HISTORY index 06500b8e..23dfa28a 100644 --- a/HISTORY +++ b/HISTORY @@ -9348,7 +9348,7 @@ Video Disk Recorder Revision History Senzel). - Official release. -2018-04-28: Version 2.4.1 +2018-05-06: Version 2.4.1 - Fixed handling the tfRecording flag in the SVDRP commands MODT and UPDT (reported by Johann Friedrichs). @@ -9359,3 +9359,5 @@ Video Disk Recorder Revision History been changed to Skins.QueueMessage(), and cSkins::ProcessQueuedMessages() is now called unconditionally in the main loop, and checks whether the current cSkinDisplay object (if any) implements SetMessage(). +- Fixed locking the Channels list in cDisplayChannel, where the lock was still held + when Flush() was called (reported by Matthias Senzel). diff --git a/menu.c b/menu.c index 686806a0..a9ea49d2 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 4.75 2018/04/28 12:09:45 kls Exp $ + * $Id: menu.c 4.76 2018/05/06 09:30:11 kls Exp $ */ #include "menu.h" @@ -4626,14 +4626,17 @@ cDisplayChannel::cDisplayChannel(int Number, bool Switched) cOsdProvider::OsdSizeChanged(osdState); // just to get the current state positioner = NULL; channel = NULL; - LOCK_CHANNELS_READ; - channel = Channels->GetByNumber(Number); - lastPresent = lastFollowing = NULL; - if (channel) { - DisplayChannel(); - DisplayInfo(); + { + LOCK_CHANNELS_READ; + channel = Channels->GetByNumber(Number); + lastPresent = lastFollowing = NULL; + if (channel) { + DisplayChannel(); + DisplayInfo(); + } + } + if (channel) displayChannel->Flush(); - } lastTime.Set(); } @@ -4868,31 +4871,33 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key) } }; if (positioner || !timeout || lastTime.Elapsed() < (uint64_t)(Setup.ChannelInfoTime * 1000)) { - LOCK_CHANNELS_READ; - if (Key == kNone && !number && group < 0 && !NewChannel && channel && channel->Number() != cDevice::CurrentChannel()) { - // makes sure a channel switch through the SVDRP CHAN command is displayed - channel = Channels->GetByNumber(cDevice::CurrentChannel()); - Refresh(); - lastTime.Set(); - } - DisplayInfo(); - if (NewChannel) { - SetTrackDescriptions(NewChannel->Number()); // to make them immediately visible in the channel display - Channels->SwitchTo(NewChannel->Number()); - SetTrackDescriptions(NewChannel->Number()); // switching the channel has cleared them - channel = NewChannel; - } - const cPositioner *Positioner = cDevice::ActualDevice()->Positioner(); - bool PositionerMoving = Positioner && Positioner->IsMoving(); - SetNeedsFastResponse(PositionerMoving); - if (!PositionerMoving) { - if (positioner) - lastTime.Set(); // to keep the channel display up a few seconds after the target position has been reached - Positioner = NULL; - } - if (Positioner || positioner) // making sure we call SetPositioner(NULL) if there is a switch from "with" to "without" positioner - displayChannel->SetPositioner(Positioner); - positioner = Positioner; + { + LOCK_CHANNELS_READ; + if (Key == kNone && !number && group < 0 && !NewChannel && channel && channel->Number() != cDevice::CurrentChannel()) { + // makes sure a channel switch through the SVDRP CHAN command is displayed + channel = Channels->GetByNumber(cDevice::CurrentChannel()); + Refresh(); + lastTime.Set(); + } + DisplayInfo(); + if (NewChannel) { + SetTrackDescriptions(NewChannel->Number()); // to make them immediately visible in the channel display + Channels->SwitchTo(NewChannel->Number()); + SetTrackDescriptions(NewChannel->Number()); // switching the channel has cleared them + channel = NewChannel; + } + const cPositioner *Positioner = cDevice::ActualDevice()->Positioner(); + bool PositionerMoving = Positioner && Positioner->IsMoving(); + SetNeedsFastResponse(PositionerMoving); + if (!PositionerMoving) { + if (positioner) + lastTime.Set(); // to keep the channel display up a few seconds after the target position has been reached + Positioner = NULL; + } + if (Positioner || positioner) // making sure we call SetPositioner(NULL) if there is a switch from "with" to "without" positioner + displayChannel->SetPositioner(Positioner); + positioner = Positioner; + } displayChannel->Flush(); return osContinue; }