async.cpp 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #include "async.h"
  2. namespace bbAsync{
  3. typedef std::chrono::duration<double> Duration;
  4. typedef std::chrono::high_resolution_clock Clock;
  5. typedef std::chrono::time_point<Clock,Duration> TimePoint;
  6. struct DelayedEvent{
  7. DelayedEvent *succ;
  8. Event *event;
  9. TimePoint time;
  10. };
  11. DelayedEvent *que;
  12. DelayedEvent *free_que;
  13. std::mutex que_mutex;
  14. std::condition_variable que_condvar;
  15. void initQue(){
  16. static bool inited;
  17. if( inited ) return;
  18. inited=true;
  19. std::thread( [](){
  20. std::unique_lock<std::mutex> lock( que_mutex );
  21. for(;;){
  22. if( que ){
  23. que_condvar.wait_until( lock,que->time );
  24. }else{
  25. que_condvar.wait( lock );
  26. }
  27. while( que && que->time<=Clock::now() ){
  28. DelayedEvent *devent=que;
  29. que=devent->succ;
  30. devent->event->post();
  31. devent->succ=free_que;
  32. free_que=devent;
  33. }
  34. }
  35. } ).detach();
  36. }
  37. void (*postEventFilter)( Event* );
  38. void setPostEventFilter( void(*filter)(Event*) ){
  39. postEventFilter=filter;
  40. }
  41. void Event::post(){
  42. postEventFilter( this );
  43. }
  44. void Event::post( double delay ){
  45. TimePoint time=Clock::now()+Duration( delay );
  46. initQue();
  47. {
  48. std::lock_guard<std::mutex> lock( que_mutex );
  49. DelayedEvent *devent=free_que;
  50. if( devent ){
  51. free_que=devent->succ;
  52. }else{
  53. devent=new DelayedEvent;
  54. }
  55. devent->event=this;
  56. devent->time=time;
  57. DelayedEvent *succ,**pred=&que;
  58. while( succ=*pred ){
  59. if( devent->time<succ->time ) break;
  60. pred=&succ->succ;
  61. }
  62. devent->succ=succ;
  63. *pred=devent;
  64. }
  65. que_condvar.notify_one();
  66. }
  67. }