diff options
author | Klaus Schmidinger <vdr@tvdr.de> | 2020-12-12 22:01:01 +0100 |
---|---|---|
committer | Klaus Schmidinger <vdr@tvdr.de> | 2020-12-12 22:01:01 +0100 |
commit | 79a3607d0c220797ebf9449dd2d49221e2761fda (patch) | |
tree | a9bd119998bf1ad4ff82c2dc4016828a287eafc1 /menu.c | |
parent | dffeabbacb5f36d514a8e3702f73e736c71ad099 (diff) | |
download | vdr-79a3607d0c220797ebf9449dd2d49221e2761fda.tar.gz vdr-79a3607d0c220797ebf9449dd2d49221e2761fda.tar.bz2 |
Avoiding a lengthy lock on the Channels list when starting a recording
Diffstat (limited to 'menu.c')
-rw-r--r-- | menu.c | 16 |
1 files changed, 14 insertions, 2 deletions
@@ -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; } |