Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[vdr] Re: Log of Timer Bug
Klaus Schmidinger wrote:
>
> I believe I found what's causing the recent problems with timers
> hitting at unexpected times.
>
> Apparently the library function localtime() is not thread safe.
> Since VDR uses this function in the foreground thread as well as
> in background threads, we need to make sure that there is no
> interference. Luckily, there is a thread safe version of this function,
> named localtime_r().
>
> At the moment it is a little hard for me to provide a patch for this,
diff -ru VDR096/config.c VDR096+localtime/config.c
--- VDR096/config.c Thu Oct 18 18:26:55 2001
+++ VDR096+localtime/config.c Sat Oct 20 23:27:58 2001
@@ -324,7 +324,8 @@
cChannel *ch = Channels.GetByNumber(cDvbApi::CurrentChannel());
channel = ch ? ch->number : 0;
time_t t = time(NULL);
- struct tm *now = localtime(&t);
+ struct tm tm_r;
+ struct tm *now = localtime_r(&t, &tm_r);
day = now->tm_mday;
start = now->tm_hour * 100 + now->tm_min;
stop = start + 200; // "instant recording" records 2 hours by default
@@ -349,10 +350,11 @@
time_t tstart = EventInfo->GetTime();
time_t tstop = tstart + EventInfo->GetDuration() + Setup.MarginStop * 60;
tstart -= Setup.MarginStart * 60;
- struct tm *time = localtime(&tstart);
+ struct tm tm_r;
+ struct tm *time = localtime_r(&tstart, &tm_r);
day = time->tm_mday;
start = time->tm_hour * 100 + time->tm_min;
- time = localtime(&tstop);
+ time = localtime_r(&tstop, &tm_r);
stop = time->tm_hour * 100 + time->tm_min;
if (stop >= 2400)
stop -= 2400;
@@ -497,12 +499,14 @@
int cTimer::GetMDay(time_t t)
{
- return localtime(&t)->tm_mday;
+ struct tm tm_r;
+ return localtime_r(&t, &tm_r)->tm_mday;
}
int cTimer::GetWDay(time_t t)
{
- int weekday = localtime(&t)->tm_wday;
+ struct tm tm_r;
+ int weekday = localtime_r(&t, &tm_r)->tm_wday;
return weekday == 0 ? 6 : weekday - 1; // we start with monday==0!
}
@@ -513,7 +517,8 @@
time_t cTimer::IncDay(time_t t, int Days)
{
- tm tm = *localtime(&t);
+ struct tm tm_r;
+ tm tm = *localtime_r(&t, &tm_r);
tm.tm_mday += Days; // now tm_mday may be out of its valid range
int h = tm.tm_hour; // save original hour to compensate for DST change
t = mktime(&tm); // normalize all values
@@ -523,7 +528,8 @@
time_t cTimer::SetTime(time_t t, int SecondsFromMidnight)
{
- tm tm = *localtime(&t);
+ struct tm tm_r;
+ tm tm = *localtime_r(&t, &tm_r);
tm.tm_hour = SecondsFromMidnight / 3600;
tm.tm_min = (SecondsFromMidnight % 3600) / 60;
tm.tm_sec = SecondsFromMidnight % 60;
diff -ru VDR096/eit.c VDR096+localtime/eit.c
--- VDR096/eit.c Sat Sep 22 15:07:21 2001
+++ VDR096+localtime/eit.c Sat Oct 20 23:27:53 2001
@@ -126,7 +126,8 @@
struct tm *ptm;
time_t loctim;
- ptm = localtime(&mjdtime);
+ struct tm tm_r;
+ ptm = localtime_r(&mjdtime, &tm_r);
loctim = time(NULL);
if (abs(mjdtime - loctim) > 2)
@@ -239,8 +240,9 @@
const char * cEventInfo::GetDate() const
{
static char szDate[25];
+ struct tm tm_r;
- strftime(szDate, sizeof(szDate), "%d.%m.%Y", localtime(&tTime));
+ strftime(szDate, sizeof(szDate), "%d.%m.%Y", localtime_r(&tTime, &tm_r));
return szDate;
}
@@ -248,8 +250,9 @@
const char * cEventInfo::GetTimeString() const
{
static char szTime[25];
+ struct tm tm_r;
- strftime(szTime, sizeof(szTime), "%R", localtime(&tTime));
+ strftime(szTime, sizeof(szTime), "%R", localtime_r(&tTime, &tm_r));
return szTime;
}
@@ -258,8 +261,9 @@
{
static char szEndTime[25];
time_t tEndTime = tTime + lDuration;
+ struct tm tm_r;
- strftime(szEndTime, sizeof(szEndTime), "%R", localtime(&tEndTime));
+ strftime(szEndTime, sizeof(szEndTime), "%R", localtime_r(&tEndTime, &tm_r));
return szEndTime;
}
@@ -455,7 +459,8 @@
// correctly on the ASTRA satellite system.
if (uServiceID == 898 // Pro-7
|| uServiceID == 899) { // Kabel 1
- tm *t = localtime(&tTime);
+ struct tm tm_r;
+ tm *t = localtime_r(&tTime, &tm_r);
if (t->tm_hour * 3600 + t->tm_min * 60 + t->tm_sec <= 6 * 3600)
tTime += 24 * 3600;
}
@@ -873,7 +878,8 @@
if (masterSIProcessor)
{
time_t now = time(NULL);
- struct tm *ptm = localtime(&now);
+ struct tm tm_r;
+ struct tm *ptm = localtime_r(&now, &tm_r);
if (now - lastCleanup > 3600 && ptm->tm_hour == 5)
{
LOCK_THREAD;
diff -ru VDR096/recording.c VDR096+localtime/recording.c
--- VDR096/recording.c Sun Sep 23 15:43:29 2001
+++ VDR096+localtime/recording.c Sat Oct 20 23:27:48 2001
@@ -243,7 +243,8 @@
summary = NULL;
if (p) {
time_t now = time(NULL);
- struct tm t = *localtime(&now); // this initializes the time zone in 't'
+ struct tm tm_r;
+ struct tm t = *localtime_r(&now, &tm_r); // this initializes the time zone in 't'
t.tm_isdst = -1; // makes sure mktime() will determine the correct dst setting
if (7 == sscanf(p + 1, DATAFORMAT, &t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &priority, &lifetime)) {
t.tm_year -= 1900;
@@ -302,7 +303,8 @@
const char *cRecording::FileName(void)
{
if (!fileName) {
- struct tm *t = localtime(&start);
+ struct tm tm_r;
+ struct tm *t = localtime_r(&start, &tm_r);
ExchangeChars(name, true);
asprintf(&fileName, NAMEFORMAT, VideoDirectory, name, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, priority, lifetime);
ExchangeChars(name, false);
@@ -320,7 +322,8 @@
}
delete titleBuffer;
titleBuffer = NULL;
- struct tm *t = localtime(&start);
+ struct tm tm_r;
+ struct tm *t = localtime_r(&start, &tm_r);
asprintf(&titleBuffer, "%02d.%02d%c%02d:%02d%c%c%s",
t->tm_mday,
t->tm_mon + 1,
Home |
Main Index |
Thread Index