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;
}