Fixed the locking sequence when switching between 'Now', 'Next' and 'Schedule' in the Schedules menu

This commit is contained in:
Klaus Schmidinger 2017-06-04 09:35:18 +02:00
parent 25d28e7421
commit ec47c4f932
2 changed files with 31 additions and 22 deletions

View File

@ -9056,7 +9056,7 @@ Video Disk Recorder Revision History
- Fixed detecting the inclusion of STL header files in tools.h (thanks to Jasmin
Jessich).
2017-05-31: Version 2.3.6
2017-06-04: Version 2.3.6
- Added backtrace functions for debugging (see cBackTrace in thread.h).
- Added checking the correct sequence of locking global lists (with help and
@ -9100,3 +9100,5 @@ Video Disk Recorder Revision History
- Fixed a possible crash in case the SVDRP connection to a peer VDR is terminated
while getting remote timers.
- Fixed the locking sequence when creating a new timer from the Schedules menu.
- Fixed the locking sequence when switching between 'Now', 'Next' and 'Schedule'
in the Schedules menu.

49
menu.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: menu.c 4.31 2017/06/03 12:49:38 kls Exp $
* $Id: menu.c 4.32 2017/06/04 09:30:56 kls Exp $
*/
#include "menu.h"
@ -1550,7 +1550,7 @@ private:
static int currentChannel;
static const cEvent *scheduleEvent;
bool Update(void);
void SetHelpKeys(void);
void SetHelpKeys(const cChannels *Channels);
public:
cMenuWhatsOn(const cTimers *Timers, const cChannels *Channels, const cSchedules *Schedules, bool Now, int CurrentChannelNr);
static int CurrentChannel(void) { return currentChannel; }
@ -1579,7 +1579,7 @@ cMenuWhatsOn::cMenuWhatsOn(const cTimers *Timers, const cChannels *Channels, con
}
currentChannel = CurrentChannelNr;
Display();
SetHelpKeys();
SetHelpKeys(Channels);
}
bool cMenuWhatsOn::Update(void)
@ -1595,7 +1595,7 @@ bool cMenuWhatsOn::Update(void)
return result;
}
void cMenuWhatsOn::SetHelpKeys(void)
void cMenuWhatsOn::SetHelpKeys(const cChannels *Channels)
{
cMenuScheduleItem *item = (cMenuScheduleItem *)Get(Current());
canSwitch = false;
@ -1609,7 +1609,6 @@ void cMenuWhatsOn::SetHelpKeys(void)
NewHelpKeys |= 0x04; // "Next"
else
NewHelpKeys |= 0x08; // "Now"
LOCK_CHANNELS_READ;
if (const cChannel *Channel = Channels->GetByChannelID(item->event->ChannelID(), true)) {
if (Channel->Number() != cDevice::CurrentChannel()) {
NewHelpKeys |= 0x10; // "Switch"
@ -1651,7 +1650,6 @@ eOSState cMenuWhatsOn::Switch(void)
eOSState cMenuWhatsOn::Record(void)
{
if (cMenuScheduleItem *item = (cMenuScheduleItem *)Get(Current())) {
{
LOCK_TIMERS_WRITE;
LOCK_CHANNELS_READ;
LOCK_SCHEDULES_READ;
@ -1676,12 +1674,11 @@ eOSState cMenuWhatsOn::Record(void)
// must add the timer before HandleRemoteModifications to get proper log messages with timer ids
Timers->Del(Timer);
}
}
if (HasSubMenu())
CloseSubMenu();
if (Update())
Display();
SetHelpKeys();
SetHelpKeys(Channels);
}
return osContinue;
}
@ -1716,7 +1713,8 @@ eOSState cMenuWhatsOn::ProcessKey(eKeys Key)
if (((cMenuScheduleItem *)item)->channel->Number() == cDevice::CurrentChannel()) {
SetCurrent(item);
Display();
SetHelpKeys();
LOCK_CHANNELS_READ;
SetHelpKeys(Channels);
break;
}
}
@ -1735,8 +1733,10 @@ eOSState cMenuWhatsOn::ProcessKey(eKeys Key)
else if (!HasSubMenu()) {
if (HadSubMenu && Update())
Display();
if (Key != kNone)
SetHelpKeys();
if (Key != kNone) {
LOCK_CHANNELS_READ;
SetHelpKeys(Channels);
}
}
return state;
}
@ -1751,7 +1751,7 @@ private:
bool now, next;
bool canSwitch;
int helpKeys;
void Set(const cChannel *Channel = NULL, bool Force = false);
void Set(const cTimers *Timers, const cChannels *Channels, const cChannel *Channel = NULL, bool Force = false);
eOSState Number(void);
eOSState Record(void);
eOSState Switch(void);
@ -1777,7 +1777,9 @@ cMenuSchedule::cMenuSchedule(void)
helpKeys = 0;
cMenuScheduleItem::SetSortMode(cMenuScheduleItem::ssmAllThis);
cMenuWhatsOn::SetCurrentChannel(cDevice::CurrentChannel());
Set(NULL, true);
LOCK_TIMERS_READ;
LOCK_CHANNELS_READ;
Set(Timers, Channels, NULL, true);
}
cMenuSchedule::~cMenuSchedule()
@ -1785,14 +1787,12 @@ cMenuSchedule::~cMenuSchedule()
cMenuWhatsOn::ScheduleEvent(); // makes sure any posted data is cleared
}
void cMenuSchedule::Set(const cChannel *Channel, bool Force)
void cMenuSchedule::Set(const cTimers *Timers, const cChannels *Channels, const cChannel *Channel, bool Force)
{
if (Force) {
schedulesStateKey.Reset();
scheduleState = -1;
}
LOCK_TIMERS_READ;
LOCK_CHANNELS_READ;
if (const cSchedules *Schedules = cSchedules::GetSchedulesRead(schedulesStateKey)) {
cMenuScheduleItem *CurrentItem = (cMenuScheduleItem *)Get(Current());
const cEvent *Event = NULL;
@ -1942,7 +1942,9 @@ void cMenuSchedule::SetHelpKeys(void)
eOSState cMenuSchedule::Number(void)
{
cMenuScheduleItem::IncSortMode();
Set(NULL, true);
LOCK_TIMERS_READ;
LOCK_CHANNELS_READ;
Set(Timers, Channels, NULL, true);
return osContinue;
}
@ -2003,8 +2005,11 @@ eOSState cMenuSchedule::Switch(void)
eOSState cMenuSchedule::ProcessKey(eKeys Key)
{
if (!HasSubMenu())
Set(); // react on any changes to the schedules list
if (!HasSubMenu()) {
LOCK_TIMERS_READ;
LOCK_CHANNELS_READ;
Set(Timers, Channels); // react on any changes to the schedules list
}
bool HadSubMenu = HasSubMenu();
eOSState state = cOsdMenu::ProcessKey(Key);
@ -2043,9 +2048,10 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key)
case kChanUp:
case kChanDn|k_Repeat:
case kChanDn: if (!HasSubMenu()) {
LOCK_TIMERS_READ;
LOCK_CHANNELS_READ;
if (const cChannel *Channel = Channels->GetByNumber(cDevice::CurrentChannel()))
Set(Channel, true);
Set(Timers, Channels, Channel, true);
}
break;
case kInfo:
@ -2062,10 +2068,11 @@ eOSState cMenuSchedule::ProcessKey(eKeys Key)
else if (!HasSubMenu()) {
now = next = false;
if (const cEvent *ei = cMenuWhatsOn::ScheduleEvent()) {
LOCK_TIMERS_READ;
LOCK_CHANNELS_READ;
if (const cChannel *Channel = Channels->GetByChannelID(ei->ChannelID(), true)) {
cMenuScheduleItem::SetSortMode(cMenuScheduleItem::ssmAllThis);
Set(Channel, true);
Set(Timers, Channels, Channel, true);
}
}
else if (HadSubMenu && Update())