summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY2
-rw-r--r--MANUAL6
-rw-r--r--timers.c49
-rw-r--r--timers.h4
4 files changed, 35 insertions, 26 deletions
diff --git a/HISTORY b/HISTORY
index 6667d23e..78b081a8 100644
--- a/HISTORY
+++ b/HISTORY
@@ -9652,3 +9652,5 @@ Video Disk Recorder Revision History
was "remote").
- Now adjusting spawned timers before setting events to timers.
- Fixed dropping outdated events.
+- To avoid problems with very short events, non-VPS pattern timers now spawn timers for all
+ matching events that would start while the first one is still recording.
diff --git a/MANUAL b/MANUAL
index 640a9094..4553b78b 100644
--- a/MANUAL
+++ b/MANUAL
@@ -540,9 +540,9 @@ The following rules apply to pattern timers:
with the given start/stop time. Overlapping events are recorded in full,
even if they extend outside the given start/stop interval.
- In order to actually record an event, a pattern timer "spawns" a separate timer
- that does the recording. At most two timers are spawned from a pattern timer at
- any given time, one for the next upcoming matching event, and one for
- the event immediately following that one, in case it also matches.
+ that does the recording. If there are matching events that would start while
+ the first spawned timer is still recording (due to the start/stop margins), timers
+ for those events are also spawned.
- Spawned timers are marked with the flag tfSpawned.
- Spawned timers take the Priority, Lifetime and VPS settings from the pattern timer.
- The special pattern "*" matches every event. So a timer with
diff --git a/timers.c b/timers.c
index ab4938a8..c1e5bf99 100644
--- a/timers.c
+++ b/timers.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: timers.c 5.11 2021/04/10 11:32:50 kls Exp $
+ * $Id: timers.c 5.12 2021/04/13 13:54:00 kls Exp $
*/
#include "timers.h"
@@ -708,7 +708,7 @@ void cTimer::SetId(int Id)
id = Id;
}
-void cTimer::SpawnPatternTimer(const cEvent *Event, cTimers *Timers)
+cTimer *cTimer::SpawnPatternTimer(const cEvent *Event, cTimers *Timers)
{
cString FileName = MakePatternFileName(Pattern(), Event->Title(), Event->ShortText(), File());
isyslog("spawning timer %s for event %s", *ToDescr(), *Event->ToDescr());
@@ -718,6 +718,7 @@ void cTimer::SpawnPatternTimer(const cEvent *Event, cTimers *Timers)
t->SetFlags(tfAvoid);
Timers->Add(t);
HandleRemoteTimerModifications(t);
+ return t;
}
bool cTimer::SpawnPatternTimers(const cSchedules *Schedules, cTimers *Timers)
@@ -727,30 +728,36 @@ bool cTimer::SpawnPatternTimers(const cSchedules *Schedules, cTimers *Timers)
if (Schedule && Schedule->Events()->First()) {
if (Schedule->Modified(scheduleStateSpawn)) {
time_t Now = time(NULL);
+ // Find the first event that matches this pattern timer and either already has a spawned
+ // timer, or has not yet ended:
for (const cEvent *e = Schedule->Events()->First(); e; e = Schedule->Events()->Next(e)) {
if (Matches(e) != tmNone) {
- bool CheckThis = false;
- bool CheckNext = false;
- if (Timers->GetTimerForEvent(e, tfSpawned)) // a matching event that already has a spawned timer
- CheckNext = true;
- else if (e->EndTime() > Now) { // only look at events that have not yet ended
- CheckThis = true;
- CheckNext = true;
- }
- if (CheckThis) {
- SpawnPatternTimer(e, Timers);
+ const cTimer *Timer = Timers->GetTimerForEvent(e, tfSpawned); // a matching event that already has a spawned timer
+ if (!Timer && e->EndTime() > Now) { // only look at events that have not yet ended
+ Timer = SpawnPatternTimer(e, Timers);
TimersSpawned = true;
}
- if (CheckNext) {
- // We also check the event immediately following this one:
- e = Schedule->Events()->Next(e);
- if (e && !Timers->GetTimerForEvent(e, tfSpawned) && Matches(e) != tmNone) {
- SpawnPatternTimer(e, Timers);
- TimersSpawned = true;
- }
- }
- if (CheckThis || CheckNext)
+ if (Timer) {
+ // Check all following matching events that would start while the first timer
+ // is still recording:
+ bool UseVps = Timer->HasFlags(tfVps);
+ time_t Limit = Timer->StopTime() + EXPIRELATENCY;
+ if (!UseVps)
+ Limit += Setup.MarginStart * 60;
+ for (e = Schedule->Events()->Next(e); e; e = Schedule->Events()->Next(e)) {
+ if (e->StartTime() <= Limit) {
+ if (!Timers->GetTimerForEvent(e, tfSpawned) && Matches(e) != tmNone) {
+ SpawnPatternTimer(e, Timers);
+ TimersSpawned = true;
+ }
+ if (UseVps)
+ break; // with VPS we only need to check the event immediately following the first one
+ }
+ else
+ break; // no need to check events that are too far in the future
+ }
break;
+ }
}
}
}
diff --git a/timers.h b/timers.h
index 18c8362d..fea94aec 100644
--- a/timers.h
+++ b/timers.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: timers.h 5.5 2021/04/10 10:09:50 kls Exp $
+ * $Id: timers.h 5.6 2021/04/13 13:54:00 kls Exp $
*/
#ifndef __TIMERS_H
@@ -99,7 +99,7 @@ public:
time_t StartTime(void) const;
time_t StopTime(void) const;
void SetId(int Id);
- void SpawnPatternTimer(const cEvent *Event, cTimers *Timers);
+ cTimer *SpawnPatternTimer(const cEvent *Event, cTimers *Timers);
bool SpawnPatternTimers(const cSchedules *Schedules, cTimers *Timers);
bool AdjustSpawnedTimer(void);
void TriggerRespawn(void);