aboutsummaryrefslogtreecommitdiff
path: root/lib/base
diff options
context:
space:
mode:
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>2008-04-16 09:53:18 +0000
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>2008-04-16 09:53:18 +0000
commitd58af85ce33b4b9c8cb065b59b591580ae8abe0c (patch)
treeaabac149c6d20c6809ee4dea0c1b371f1de24f81 /lib/base
parent5c392355566dce59c1e486ae934228aa9a5fa2bc (diff)
downloadenigma2-d58af85ce33b4b9c8cb065b59b591580ae8abe0c.tar.gz
enigma2-d58af85ce33b4b9c8cb065b59b591580ae8abe0c.zip
use clock_gettime for internal timers instead of gettimeofday .. so now our
timers are independent of the normal linux clock (and change linux time without inform e2 is now really uncritical)
Diffstat (limited to 'lib/base')
-rw-r--r--lib/base/ebase.cpp69
-rw-r--r--lib/base/ebase.h95
2 files changed, 54 insertions, 110 deletions
diff --git a/lib/base/ebase.cpp b/lib/base/ebase.cpp
index 01ee6a53..038e5ad1 100644
--- a/lib/base/ebase.cpp
+++ b/lib/base/ebase.cpp
@@ -44,11 +44,10 @@ void eTimer::start(long msek, bool singleShot)
bActive = true;
bSingleShot = singleShot;
interval = msek;
- gettimeofday(&nextActivation, 0);
- nextActivation.tv_sec -= context.getTimeOffset();
-// eDebug("this = %p\nnow sec = %d, usec = %d\nadd %d msec", this, nextActivation.tv_sec, nextActivation.tv_usec, msek);
+ clock_gettime(CLOCK_MONOTONIC, &nextActivation);
+// eDebug("this = %p\nnow sec = %d, nsec = %d\nadd %d msec", this, nextActivation.tv_sec, nextActivation.tv_nsec, msek);
nextActivation += (msek<0 ? 0 : msek);
-// eDebug("next Activation sec = %d, usec = %d", nextActivation.tv_sec, nextActivation.tv_usec );
+// eDebug("next Activation sec = %d, nsec = %d", nextActivation.tv_sec, nextActivation.tv_nsec );
context.addTimer(this);
}
@@ -59,12 +58,11 @@ void eTimer::startLongTimer( int seconds )
bActive = bSingleShot = true;
interval = 0;
- gettimeofday(&nextActivation, 0);
- nextActivation.tv_sec -= context.getTimeOffset();
-// eDebug("this = %p\nnow sec = %d, usec = %d\nadd %d sec", this, nextActivation.tv_sec, nextActivation.tv_usec, seconds);
+ clock_gettime(CLOCK_MONOTONIC, &nextActivation);
+// eDebug("this = %p\nnow sec = %d, nsec = %d\nadd %d sec", this, nextActivation.tv_sec, nextActivation.tv_nsec, seconds);
if ( seconds > 0 )
nextActivation.tv_sec += seconds;
-// eDebug("next Activation sec = %d, usec = %d", nextActivation.tv_sec, nextActivation.tv_usec );
+// eDebug("next Activation sec = %d, nsec = %d", nextActivation.tv_sec, nextActivation.tv_nsec );
context.addTimer(this);
}
@@ -108,18 +106,12 @@ void eTimer::activate() // Internal Funktion... called from eApplication
/*emit*/ timeout();
}
-void eTimer::addTimeOffset( int offset )
-{
- nextActivation.tv_sec += offset;
-}
-
// mainloop
ePtrList<eMainloop> eMainloop::existing_loops;
eMainloop::~eMainloop()
{
existing_loops.remove(this);
- pthread_mutex_destroy(&recalcLock);
for (std::map<int, eSocketNotifier*>::iterator it(notifiers.begin());it != notifiers.end();++it)
it->second->stop();
while(m_timer_list.begin() != m_timer_list.end())
@@ -157,15 +149,11 @@ int eMainloop::processOneEvent(unsigned int twisted_timeout, PyObject **res, ePy
if (!m_timer_list.empty() || twisted_timeout > 0)
{
- applyTimeOffset();
if (!m_timer_list.empty())
{
/* process all timers which are ready. first remove them out of the list. */
while (!m_timer_list.empty() && (poll_timeout = timeout_usec( m_timer_list.begin()->getNextActivation() ) ) <= 0 )
- {
m_timer_list.begin()->activate();
- applyTimeOffset();
- }
if (poll_timeout < 0)
poll_timeout = 0;
else /* convert us to ms */
@@ -216,7 +204,7 @@ int eMainloop::processOneEvent(unsigned int twisted_timeout, PyObject **res, ePy
Py_END_ALLOW_THREADS
} else
ret = ::poll(pfd, fdcount, poll_timeout);
-
+
m_is_idle = 0;
/* ret > 0 means that there are some active poll entries. */
@@ -283,7 +271,7 @@ int eMainloop::iterate(unsigned int twisted_timeout, PyObject **res, ePyObject d
if (twisted_timeout)
{
- gettimeofday(&m_twisted_timer, 0);
+ clock_gettime(CLOCK_MONOTONIC, &m_twisted_timer);
m_twisted_timer += twisted_timeout;
}
@@ -302,15 +290,12 @@ int eMainloop::iterate(unsigned int twisted_timeout, PyObject **res, ePyObject d
int to = 0;
if (twisted_timeout)
{
- timeval now, timeout;
- gettimeofday(&now, 0);
- m_twisted_timer += time_offset; // apply pending offset
+ timespec now, timeout;
+ clock_gettime(CLOCK_MONOTONIC, &now);
if (m_twisted_timer<=now) // timeout
return 0;
timeout = m_twisted_timer - now;
- to = timeout.tv_sec * 1000 + timeout.tv_usec / 1000;
- // remove pending offset .. it is re-applied in next call of processOneEvent.. applyTimeOffset
- m_twisted_timer -= time_offset;
+ to = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000;
}
ret = processOneEvent(to, res, dict);
} while ( !ret && !(res && *res) );
@@ -357,38 +342,6 @@ void eMainloop::quit(int ret)
app_quit_now = true;
}
-void eMainloop::addTimeOffset(int offset)
-{
- for (ePtrList<eMainloop>::iterator it(existing_loops.begin()); it != existing_loops.end(); ++it )
- it->addInstanceTimeOffset(offset);
-}
-
-void eMainloop::addInstanceTimeOffset(int offset)
-{
- singleLock s(recalcLock);
- if (m_timer_list.empty())
- time_offset=0;
- else
- {
- if ( time_offset )
- eDebug("time_offset %d avail.. add new offset %d than new is %d",
- time_offset, offset, time_offset+offset);
- time_offset+=offset;
- }
-}
-
-void eMainloop::applyTimeOffset()
-{
- singleLock s(recalcLock);
- if ( time_offset )
- {
- for (ePtrList<eTimer>::iterator it(m_timer_list.begin()); it != m_timer_list.end(); ++it )
- it->addTimeOffset( time_offset );
- m_twisted_timer += time_offset;
- time_offset=0;
- }
-}
-
eApplication* eApp = 0;
#include "structmember.h"
diff --git a/lib/base/ebase.h b/lib/base/ebase.h
index c4dab621..10b46120 100644
--- a/lib/base/ebase.h
+++ b/lib/base/ebase.h
@@ -21,115 +21,115 @@ extern eApplication* eApp;
#ifndef SWIG
/* TODO: remove these inlines. */
-static inline bool operator<( const timeval &t1, const timeval &t2 )
+static inline bool operator<( const timespec &t1, const timespec &t2 )
{
- return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_usec < t2.tv_usec);
+ return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_nsec < t2.tv_nsec);
}
-static inline bool operator<=( const timeval &t1, const timeval &t2 )
+static inline bool operator<=( const timespec &t1, const timespec &t2 )
{
- return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_usec <= t2.tv_usec);
+ return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_nsec <= t2.tv_nsec);
}
-static inline timeval &operator+=( timeval &t1, const timeval &t2 )
+static inline timespec &operator+=( timespec &t1, const timespec &t2 )
{
t1.tv_sec += t2.tv_sec;
- if ( (t1.tv_usec += t2.tv_usec) >= 1000000 )
+ if ( (t1.tv_nsec += t2.tv_nsec) >= 1000000000 )
{
t1.tv_sec++;
- t1.tv_usec -= 1000000;
+ t1.tv_nsec -= 1000000000;
}
return t1;
}
-static inline timeval operator+( const timeval &t1, const timeval &t2 )
+static inline timespec operator+( const timespec &t1, const timespec &t2 )
{
- timeval tmp;
+ timespec tmp;
tmp.tv_sec = t1.tv_sec + t2.tv_sec;
- if ( (tmp.tv_usec = t1.tv_usec + t2.tv_usec) >= 1000000 )
+ if ( (tmp.tv_nsec = t1.tv_nsec + t2.tv_nsec) >= 1000000000 )
{
tmp.tv_sec++;
- tmp.tv_usec -= 1000000;
+ tmp.tv_nsec -= 1000000000;
}
return tmp;
}
-static inline timeval operator-( const timeval &t1, const timeval &t2 )
+static inline timespec operator-( const timespec &t1, const timespec &t2 )
{
- timeval tmp;
+ timespec tmp;
tmp.tv_sec = t1.tv_sec - t2.tv_sec;
- if ( (tmp.tv_usec = t1.tv_usec - t2.tv_usec) < 0 )
+ if ( (tmp.tv_nsec = t1.tv_nsec - t2.tv_nsec) < 0 )
{
tmp.tv_sec--;
- tmp.tv_usec += 1000000;
+ tmp.tv_nsec += 1000000000;
}
return tmp;
}
-static inline timeval operator-=( timeval &t1, const timeval &t2 )
+static inline timespec operator-=( timespec &t1, const timespec &t2 )
{
t1.tv_sec -= t2.tv_sec;
- if ( (t1.tv_usec -= t2.tv_usec) < 0 )
+ if ( (t1.tv_nsec -= t2.tv_nsec) < 0 )
{
t1.tv_sec--;
- t1.tv_usec += 1000000;
+ t1.tv_nsec += 1000000000;
}
return t1;
}
-static inline timeval &operator+=( timeval &t1, const long msek )
+static inline timespec &operator+=( timespec &t1, const long msek )
{
t1.tv_sec += msek / 1000;
- if ( (t1.tv_usec += (msek % 1000) * 1000) >= 1000000 )
+ if ( (t1.tv_nsec += (msek % 1000) * 1000000) >= 1000000000 )
{
t1.tv_sec++;
- t1.tv_usec -= 1000000;
+ t1.tv_nsec -= 1000000000;
}
return t1;
}
-static inline timeval operator+( const timeval &t1, const long msek )
+static inline timespec operator+( const timespec &t1, const long msek )
{
- timeval tmp;
+ timespec tmp;
tmp.tv_sec = t1.tv_sec + msek / 1000;
- if ( (tmp.tv_usec = t1.tv_usec + (msek % 1000) * 1000) >= 1000000 )
+ if ( (tmp.tv_nsec = t1.tv_nsec + (msek % 1000) * 1000000) >= 1000000000 )
{
tmp.tv_sec++;
- tmp.tv_usec -= 1000000;
+ tmp.tv_nsec -= 1000000;
}
return tmp;
}
-static inline timeval operator-( const timeval &t1, const long msek )
+static inline timespec operator-( const timespec &t1, const long msek )
{
- timeval tmp;
+ timespec tmp;
tmp.tv_sec = t1.tv_sec - msek / 1000;
- if ( (tmp.tv_usec = t1.tv_usec - (msek % 1000)*1000) < 0 )
+ if ( (tmp.tv_nsec = t1.tv_nsec - (msek % 1000)*1000000) < 0 )
{
tmp.tv_sec--;
- tmp.tv_usec += 1000000;
+ tmp.tv_nsec += 1000000000;
}
return tmp;
}
-static inline timeval operator-=( timeval &t1, const long msek )
+static inline timespec operator-=( timespec &t1, const long msek )
{
t1.tv_sec -= msek / 1000;
- if ( (t1.tv_usec -= (msek % 1000) * 1000) < 0 )
+ if ( (t1.tv_nsec -= (msek % 1000) * 1000000) < 0 )
{
t1.tv_sec--;
- t1.tv_usec += 1000000;
+ t1.tv_nsec += 1000000000;
}
return t1;
}
-static inline long timeout_usec ( const timeval & orig )
+static inline long timeout_usec ( const timespec & orig )
{
- timeval now;
- gettimeofday(&now,0);
+ timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
if ( (orig-now).tv_sec > 2000 )
return 2000*1000*1000;
- return (orig-now).tv_sec*1000000 + (orig-now).tv_usec;
+ return (orig-now).tv_sec*1000000 + (orig-now).tv_nsec/1000;
}
class eMainloop;
@@ -190,23 +190,16 @@ class eMainloop
int loop_level;
int processOneEvent(unsigned int user_timeout, PyObject **res=0, ePyObject additional=ePyObject());
int retval;
- int time_offset;
int m_is_idle;
- pthread_mutex_t recalcLock;
-
+
int m_interrupt_requested;
- timeval m_twisted_timer; // twisted timer
-
+ timespec m_twisted_timer; // twisted timer
+
void addSocketNotifier(eSocketNotifier *sn);
void removeSocketNotifier(eSocketNotifier *sn);
void addTimer(eTimer* e);
void removeTimer(eTimer* e);
- void applyTimeOffset();
public:
- static void addTimeOffset(int offset);
- void addInstanceTimeOffset(int offset);
- int getTimeOffset() { return time_offset; }
-
#ifndef SWIG
static ePtrList<eMainloop> existing_loops;
#endif
@@ -215,7 +208,6 @@ public:
:app_quit_now(0),loop_level(0),retval(0), m_is_idle(0), m_interrupt_requested(0)
{
existing_loops.push_back(this);
- pthread_mutex_init(&recalcLock, 0);
}
virtual ~eMainloop();
@@ -235,12 +227,12 @@ public:
/* run will iterate endlessly until the app is quit, and return
the exit code */
int runLoop();
-
+
/* our new shared polling interface. */
PyObject *poll(SWIG_PYOBJECT(ePyObject) dict, SWIG_PYOBJECT(ePyObject) timeout);
void interruptPoll();
void reset();
-
+
/* m_is_idle needs to be atomic, but it doesn't really matter much, as it's read-only from outside */
int isIdle() { return m_is_idle; }
};
@@ -276,11 +268,10 @@ class eTimer
{
friend class eMainloop;
eMainloop &context;
- timeval nextActivation;
+ timespec nextActivation;
long interval;
bool bSingleShot;
bool bActive;
- void addTimeOffset(int);
void activate();
public:
/**
@@ -296,7 +287,7 @@ public:
bool isActive() { return bActive; }
- timeval &getNextActivation() { return nextActivation; }
+ timespec &getNextActivation() { return nextActivation; }
void start(long msec, bool b=false);
void stop();