Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[vdr] Re: AW: VPS alone at home ;-)



Rainer Zocholl wrote:
Malte.Grunwald@beb.de 07.12.04 10:28


Rainer Zocholl wrote

20:15-21:01 "Markt im Dritten"

Real time   VPS
20:30-21:15 20:15-21:00 Markt im Dritten
21:15-22:45 21:00-22:30 Tatort
(Thanks to osdteletext it was easy to reconstruct)


Recorded in directory "Markt im Dritten":
1. 20:15...21:17 (1:02:35) "Akutelles Maga.." OK
 (Start point is OK as i activated VPS during the transmission
  as i don't wanted to miss teh end of the programm. (That
worked OK!))
2. 21:00..(manual abort) "Fernsehfilm Deutschland..." WORNG


Why did VDR start a second recording at 21:00(realtime: 21:15)?
(The event should be set to next week, but was set to this
week and the wrong VPS time...)

17:41 vdr[14959]: timer 4 (15 2015-2101 'Markt im Dritten')...
                             ~~~~
 set to event Mon 06.12.2004 21:00-22:30 (VPS : 06.12 21:00)
'Tatort: Schichtwechsel'
                             ~~~~~
                             ???
[..]
Hi,

keep in mind, that the Tartort actually started at 21:15. There was some additinal program.

Exactly this is the reason!

While trying to make vdr thread safe it happens that i read epg.c,
(because it uses the non thread safe functions of tools.c ...)
You will find the cEvent class, almost each with a "static buf[..]".
Now imagine that there are two threads running:
one just "finishing" the recording and calcutating the
next event (using cEvent::GetVpsString) and the
other thread receiving a new event from epg data, using
cEvent::GetVpsString.
I assume(hope) "&vps" is thread specific (&tm_r is already local to function)
and "localtime_r" is used because of "funny effects".
But both threads uses the "static buf[25]", so the second thread will win...
the first will continue with the data of the second...
Because it's very likely that when a recording stops, a new
epg event occurs makes VPS unrelyable.

(I don't know if these too functions are really on two threads,
but there maybe an other thread too. Or a plugin. Such effects are very typical
for reentrance problems, often seen in string print/logging  routines..)


One simple workarround would be to force the use of
"tls"-libs, gcc 3.x and define
"__threaded static buf[25]".

But this will not protect against "funny effects" by recursions
inside one thread.
So there is only a (ugly) way to use the (costly) malloc
or to add a pointer from the caller.





const char *cEvent::GetVpsString(void) const   // DON'T USE IN MULTITHREAD
{
  static char buf[25];
  struct tm tm_r;
  strftime(buf, sizeof(buf), "%d.%m %R", localtime_r(&vps, &tm_r));
  return buf;
}
kls@hawk:/home/kls/vdr/VDR > grep GetVpsString *.c
epg.c:const char *cEvent::GetVpsString(void) const
skinclassic.c:     asprintf(&buffer, " VPS: %s", Event->GetVpsString());
skinsttng.c:     asprintf(&buffer, " VPS: %s", Event->GetVpsString());
timers.c:           sprintf(vpsbuf, "(VPS: %s) ", Event->GetVpsString());

cEvent::GetVpsString() is only used from the main program, so there's no need
to jump around in circles here ;-)

Sure, static buffers should be avoided and I'll attend to this in
due time, but regarding your immediate problem I don't think that
this has anything to do with it.

Klaus




Home | Main Index | Thread Index