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
PMT pid were checked any more
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>
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).
- Fixed PMT handling in case locking the Channels list times out (reported by Helmut
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
* 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"
@ -5229,6 +5229,11 @@ cRecordControl::cRecordControl(cDevice *Device, cTimers *Timers, cTimer *Timer,
const char *LastReplayed = cReplayControl::LastReplayed(); // must do this before locking schedules!
// Whatever happens here, the timers will be modified in some way...
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
// others from modifying any EPG data:
cStateKey SchedulesStateKey;
@ -5244,6 +5249,7 @@ cRecordControl::cRecordControl(cDevice *Device, cTimers *Timers, cTimer *Timer,
timer = new cTimer(true, Pause);
Timers->Add(timer);
instantId = cString::sprintf(cDevice::NumDevices() > 1 ? "%s - %d" : "%s", timer->Channel()->Name(), device->DeviceNumber() + 1);
ChannelsStateKey.Remove();
}
timer->SetPending(true);
timer->SetRecording(true);
@ -5380,7 +5386,8 @@ bool cRecordControls::Start(cTimers *Timers, cTimer *Timer, bool Pause)
LastNoDiskSpaceMessage = 0;
ChangeState();
LOCK_CHANNELS_READ;
cStateKey StateKey;
const cChannels *Channels = cChannels::GetChannelsRead(StateKey);
int ch = Timer ? Timer->Channel()->Number() : cDevice::CurrentChannel();
if (const cChannel *Channel = Channels->GetByNumber(ch)) {
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) {
dsyslog("switching device %d to channel %d %s (%s)", device->DeviceNumber() + 1, Channel->Number(), *Channel->GetChannelID().ToString(), Channel->Name());
if (!device->SwitchChannel(Channel, false)) {
StateKey.Remove();
ShutdownHandler.RequestEmergencyExit();
return false;
}
StateKey.Remove();
Channels = NULL;
if (!Timer || Timer->Matches()) {
for (int i = 0; i < MAXRECORDCONTROLS; i++) {
if (!RecordControls[i]) {
@ -5407,6 +5417,8 @@ bool cRecordControls::Start(cTimers *Timers, cTimer *Timer, bool Pause)
}
else
esyslog("ERROR: channel %d not defined!", ch);
if (Channels)
StateKey.Remove();
return false;
}