1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Avoiding a lengthy lock on the Channels list when starting a recording

This commit is contained in:
Klaus Schmidinger 2020-12-12 22:01:01 +01:00
parent dffeabbacb
commit 79a3607d0c
3 changed files with 17 additions and 2 deletions

View File

@ -3639,6 +3639,7 @@ Helmut Binder <cco@aon.at>
for fixing a bug in handling shared PMTs, where after the first pass not all SIDs of a for fixing a bug in handling shared PMTs, where after the first pass not all SIDs of a
PMT pid were checked any more PMT pid were checked any more
for reporting a problem with PMT handling in case locking the Channels list times out for reporting a problem with PMT handling in case locking the Channels list times out
for avoiding a lengthy lock on the Channels list when starting a recording
Ulrich Eckhardt <uli@uli-eckhardt.de> Ulrich Eckhardt <uli@uli-eckhardt.de>
for reporting a problem with shutdown after user inactivity in case a plugin is for reporting a problem with shutdown after user inactivity in case a plugin is

View File

@ -9553,3 +9553,5 @@ Video Disk Recorder Revision History
PMT pid were checked any more (thanks to Helmut Binder). PMT pid were checked any more (thanks to Helmut Binder).
- Fixed PMT handling in case locking the Channels list times out (reported by Helmut - Fixed PMT handling in case locking the Channels list times out (reported by Helmut
Binder). Binder).
- Avoiding a lengthy lock on the Channels list when starting a recording (thanks to
Helmut Binder).

16
menu.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: menu.c 4.87 2020/11/06 13:13:05 kls Exp $ * $Id: menu.c 4.88 2020/12/12 22:01:01 kls Exp $
*/ */
#include "menu.h" #include "menu.h"
@ -5229,6 +5229,11 @@ cRecordControl::cRecordControl(cDevice *Device, cTimers *Timers, cTimer *Timer,
const char *LastReplayed = cReplayControl::LastReplayed(); // must do this before locking schedules! const char *LastReplayed = cReplayControl::LastReplayed(); // must do this before locking schedules!
// Whatever happens here, the timers will be modified in some way... // Whatever happens here, the timers will be modified in some way...
Timers->SetModified(); Timers->SetModified();
cStateKey ChannelsStateKey;
// To create a new timer, we need to make shure there is
// a lock on Channels prior to the Schedules locking below
if (!Timer)
cChannels::GetChannelsRead(ChannelsStateKey);
// We're going to work with an event here, so we need to prevent // We're going to work with an event here, so we need to prevent
// others from modifying any EPG data: // others from modifying any EPG data:
cStateKey SchedulesStateKey; cStateKey SchedulesStateKey;
@ -5244,6 +5249,7 @@ cRecordControl::cRecordControl(cDevice *Device, cTimers *Timers, cTimer *Timer,
timer = new cTimer(true, Pause); timer = new cTimer(true, Pause);
Timers->Add(timer); Timers->Add(timer);
instantId = cString::sprintf(cDevice::NumDevices() > 1 ? "%s - %d" : "%s", timer->Channel()->Name(), device->DeviceNumber() + 1); instantId = cString::sprintf(cDevice::NumDevices() > 1 ? "%s - %d" : "%s", timer->Channel()->Name(), device->DeviceNumber() + 1);
ChannelsStateKey.Remove();
} }
timer->SetPending(true); timer->SetPending(true);
timer->SetRecording(true); timer->SetRecording(true);
@ -5380,7 +5386,8 @@ bool cRecordControls::Start(cTimers *Timers, cTimer *Timer, bool Pause)
LastNoDiskSpaceMessage = 0; LastNoDiskSpaceMessage = 0;
ChangeState(); ChangeState();
LOCK_CHANNELS_READ; cStateKey StateKey;
const cChannels *Channels = cChannels::GetChannelsRead(StateKey);
int ch = Timer ? Timer->Channel()->Number() : cDevice::CurrentChannel(); int ch = Timer ? Timer->Channel()->Number() : cDevice::CurrentChannel();
if (const cChannel *Channel = Channels->GetByNumber(ch)) { if (const cChannel *Channel = Channels->GetByNumber(ch)) {
int Priority = Timer ? Timer->Priority() : Pause ? Setup.PausePriority : Setup.DefaultPriority; int Priority = Timer ? Timer->Priority() : Pause ? Setup.PausePriority : Setup.DefaultPriority;
@ -5388,9 +5395,12 @@ bool cRecordControls::Start(cTimers *Timers, cTimer *Timer, bool Pause)
if (device) { if (device) {
dsyslog("switching device %d to channel %d %s (%s)", device->DeviceNumber() + 1, Channel->Number(), *Channel->GetChannelID().ToString(), Channel->Name()); dsyslog("switching device %d to channel %d %s (%s)", device->DeviceNumber() + 1, Channel->Number(), *Channel->GetChannelID().ToString(), Channel->Name());
if (!device->SwitchChannel(Channel, false)) { if (!device->SwitchChannel(Channel, false)) {
StateKey.Remove();
ShutdownHandler.RequestEmergencyExit(); ShutdownHandler.RequestEmergencyExit();
return false; return false;
} }
StateKey.Remove();
Channels = NULL;
if (!Timer || Timer->Matches()) { if (!Timer || Timer->Matches()) {
for (int i = 0; i < MAXRECORDCONTROLS; i++) { for (int i = 0; i < MAXRECORDCONTROLS; i++) {
if (!RecordControls[i]) { if (!RecordControls[i]) {
@ -5407,6 +5417,8 @@ bool cRecordControls::Start(cTimers *Timers, cTimer *Timer, bool Pause)
} }
else else
esyslog("ERROR: channel %d not defined!", ch); esyslog("ERROR: channel %d not defined!", ch);
if (Channels)
StateKey.Remove();
return false; return false;
} }