diff options
| -rw-r--r-- | CONTRIBUTORS | 1 | ||||
| -rw-r--r-- | HISTORY | 2 | ||||
| -rw-r--r-- | lirc.c | 17 | ||||
| -rw-r--r-- | menu.c | 28 | ||||
| -rw-r--r-- | menu.h | 6 | ||||
| -rw-r--r-- | rcu.c | 9 | ||||
| -rw-r--r-- | tools.c | 44 | ||||
| -rw-r--r-- | tools.h | 14 | 
8 files changed, 75 insertions, 46 deletions
| diff --git a/CONTRIBUTORS b/CONTRIBUTORS index b62f8a32..38d3bfd9 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -350,6 +350,7 @@ Rainer Zocholl <vdrcontrib@zocki.toppoint.de>   for reporting a possible race condition in generating the DVB device names   for pointing out that non-threadsafe functions should be replaced with their   threadsafe versions + for pointing out a threadsafe and overflow problem with time_ms()  Oleg Assovski <assen@bitcom.msk.ru>   for adding EPG scanning for another 4 days @@ -3222,3 +3222,5 @@ Video Disk Recorder Revision History    WeekDayName() -> cWeekDayName    DayDateTime() -> cDayDateTime  - Removed delay_ms(), using cCondWait::SleepMs() instead. +- Replaced time_ms() with a threadsafe and non-overflowing cTimeMs (thanks to Rainer +  Zocholl for pointing out this problem). @@ -6,7 +6,7 @@   *   * LIRC support added by Carsten Koch <Carsten.Koch@icem.de>  2000-06-16.   * - * $Id: lirc.c 1.8 2004/12/18 13:25:11 kls Exp $ + * $Id: lirc.c 1.9 2004/12/19 18:05:13 kls Exp $   */  #include "lirc.h" @@ -52,8 +52,8 @@ bool cLircRemote::Ready(void)  void cLircRemote::Action(void)  { -  int FirstTime = 0; -  int LastTime = 0; +  cTimeMs FirstTime; +  cTimeMs LastTime;    char buf[LIRC_BUFFER_SIZE];    char LastKeyName[LIRC_KEY_BUF] = "";    bool repeat = false; @@ -75,28 +75,27 @@ void cLircRemote::Action(void)           int count;           char KeyName[LIRC_KEY_BUF];           sscanf(buf, "%*x %x %29s", &count, KeyName); // '29' in '%29s' is LIRC_KEY_BUF-1! -         int Now = time_ms();           if (count == 0) { -            if (strcmp(KeyName, LastKeyName) == 0 && Now - FirstTime < KEYPRESSDELAY) +            if (strcmp(KeyName, LastKeyName) == 0 && FirstTime.Elapsed() < KEYPRESSDELAY)                 continue; // skip keys coming in too fast              if (repeat)                 Put(LastKeyName, false, true);              strcpy(LastKeyName, KeyName);              repeat = false; -            FirstTime = Now; +            FirstTime.Set();              timeout = -1;              }           else { -            if (Now - FirstTime < REPEATDELAY) +            if (FirstTime.Elapsed() < REPEATDELAY)                 continue; // repeat function kicks in after a short delay              repeat = true;              timeout = REPEATDELAY;              } -         LastTime = Now; +         LastTime.Set();           Put(KeyName, repeat);           }        else if (repeat) { // the last one was a repeat, so let's generate a release -         if (time_ms() - LastTime >= REPEATDELAY) { +         if (LastTime.Elapsed() >= REPEATDELAY) {              Put(LastKeyName, false, true);              repeat = false;              *LastKeyName = 0; @@ -4,7 +4,7 @@   * See the main source file 'vdr.c' for copyright information and   * how to reach the author.   * - * $Id: menu.c 1.321 2004/12/12 16:07:05 kls Exp $ + * $Id: menu.c 1.322 2004/12/19 17:59:47 kls Exp $   */  #include "menu.h" @@ -2516,7 +2516,7 @@ cDisplayChannel::cDisplayChannel(int Number, bool Switched)       DisplayInfo();       displayChannel->Flush();       } -  lastTime = time_ms(); +  lastTime.Set();  }  cDisplayChannel::cDisplayChannel(eKeys FirstKey) @@ -2525,7 +2525,7 @@ cDisplayChannel::cDisplayChannel(eKeys FirstKey)    group = -1;    number = 0;    lastPresent = lastFollowing = NULL; -  lastTime = time_ms(); +  lastTime.Set();    withInfo = Setup.ShowInfoOnChSwitch;    displayChannel = Skins.Current()->DisplayChannel(withInfo);    ProcessKey(FirstKey); @@ -2570,7 +2570,7 @@ void cDisplayChannel::Refresh(void)    channel = Channels.GetByNumber(cDevice::CurrentChannel());    DisplayChannel();    displayChannel->SetEvents(NULL, NULL); -  lastTime = time_ms(); +  lastTime.Set();  }  eOSState cDisplayChannel::ProcessKey(eKeys Key) @@ -2590,7 +2590,7 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)                 displayChannel->SetEvents(NULL, NULL);                 withInfo = false;                 DisplayChannel(); -               lastTime = time_ms(); +               lastTime.Set();                 // Lets see if there can be any useful further input:                 int n = channel ? number * 10 : 0;                 cChannel *ch = channel; @@ -2639,7 +2639,7 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)                    group = -1;                 }              } -         lastTime = time_ms(); +         lastTime.Set();           break;      case kUp|k_Repeat:      case kUp: @@ -2656,14 +2656,14 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)           Refresh();           break;      case kNone: -         if (number && time_ms() - lastTime > DIRECTCHANNELTIMEOUT) { +         if (number && lastTime.Elapsed() > DIRECTCHANNELTIMEOUT) {              if (Channels.GetByNumber(number))                 Channels.SwitchTo(number);              else {                 number = 0;                 channel = NULL;                 DisplayChannel(); -               lastTime = time_ms(); +               lastTime.Set();                 return osContinue;                 }              return osEnd; @@ -2687,7 +2687,7 @@ eOSState cDisplayChannel::ProcessKey(eKeys Key)                       return osEnd;                       }      }; -  if (time_ms() - lastTime < INFOTIMEOUT) { +  if (lastTime.Elapsed() < INFOTIMEOUT) {       if (!number && group < 0 && channel && channel->Number() != cDevice::CurrentChannel())          Refresh(); // makes sure a channel switch through the SVDRP CHAN command is displayed       DisplayInfo(); @@ -2708,7 +2708,7 @@ cDisplayVolume::cDisplayVolume(void)  :cOsdObject(true)  {    currentDisplayVolume = this; -  timeout = time_ms() + (cDevice::PrimaryDevice()->IsMute() ? MUTETIMEOUT : VOLUMETIMEOUT); +  timeout.Set(cDevice::PrimaryDevice()->IsMute() ? MUTETIMEOUT : VOLUMETIMEOUT);    displayVolume = Skins.Current()->DisplayVolume();    Show();  } @@ -2745,15 +2745,15 @@ eOSState cDisplayVolume::ProcessKey(eKeys Key)      case kVolDn|k_Repeat:      case kVolDn:           Show(); -         timeout = time_ms() + VOLUMETIMEOUT; +         timeout.Set(VOLUMETIMEOUT);           break;      case kMute:           if (cDevice::PrimaryDevice()->IsMute()) {              Show(); -            timeout = time_ms() + MUTETIMEOUT; +            timeout.Set(MUTETIMEOUT);              }           else -            timeout = 0; +            timeout.Set();           break;      case kNone: break;      default: if ((Key & k_Release) == 0) { @@ -2761,7 +2761,7 @@ eOSState cDisplayVolume::ProcessKey(eKeys Key)                  return osEnd;                  }      } -  return time_ms() < timeout ? osContinue : osEnd; +  return timeout.TimedOut() ? osEnd : osContinue;  }  // --- cRecordControl -------------------------------------------------------- @@ -4,7 +4,7 @@   * See the main source file 'vdr.c' for copyright information and   * how to reach the author.   * - * $Id: menu.h 1.64 2004/06/13 11:46:03 kls Exp $ + * $Id: menu.h 1.65 2004/12/19 17:59:47 kls Exp $   */  #ifndef __MENU_H @@ -46,7 +46,7 @@ private:    cSkinDisplayChannel *displayChannel;    int group;    bool withInfo; -  int lastTime; +  cTimeMs lastTime;    int number;    cChannel *channel;    const cEvent *lastPresent; @@ -64,7 +64,7 @@ public:  class cDisplayVolume : public cOsdObject {  private:    cSkinDisplayVolume *displayVolume; -  int timeout; +  cTimeMs timeout;    static cDisplayVolume *currentDisplayVolume;    virtual void Show(void);    cDisplayVolume(void); @@ -4,7 +4,7 @@   * See the main source file 'vdr.c' for copyright information and   * how to reach the author.   * - * $Id: rcu.c 1.7 2004/12/19 17:19:34 kls Exp $ + * $Id: rcu.c 1.8 2004/12/19 18:06:00 kls Exp $   */  #include "rcu.h" @@ -94,7 +94,7 @@ void cRcuRemote::Action(void)  #pragma pack()    time_t LastCodeRefresh = 0; -  int FirstTime = 0; +  cTimeMs FirstTime;    uint64 LastCommand = 0;    bool repeat = false; @@ -116,15 +116,14 @@ void cRcuRemote::Action(void)                        // This remote control sends the above command before and after                        // each keypress - let's just drop this:                        break; -                   int Now = time_ms();                     Command |= uint64(Address) << 32;                     if (Command != LastCommand) {                        LastCommand = Command;                        repeat = false; -                      FirstTime = Now; +                      FirstTime.Set();                        }                     else { -                      if (Now - FirstTime < REPEATDELAY) +                      if (FirstTime.Elapsed() < REPEATDELAY)                           break; // repeat function kicks in after a short delay                        repeat = true;                        } @@ -4,7 +4,7 @@   * See the main source file 'vdr.c' for copyright information and   * how to reach the author.   * - * $Id: tools.c 1.84 2004/12/19 17:19:46 kls Exp $ + * $Id: tools.c 1.85 2004/12/19 18:06:16 kls Exp $   */  #include "tools.h" @@ -187,18 +187,6 @@ int numdigits(int n)    return strlen(buf);  } -int time_ms(void) -{ -  static time_t t0 = 0; -  struct timeval t; -  if (gettimeofday(&t, NULL) == 0) { -     if (t0 == 0) -        t0 = t.tv_sec; // this avoids an overflow (we only work with deltas) -     return (t.tv_sec - t0) * 1000 + t.tv_usec / 1000; -     } -  return 0; -} -  bool isnumber(const char *s)  {    if (!*s) @@ -432,6 +420,36 @@ time_t LastModifiedTime(const char *FileName)    return 0;  } +// --- cTimeMs --------------------------------------------------------------- + +cTimeMs::cTimeMs(void) +{ +  Set(); +} + +void cTimeMs::Set(int Ms) +{ +  begin = Now() + Ms; +} + +bool cTimeMs::TimedOut(void) +{ +  return Now() >= begin; +} + +uint64 cTimeMs::Now(void) +{ +  struct timeval t; +  if (gettimeofday(&t, NULL) == 0) +     return (uint64(t.tv_sec)) * 1000 + t.tv_usec / 1000; +  return 0; +} + +uint64 cTimeMs::Elapsed(void) +{ +  return Now() - begin; +} +  // --- cBufferedStringFunction -----------------------------------------------  cBufferedStringFunction::cBufferedStringFunction(void) @@ -4,7 +4,7 @@   * See the main source file 'vdr.c' for copyright information and   * how to reach the author.   * - * $Id: tools.h 1.60 2004/12/19 17:20:05 kls Exp $ + * $Id: tools.h 1.61 2004/12/19 18:06:10 kls Exp $   */  #ifndef __TOOLS_H @@ -71,7 +71,6 @@ bool startswith(const char *s, const char *p);  bool endswith(const char *s, const char *p);  bool isempty(const char *s);  int numdigits(int n); -int time_ms(void);  bool isnumber(const char *s);  int FreeDiskSpaceMB(const char *Directory, int *UsedMB = NULL);  bool DirectoryOk(const char *DirName, bool LogErrors = false); @@ -82,6 +81,17 @@ char *ReadLink(const char *FileName);  bool SpinUpDisk(const char *FileName);  time_t LastModifiedTime(const char *FileName); +class cTimeMs { +private: +  uint64 begin; +public: +  cTimeMs(void); +  void Set(int Ms = 0); +  bool TimedOut(void); +  uint64 Now(void); +  uint64 Elapsed(void); +  }; +  class cBufferedStringFunction {  protected:    char *buffer; | 
