webkit中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. virtualvoidsetFiredFunction(void(*)())=0;
  4. //ThefiretimeisrelativetotheclassicPOSIXepochofJanuary1,1970,
  5. //astheresultofcurrentTime()is.
  6. virtualvoidsetFireTime(double)=0;
  7. virtualvoidstop()=0;
  8. };
  9. //Implementedbyport(sinceitprovidestherunloopforthemainthread).
  10. //FIXME:makeportsimplementMainThreadSharedTimerdirectlyinstead.
  11. voidsetSharedTimerFiredFunction(void(*)());
  12. voidsetSharedTimerFireTime(double);
  13. voidstopSharedTimer();
  14. //ImplementationofSharedTimerforthemainthread.
  15. classMainThreadSharedTimer:publicSharedTimer{
  16. public:
  17. virtualvoidsetFiredFunction(void(*function)())
  18. {
  19. setSharedTimerFiredFunction(function);
  20. }
  21. virtualvoidsetFireTime(doublefireTime)
  22. {
  23. setSharedTimerFireTime(fireTime);
  24. }
  25. virtualvoidstop()
  26. {
  27. stopSharedTimer();
  28. }
  29. };

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

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

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. voidThreadTimers::sharedTimerFiredInternal()
  2. {
  3. //Doare-entrancycheck.
  4. if(m_firingTimers)
  5. return;
  6. m_firingTimers=true;
  7. doublefireTime=currentTime();
  8. doubletimeToQuit=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. doubleinterval=timer->repeatInterval();
  14. timer->setNextFireTime(interval?fireTime+interval:0);
  15. //Oncethetimerhasbeenfired,itmaybedeleted,sodonothingelsewithitafterthispoint.
  16. timer->fired();
  17. //Catchthecasewherethetimeraskedtimerstofireinanestedeventloop,orweareovertimelimit.
  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<typenameTimerFiredClass>classTimer:publicTimerBase{
  2. public:
  3. typedefvoid(TimerFiredClass::*TimerFiredFunction)(Timer*);
  4. Timer(TimerFiredClass*o,TimerFiredFunctionf)
  5. :m_object(o),m_function(f){}
  6. private:
  7. virtualvoidfired(){(m_object->*m_function)(this);}
  8. TimerFiredClass*m_object;
  9. TimerFiredFunctionm_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. #ifndefTimer_h
  2. #defineTimer_h
  3. #include<wtf/Noncopyable.h>
  4. #include<wtf/Threading.h>
  5. namespaceWebCore{
  6. //Timeintervalsareallinseconds.
  7. classTimerHeapElement;
  8. classTimerBase:publicNoncopyable{
  9. public:
  10. TimerBase();
  11. virtual~TimerBase();
  12. voidstart(doublenextFireInterval,doublerepeatInterval);
  13. voidstartRepeating(doublerepeatInterval){start(repeatInterval,repeatInterval);}
  14. voidstartOneShot(doubleinterval){start(interval,0);}
  15. voidstop();
  16. boolisActive()const;
  17. doublenextFireInterval()const;
  18. doublerepeatInterval()const{returnm_repeatInterval;}
  19. voidaugmentRepeatInterval(doubledelta){setNextFireTime(m_nextFireTime+delta);m_repeatInterval+=delta;}
  20. staticvoidfireTimersInNestedEventLoop();
  21. private:
  22. virtualvoidfired()=0;
  23. voidcheckConsistency()const;
  24. voidcheckHeapIndex()const;
  25. voidsetNextFireTime(double);
  26. boolinHeap()const{returnm_heapIndex!=-1;}
  27. voidheapDecreaseKey();
  28. voidheapDelete();
  29. voidheapDeleteMin();
  30. voidheapIncreaseKey();
  31. voidheapInsert();
  32. voidheapPop();
  33. voidheapPopMin();
  34. doublem_nextFireTime;//0ifinactive
  35. doublem_repeatInterval;//0ifnotrepeating
  36. intm_heapIndex;//-1ifnotinheap
  37. unsignedm_heapInsertionOrder;//Usedtokeeporderamongequal-fire-timetimers
  38. #ifndefNDEBUG
  39. ThreadIdentifierm_thread;
  40. #endif
  41. friendclassTimerHeapElement;
  42. friendclassThreadTimers;
  43. friendbooloperator<(constTimerHeapElement&,constTimerHeapElement&);
  44. };
  45. template<typenameTimerFiredClass>classTimer:publicTimerBase{
  46. public:
  47. typedefvoid(TimerFiredClass::*TimerFiredFunction)(Timer*);
  48. Timer(TimerFiredClass*o,TimerFiredFunctionf)
  49. :m_object(o),m_function(f){}
  50. private:
  51. virtualvoidfired(){(m_object->*m_function)(this);}
  52. TimerFiredClass*m_object;
  53. TimerFiredFunctionm_function;
  54. };
  55. inlineboolTimerBase::isActive()const
  56. {
  57. ASSERT(m_thread==currentThread());
  58. returnm_nextFireTime;
  59. }
  60. }
  61. #endif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值