SHARE
TWEET

Untitled

a guest Jul 23rd, 2019 66 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const int   kDispatcherTaskExpiration = 2000;
  2. const auto  kSystemTimeZero = std::chrono::system_clock::time_point(std::chrono::milliseconds(0));
  3.  
  4. class Task
  5. {
  6. public:
  7.     explicit Task(std::function<void(void)>&& f) :
  8.         func_(std::move(f)) {}
  9.  
  10.     Task(uint32_t ms, std::function<void(void)>&& f) :
  11.         expiration(std::chrono::system_clock::now() + std::chrono::milliseconds(ms)), func_(std::move(f)) {}
  12.  
  13.     virtual ~Task() = default;
  14.  
  15.     void operator()()
  16.     {
  17.         func_();
  18.     }
  19.  
  20.     void SetDontExpire()
  21.     {
  22.         expiration = kSystemTimeZero;
  23.     }
  24.  
  25.     bool HasExpired() const
  26.     {
  27.         if (expiration == kSystemTimeZero)
  28.         {
  29.             return false;
  30.         }
  31.  
  32.         return expiration < std::chrono::system_clock::now();
  33.     }
  34.  
  35. protected:
  36.     std::chrono::system_clock::time_point expiration = kSystemTimeZero;
  37.  
  38. private:
  39.     std::function<void(void)> func_;
  40. };
  41.  
  42. Task* CreateTask(std::function<void(void)> f);
  43. Task* CreateTask(uint32_t expiration, std::function<void(void)> f);
  44.  
  45. class Dispatcher
  46. {
  47. public:
  48.     void AddTask(Task* task, bool push_front = false);
  49.     Task* GetTask();
  50.  
  51.     bool HasTaskToExecute() const
  52.     {
  53.         return !taskList_.empty();
  54.     }
  55.  
  56.     uint64_t GetDispatcherCycle() const
  57.     {
  58.         return dispatcherCycle_;
  59.     }
  60.  
  61. private:
  62.     std::mutex taskLock_;
  63.  
  64.     std::list<Task*> taskList_;
  65.     uint64_t dispatcherCycle_ = 0;
  66. };
  67.  
  68.  
  69. Task* CreateTask(std::function<void(void)> f)
  70. {
  71.     return new Task(std::move(f));
  72. }
  73.  
  74. Task* CreateTask(uint32_t expiration, std::function<void(void)> f)
  75. {
  76.     return new Task(expiration, std::move(f));
  77. }
  78.  
  79. void Dispatcher::AddTask(Task* task, bool push_front)
  80. {
  81.     bool doSignal = false;
  82.  
  83.     taskLock_.lock();
  84.    
  85.     doSignal = taskList_.empty();
  86.  
  87.     if (push_front)
  88.     {
  89.         taskList_.push_front(task);
  90.     }
  91.     else
  92.     {
  93.         taskList_.push_back(task);
  94.     }
  95.  
  96.     taskLock_.unlock();
  97. }
  98.  
  99. Task* Dispatcher::GetTask()
  100. {
  101.     // NOTE: second argument defer_lock is to prevent from immediate locking
  102.     std::unique_lock<std::mutex> taskLockUnique(taskLock_, std::defer_lock);
  103.    
  104.     taskLockUnique.lock();
  105.  
  106.     if (!taskList_.empty)
  107.     {
  108.         Task* task = taskList_.front();
  109.         taskList_.pop_front();
  110.  
  111.         taskLockUnique.unlock();
  112.  
  113.         if (!task->HasExpired())
  114.         {
  115.             ++dispatcherCycle_;
  116.  
  117.             return task;
  118.         }
  119.  
  120.         delete task;
  121.     }
  122.     else
  123.     {
  124.         taskLockUnique.unlock();
  125.     }
  126.  
  127.     return nullptr;
  128. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top