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