summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2020-12-12 22:01:01 +0100
committerKlaus Schmidinger <vdr@tvdr.de>2020-12-12 22:01:01 +0100
commit79a3607d0c220797ebf9449dd2d49221e2761fda (patch)
treea9bd119998bf1ad4ff82c2dc4016828a287eafc1
parentdffeabbacb5f36d514a8e3702f73e736c71ad099 (diff)
downloadvdr-79a3607d0c220797ebf9449dd2d49221e2761fda.tar.gz
vdr-79a3607d0c220797ebf9449dd2d49221e2761fda.tar.bz2
Avoiding a lengthy lock on the Channels list when starting a recording
-rw-r--r--CONTRIBUTORS1
-rw-r--r--HISTORY2
-rw-r--r--menu.c16
3 files changed, 17 insertions, 2 deletions
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index c6efd469..1c1602f8 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -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
diff --git a/HISTORY b/HISTORY
index b1167360..b0467e9e 100644
--- a/HISTORY
+++ b/HISTORY
@@ -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).
diff --git a/menu.c b/menu.c
index 1a295dc7..724c0a22 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.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;
}