From: Felix Domke Date: Sun, 16 Oct 2005 01:21:12 +0000 (+0000) Subject: cleaned up poll core X-Git-Tag: 2.6.0~5448 X-Git-Url: https://git.cweiske.de/enigma2.git/commitdiff_plain/3392a6ecccfe92d342eebe58736d9e33f8332943 cleaned up poll core --- diff --git a/lib/base/ebase.cpp b/lib/base/ebase.cpp index 19444d20..2ad023b9 100644 --- a/lib/base/ebase.cpp +++ b/lib/base/ebase.cpp @@ -45,7 +45,6 @@ void eTimer::start(long msek, bool singleShot) bSingleShot = singleShot; interval = msek; gettimeofday(&nextActivation, 0); - nextActivation.tv_sec -= context.getTimerOffset(); nextActivation += (msek<0 ? 0 : msek); // eDebug("this = %p\nnow sec = %d, usec = %d\nadd %d msec", this, nextActivation.tv_sec, nextActivation.tv_usec, msek); // eDebug("next Activation sec = %d, usec = %d", nextActivation.tv_sec, nextActivation.tv_usec ); @@ -60,7 +59,6 @@ void eTimer::startLongTimer( int seconds ) bActive = bSingleShot = true; interval = 0; gettimeofday(&nextActivation, 0); - nextActivation.tv_sec -= context.getTimerOffset(); // eDebug("this = %p\nnow sec = %d, usec = %d\nadd %d msec", this, nextActivation.tv_sec, nextActivation.tv_usec, msek); if ( seconds > 0 ) nextActivation.tv_sec += seconds; @@ -108,7 +106,7 @@ void eTimer::activate() // Internal Funktion... called from eApplication /*emit*/ timeout(); } -inline void eTimer::recalc( int offset ) +void eTimer::addTimeOffset( int offset ) { nextActivation.tv_sec += offset; } @@ -116,20 +114,6 @@ inline void eTimer::recalc( int offset ) // mainloop ePtrList eMainloop::existing_loops; -void eMainloop::setTimerOffset( int difference ) -{ - singleLock s(recalcLock); - if (!TimerList) - timer_offset=0; - else - { - if ( timer_offset ) - eDebug("time_offset %d avail.. add new offset %d than new is %d", - timer_offset, difference, timer_offset+difference); - timer_offset+=difference; - } -} - void eMainloop::addSocketNotifier(eSocketNotifier *sn) { notifiers.insert(std::pair (sn->getFD(), sn)); @@ -173,60 +157,90 @@ void eMainloop::processOneEvent() time anyway */ - // first, process pending timers... - long usec=0; - - if ( TimerList ) - doRecalcTimers(); - while (TimerList && (usec = timeout_usec( TimerList.begin()->getNextActivation() ) ) <= 0 ) + /* get current time */ + timeval now; + gettimeofday(&now, 0); + + int poll_timeout = -1; /* infinite in case of empty timer list */ + + if (m_timer_list) { - TimerList.begin()->activate(); - doRecalcTimers(); + poll_timeout = timeval_to_usec(m_timer_list.begin()->getNextActivation() - now); + /* if current timer already passed, don't delay infinite. */ + if (poll_timeout < 0) + poll_timeout = 0; + + /* convert us to ms */ + poll_timeout /= 1000; } + + int ret = 0; - int fdAnz = notifiers.size(); - pollfd pfd[fdAnz]; - -// fill pfd array - std::map::iterator it(notifiers.begin()); - for (int i=0; i < fdAnz; i++, it++) + if (poll_timeout) { - pfd[i].fd = it->first; - pfd[i].events = it->second->getRequested(); - } - - // to the poll. When there are no timers, we have an infinite timeout - int ret=poll(pfd, fdAnz, TimerList ? usec / 1000 : -1); // convert to ms + // build the poll aray + int fdcount = notifiers.size(); + pollfd* pfd = new pollfd[fdcount]; // make new pollfd array - if (ret>0) - { - // eDebug("bin aussem poll raus und da war was"); - for (int i=0; i < fdAnz ; i++) + std::map::iterator it(notifiers.begin()); + for (int i=0; i < fdcount; i++, it++) { - if( notifiers.find(pfd[i].fd) == notifiers.end()) - continue; + pfd[i].fd = it->first; + pfd[i].events = it->second->getRequested(); + } - int req = notifiers[pfd[i].fd]->getRequested(); + ret = poll(pfd, fdcount, poll_timeout); - if ( pfd[i].revents & req ) + /* ret > 0 means that there are some active poll entries. */ + if (ret > 0) + { + for (int i=0; i < fdcount ; i++) { - notifiers[pfd[i].fd]->activate(pfd[i].revents); - if (!--ret) - break; + if (notifiers.find(pfd[i].fd) == notifiers.end()) + continue; + + int req = notifiers[pfd[i].fd]->getRequested(); + + if (pfd[i].revents & req) + { + notifiers[pfd[i].fd]->activate(pfd[i].revents); + + if (!--ret) + break; + } else if (pfd[i].revents & (POLLERR|POLLHUP|POLLNVAL)) + eFatal("poll: unhandled POLLERR/HUP/NVAL for fd %d(%d) -> FIX YOUR CODE", pfd[i].fd,pfd[i].revents); } - else if (pfd[i].revents & (POLLERR|POLLHUP|POLLNVAL)) - eDebug("poll: unhandled POLLERR/HUP/NVAL for fd %d(%d)", pfd[i].fd,pfd[i].revents); + } else if (ret < 0) + { + /* when we got a signal, we get EINTR. we do not care, + because we check current time in timers anyway. */ + if (errno != EINTR) + eDebug("poll made error (%m)"); + else + ret = 0; } + delete [] pfd; } - else if (ret<0) + + /* when we not processed anything, check timers. */ + if (!ret) { - /* when we got a signal, we get EINTR. we do not care, - because we check current time in timers anyway. */ - if (errno != EINTR) - eDebug("poll made error"); + /* process all timers which are ready. first remove them out of the list. */ + while ((!m_timer_list.empty()) && (m_timer_list.begin()->getNextActivation() < now)) + m_timer_list.begin()->activate(); } } +void eMainloop::addTimer(eTimer* e) +{ + m_timer_list.insert_in_order(e); +} + +void eMainloop::removeTimer(eTimer* e) +{ + m_timer_list.remove(e); +} + int eMainloop::exec() { if (!loop_level) @@ -271,15 +285,11 @@ void eMainloop::quit( int ret ) // call this to leave all loops app_quit_now = true; } -inline void eMainloop::doRecalcTimers() +void eMainloop::addTimeOffset(int offset) { singleLock s(recalcLock); - if ( timer_offset ) - { - for (ePtrList::iterator it(TimerList); it != TimerList.end(); ++it ) - it->recalc( timer_offset ); - timer_offset=0; - } + for (ePtrList::iterator it(m_timer_list); it != m_timer_list.end(); ++it ) + it->addTimeOffset(offset); } eApplication* eApp = 0; diff --git a/lib/base/ebase.h b/lib/base/ebase.h index aaabd30d..7fd5af02 100644 --- a/lib/base/ebase.h +++ b/lib/base/ebase.h @@ -16,6 +16,7 @@ class eApplication; extern eApplication* eApp; + /* TODO: remove these inlines. */ static inline bool operator<( const timeval &t1, const timeval &t2 ) { return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_usec < t2.tv_usec); @@ -113,20 +114,9 @@ static inline timeval operator-=( timeval &t1, const long msek ) return t1; } -static inline timeval timeout_timeval ( const timeval & orig ) +static inline int timeval_to_usec(const timeval &t1) { - timeval now; - gettimeofday(&now,0); - - return orig-now; -} - -static inline long timeout_usec ( const timeval & orig ) -{ - timeval now; - gettimeofday(&now,0); - - return (orig-now).tv_sec*1000000 + (orig-now).tv_usec; + return t1.tv_sec*1000000 + t1.tv_usec; } class eMainloop; @@ -179,7 +169,7 @@ class eMainloop friend class eTimer; friend class eSocketNotifier; std::map notifiers; - ePtrList TimerList; + ePtrList m_timer_list; bool app_exit_loop; bool app_quit_now; int loop_level; @@ -187,12 +177,13 @@ class eMainloop int retval; int timer_offset; pthread_mutex_t recalcLock; - inline void doRecalcTimers(); - inline void addSocketNotifier(eSocketNotifier *sn); - inline void removeSocketNotifier(eSocketNotifier *sn); - inline void addTimer(eTimer* e) { TimerList.insert_in_order(e); } - inline void removeTimer(eTimer* e) { TimerList.remove(e); } public: + void addTimeOffset(int offset); + void addSocketNotifier(eSocketNotifier *sn); + void removeSocketNotifier(eSocketNotifier *sn); + void addTimer(eTimer* e); + void removeTimer(eTimer* e); + static ePtrList existing_loops; eMainloop() :app_quit_now(0),loop_level(0),retval(0),timer_offset(0) @@ -207,13 +198,11 @@ public: } int looplevel() { return loop_level; } + /* OBSOLETE. DONT USE. */ int exec(); // recursive enter the loop void quit(int ret=0); // leave all pending loops (recursive leave()) void enter_loop(); void exit_loop(); - void setTimerOffset( int ); - int getTimerOffset() { return timer_offset; } - bool isAppQuitNowSet() { return app_quit_now; } }; /** @@ -250,7 +239,6 @@ class eTimer long interval; bool bSingleShot; bool bActive; - inline void recalc(int); public: /** * \brief Constructs a timer. @@ -272,5 +260,6 @@ public: void changeInterval(long msek); bool operator<(const eTimer& t) const { return nextActivation < t.nextActivation; } void startLongTimer( int seconds ); + void addTimeOffset(int); }; #endif