Timer实现


1. webkit中timer实现的框架类图

 1.1 TimerHeap其实就是一个容器,管理一个一个的Timer

 1.2 ThreadTimers 相当于整个timer模块的管理者,负责调度SharedTimer并且操作TimerHeap

 1.3 SharedTimer是平台相关的一个类 源码如下:

 

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. public:  
  2.        virtual ~SharedTimer() {}  
  3.        virtual void setFiredFunction(void (*)()) = 0;  
  4.        // The fire time is relative to the classic POSIX epoch of January 1, 1970,  
  5.        // as the result of currentTime() is.  
  6.        virtual void setFireTime(double) = 0;  
  7.        virtual void stop() = 0;  
  8.    };  
  9.    // Implemented by port (since it provides the run loop for the main thread).  
  10.    // FIXME: make ports implement MainThreadSharedTimer directly instead.  
  11.    void setSharedTimerFiredFunction(void (*)());  
  12.    void setSharedTimerFireTime(double);  
  13.    void stopSharedTimer();  
  14.    // Implementation of SharedTimer for the main thread.  
  15.    class MainThreadSharedTimer : public SharedTimer {  
  16.    public:  
  17.        virtual void setFiredFunction(void (*function)())  
  18.        {  
  19.            setSharedTimerFiredFunction(function);  
  20.        }  
  21.          
  22.        virtual void setFireTime(double fireTime)  
  23.        {  
  24.            setSharedTimerFireTime(fireTime);  
  25.        }  
  26.          
  27.        virtual void stop()  
  28.        {  
  29.            stopSharedTimer();  
  30.        }  
  31.    };  
 

 

需要设置一个回调函数给底层的Timer,也是通过这个回调,底层timer与上层的结合起来

回调函数是ThreadTimers的一个成员函数,代码如下:

 

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. void ThreadTimers::sharedTimerFiredInternal()  
  2. {  
  3.     // Do a re-entrancy check.  
  4.     if (m_firingTimers)  
  5.         return;  
  6.     m_firingTimers = true;  
  7.     double fireTime = currentTime();  
  8.     double timeToQuit = fireTime + maxDurationOfFiringTimers;  
  9.     while (!m_timerHeap.isEmpty() && m_timerHeap.first()->m_nextFireTime <= fireTime) {  
  10.         TimerBase* timer = m_timerHeap.first();  
  11.         timer->m_nextFireTime = 0;  
  12.         timer->heapDeleteMin();  
  13.         double interval = timer->repeatInterval();  
  14.         timer->setNextFireTime(interval ? fireTime + interval : 0);  
  15.         // Once the timer has been fired, it may be deleted, so do nothing else with it after this point.  
  16.         timer->fired();  
  17.         // Catch the case where the timer asked timers to fire in a nested event loop, or we are over time limit.  
  18.         if (!m_firingTimers || timeToQuit < currentTime())  
  19.             break;  
  20.     }  
  21.     m_firingTimers = false;  
  22.     updateSharedTimer();  
  23. }  
 

 

通过这个回调,ThreadTimers就从TimerHeap中取出一个个的Timer来执行

 1.5 注意Webkit中timer的实现是用模板实现,直接上源代码

 

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. template <typename TimerFiredClass> class Timer : public TimerBase {  
  2. public:  
  3.     typedef void (TimerFiredClass::*TimerFiredFunction)(Timer*);  
  4.     Timer(TimerFiredClass* o, TimerFiredFunction f)  
  5.         : m_object(o), m_function(f) { }  
  6. private:  
  7.     virtual void fired() { (m_object->*m_function)(this); }  
  8.     TimerFiredClass* m_object;  
  9.     TimerFiredFunction m_function;  
  10. };  
 

 

2. webkit中如何应用timer

 通过小弟几天的分析,不知正确与否,webkit主要是通过这个timer实现异步,下面以一个场景为例,呈上时序图

场景描述: DOMHTMLParser解析html文档的时候,如果html文档的标签数超过了引擎规定的默认标签且解析时间超过了允许的最长解析时间,会停止解析,通过一个timer异步,之后再timer回调中恢复解析

时序图如下:

timer回调得到执行的时序图如下:

HTMLDocumentSheduler 初始化timer的代码:

 

  1. 类成员:Timer<HTMLParserScheduler> m_continueNextChunkTimer;  
  2. 构造函数:  
  3. HTMLParserScheduler::HTMLParserScheduler(HTMLDocumentParser* parser)  
  4.     : m_parser(parser)  
  5.     , m_parserTimeLimit(parserTimeLimit(m_parser->document()->page()))  
  6.     , m_parserChunkSize(parserChunkSize(m_parser->document()->page()))  
  7.     , m_continueNextChunkTimer(this, &HTMLParserScheduler::continueNextChunkTimerFired)  
  8. {  
  9. }  

 

这样整个timer模块的设计思路和应用场景就清楚了

3. 系统如何初始化timer模块

神马都是浮云,直接上时序图

Timer源码:

 

  1. #ifndef Timer_h  
  2. #define Timer_h  
  3. #include <wtf/Noncopyable.h>  
  4. #include <wtf/Threading.h>  
  5. namespace WebCore {  
  6. // Time intervals are all in seconds.  
  7. class TimerHeapElement;  
  8. class TimerBase : public Noncopyable {  
  9. public:  
  10.     TimerBase();  
  11.     virtual ~TimerBase();  
  12.     void start(double nextFireInterval, double repeatInterval);  
  13.     void startRepeating(double repeatInterval) { start(repeatInterval, repeatInterval); }  
  14.     void startOneShot(double interval) { start(interval, 0); }  
  15.     void stop();  
  16.     bool isActive() const;  
  17.     double nextFireInterval() const;  
  18.     double repeatInterval() const { return m_repeatInterval; }  
  19.     void augmentRepeatInterval(double delta) { setNextFireTime(m_nextFireTime + delta); m_repeatInterval += delta; }  
  20.     static void fireTimersInNestedEventLoop();  
  21. private:  
  22.     virtual void fired() = 0;  
  23.     void checkConsistency() const;  
  24.     void checkHeapIndex() const;  
  25.     void setNextFireTime(double);  
  26.     bool inHeap() const { return m_heapIndex != -1; }  
  27.     void heapDecreaseKey();  
  28.     void heapDelete();  
  29.     void heapDeleteMin();  
  30.     void heapIncreaseKey();  
  31.     void heapInsert();  
  32.     void heapPop();  
  33.     void heapPopMin();  
  34.     double m_nextFireTime; // 0 if inactive  
  35.     double m_repeatInterval; // 0 if not repeating  
  36.     int m_heapIndex; // -1 if not in heap  
  37.     unsigned m_heapInsertionOrder; // Used to keep order among equal-fire-time timers  
  38. #ifndef NDEBUG  
  39.     ThreadIdentifier m_thread;  
  40. #endif  
  41.     friend class TimerHeapElement;  
  42.     friend class ThreadTimers;  
  43.     friend bool operator<(const TimerHeapElement&, const TimerHeapElement&);  
  44. };  
  45. template <typename TimerFiredClass> class Timer : public TimerBase {  
  46. public:  
  47.     typedef void (TimerFiredClass::*TimerFiredFunction)(Timer*);  
  48.     Timer(TimerFiredClass* o, TimerFiredFunction f)  
  49.         : m_object(o), m_function(f) { }  
  50. private:  
  51.     virtual void fired() { (m_object->*m_function)(this); }  
  52.     TimerFiredClass* m_object;  
  53.     TimerFiredFunction m_function;  
  54. };  
  55. inline bool TimerBase::isActive() const  
  56. {  
  57.     ASSERT(m_thread == currentThread());  
  58.     return m_nextFireTime;  
  59. }  
  60. }  
  61. #endif  
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值