diff options
| author | Sam Varshavchik | 2013-08-19 16:39:41 -0400 |
|---|---|---|
| committer | Sam Varshavchik | 2013-08-25 14:43:51 -0400 |
| commit | 9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch) | |
| tree | 7a81a04cb51efb078ee350859a64be2ebc6b8813 /curses/timer.C | |
| parent | a9520698b770168d1f33d6301463bb70a19655ec (diff) | |
| download | courier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2 | |
Initial checkin
Imported from subversion report, converted to git. Updated all paths in
scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'curses/timer.C')
| -rw-r--r-- | curses/timer.C | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/curses/timer.C b/curses/timer.C new file mode 100644 index 0000000..8097f37 --- /dev/null +++ b/curses/timer.C @@ -0,0 +1,172 @@ +/* +** Copyright 2002, Double Precision Inc. +** +** See COPYING for distribution information. +*/ + +#include "curses_config.h" +#include "timer.H" + +std::set<Timer *> Timer::timer_list; + +Timer::Timer() +{ + timeout.tv_sec=0; + timeout.tv_usec=0; + + timer_list.insert(this); +} + +Timer::~Timer() +{ + timer_list.erase(this); +} + +void Timer::setTimer(int nSeconds) +{ + gettimeofday(&timeout, NULL); + timeout.tv_sec += nSeconds; +} + +void Timer::setTimer(struct timeval tv) +{ + gettimeofday(&timeout, NULL); + timeout.tv_sec += tv.tv_sec; + + timeout.tv_usec += tv.tv_usec; + + if (timeout.tv_usec >= 1000000) + { + ++timeout.tv_sec; + timeout.tv_usec %= 1000000; + } +} + +struct timeval Timer::getTimer() const +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + + return getTimer(tv); +} + +struct timeval Timer::getTimer(const struct timeval &tv) const +{ + struct timeval t; + + t.tv_sec=0; + t.tv_usec=0; + + if (timeout.tv_sec == 0 && timeout.tv_usec == 0) + return t; + + if (tv.tv_sec > timeout.tv_sec) + return t; + + if (tv.tv_sec == timeout.tv_sec && + tv.tv_usec >= timeout.tv_usec) + return t; + + t=timeout; + + t.tv_sec -= tv.tv_sec; + t.tv_usec -= tv.tv_usec; + + if (t.tv_usec < 0) + { + t.tv_usec += 1000000; + t.tv_sec--; + } + + return t; +} + +#define DEBUG 1 +#undef DEBUG + +struct timeval Timer::getNextTimeout(bool &alarmCalledFlag) +{ + struct timeval now; + + gettimeofday(&now, NULL); + + bool alarmed; + + bool wasAlarmed=false; + + struct timeval s; + + alarmCalledFlag=false; + + do + { +#if DEBUG + cerr << "In getNextTimeout:" << endl; +#endif + + alarmed=false; + + std::set<Timer *>::iterator b=timer_list.begin(), + e=timer_list.end(); + + s.tv_sec=0; + s.tv_usec=0; + + while (b != e) + { + Timer *t= *b++; + + if (t->timeout.tv_sec == 0 && + t->timeout.tv_usec == 0) + continue; + + struct timeval v=t->getTimer(now); + +#if DEBUG + cerr << "Timer " << t << ": " << v.tv_sec + << "." << v.tv_usec << endl; +#endif + + if (v.tv_sec == 0 && v.tv_usec == 0) + { +#if DEBUG + cerr << "ALARM: " << + (wasAlarmed ? "ignored":"handled") + << endl; +#endif + if (wasAlarmed) + { + // We can get here if an alarm + // went off, and the alarm handler + // reset the alarm to 0 seconds again. + // We'll get it on the next go-round + + s=v; + break; // Kick the alarm next time + } + t->timeout=v; + t->alarm(); + alarmCalledFlag=true; + alarmed=true; + } + else if ((s.tv_sec == 0 && s.tv_usec == 0) || + v.tv_sec < s.tv_sec || + (v.tv_sec == s.tv_sec + && v.tv_usec < s.tv_usec)) + s=v; + } + + wasAlarmed=alarmed; + + } while (alarmed); + +#if DEBUG + cerr << "getNextTimeout: " << s.tv_sec << "." << s.tv_usec << endl; +#endif + return s; +} + +void Timer::alarm() +{ +} |
