Udo Richter wrote:
I just noticed a serious issue with a missed timer event. After a daily timer, VDR did an automatic shutdown, but not for the next day to record the same timer again, but for the next following timer event!

Ok, I was able to verify and debug this a bit. Using the attached patch, I was able to provoke and monitor this.

The attached patch adds debug code to GetNextActiveTimer, checking whether Matches() does anything, and whether StopTime() is in the past.

This log shows a daily timer running out:
Aug  3 01:33:28 vdr: timer 14 (1 0124-0135 'Das Erste') modified (active)
Aug  3 01:33:30 vdr: timer 14 (1 0124-0135 'Das Erste') start
Aug  3 01:33:39 vdr: Power button pressed
Aug  3 01:33:39 vdr: confirm: Aufnahme läuft - trotzdem ausschalten?
Aug  3 01:33:39 vdr: warning: Aufnahme läuft - trotzdem ausschalten?
Aug  3 01:33:50 vdr: not confirmed
Aug  3 01:35:00 vdr: timer 14 (1 0124-0135 'Das Erste') stop
Aug  3 01:35:01 vdr: Start/Stop Timer error: Start changed from Thu Aug  3 
01:24:00 2006 to Fri Aug  4 01:24:00 2006, stop from Thu Aug  3 01:35:00 2006 
to Fri Aug  4 01:35:00 2006
Aug  3 01:35:01 vdr: next timer event at Fri Aug  4 01:24:00 2006
Aug  3 01:35:01 vdr: confirm: Taste drücken, um Ausschalten abzubrechen
Aug  3 01:35:01 vdr: warning: Taste drücken, um Ausschalten abzubrechen
Aug  3 01:35:07 vdr: confirmed

'The Start/Stop Timer error' shows that GetNextActiveTimer would have seen the finished Aug 3 timer, not the next Aug 4 timer. The timing for shutdown is actually that short, and the 'next timer' is not updated, even if the shutdown is 5 minutes later.

However, observe that the check is done at 01:35:01. If VDR is a little bit faster, the check could be at 01:35:00, and the call to Matches() would not switch to the Aug 4 timer either. The other debug message should show this, but I could not trigger this. Maybe on a faster machine it would do.

I suggest two changes to VDR:
- As the patch does, add a Matches() call to GetNextActiveTimer
- In Matches(), change this:
@@ -351,7 +351,7 @@
          if (DayMatches(t0)) {
             time_t a = SetTime(t0, begin);
             time_t b = a + length;
-            if ((!day || a >= day) && t <= b) {
+            if ((!day || a >= day) && t < b) {
                startTime = a;
                stopTime = b;
                break;
This way the daily timer already jumps to next day at t=StopTime, not at t=StopTime+1. This matches the following line:

return startTime <= t + Margin && t < stopTime; // must stop *before* stopTime to allow adjacent timers

Both changes should fix this issue imho, but its safer to have both.


By the way, in the above situation, VDR did shut down 7 seconds after the timer ended, because UserShutdown was still true. Normally VDR would have waited 5 minutes. But thats another issue.


Cheers,

Udo







--- timers.c.bak        2006-08-03 01:01:35.191684432 +0200
+++ timers.c    2006-08-03 01:59:23.883790392 +0200
@@ -647,6 +647,23 @@
 {
   cTimer *t0 = NULL;
   for (cTimer *ti = First(); ti; ti = Next(ti)) {
+      time_t stop=ti->StopTime();
+      time_t start=ti->StartTime();
+      ti->Matches();
+      if (stop!=ti->StopTime() || start!=ti->StartTime()) {
+         esyslog("Start/Stop Timer error: Start changed from %s to %s, stop 
from %s to %s",
+                 *TimeToString(start),*TimeToString(ti->StartTime()),
+                 *TimeToString(stop),*TimeToString(ti->StopTime()));
+         printf("Start/Stop Timer error: Start changed from %s to %s, stop 
from %s to %s\n",
+                 *TimeToString(start),*TimeToString(ti->StartTime()),
+                 *TimeToString(stop),*TimeToString(ti->StopTime()));
+      }
+      if (ti->StopTime() <= time(NULL)) {
+         esyslog("Start/Stop Timer error: Outdated timer from %s to %s",
+                 *TimeToString(start),*TimeToString(stop));
+         printf("Start/Stop Timer error: Outdated timer from %s to %s\n",
+                 *TimeToString(start),*TimeToString(stop));
+      }
       if ((ti->HasFlags(tfActive)) && (!t0 || ti->StopTime() > time(NULL) && 
ti->Compare(*t0) < 0))
          t0 = ti;
       }
_______________________________________________
vdr mailing list
vdr@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr

Reply via email to