Advertisement
Guest User

Untitled

a guest
Jul 24th, 2019
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.96 KB | None | 0 0
  1.  
  2. class WorkTask
  3. {
  4. public:
  5. void SetEventId(uint32_t id)
  6. {
  7. eventId_ = id;
  8. }
  9.  
  10. uint32_t GetEventId() const
  11. {
  12. return eventId_;
  13. }
  14.  
  15. void SetLastExecution(int64_t time)
  16. {
  17. lastExecution_ = time;
  18. }
  19.  
  20. int64_t GetLastExecution() const
  21. {
  22. return lastExecution_;
  23. }
  24.  
  25. int64_t GetPeriod() const
  26. {
  27. return period_;
  28. }
  29.  
  30. bool IsReutilizable() const
  31. {
  32. return reutilize_;
  33. }
  34.  
  35. std::function<void(void)> GetFunc()
  36. {
  37. return func_;
  38. }
  39.  
  40. private:
  41. WorkTask(uint32_t period, std::function<void(void)>&& f, bool reutilize) :
  42. period_(period), reutilize_(reutilize), func_(f) {}
  43.  
  44. bool reutilize_;
  45.  
  46. int64_t period_;
  47. int64_t lastExecution_ = 0;
  48. uint32_t eventId_ = 0;
  49.  
  50. std::function<void(void)> func_;
  51.  
  52. friend WorkTask* createWorkerTask(uint32_t, std::function<void(void)>, bool);
  53. };
  54.  
  55. WorkTask* createWorkerTask(uint32_t delay, std::function<void(void)> f, bool reutilize = true);
  56.  
  57. bool periodSort(const WorkTask* lhs, const WorkTask* rhs);
  58.  
  59. class Worker : public ThreadHolder<Worker>
  60. {
  61. public:
  62. Worker(Dispatcher& dispatcher)
  63. : dispatcher_(dispatcher)
  64. {
  65.  
  66. }
  67.  
  68. uint32_t AddWork(WorkTask* task);
  69. bool StopWork(uint32_t eventId);
  70.  
  71. void Shutdown();
  72.  
  73. void ThreadMain();
  74.  
  75. private:
  76. std::thread thread_;
  77. std::mutex eventLock_;
  78. std::condition_variable eventSignal_;
  79.  
  80. Dispatcher& dispatcher_;
  81.  
  82. uint32_t lastEventId_{ 0 };
  83. std::list<WorkTask*> workList_;
  84. std::unordered_set<uint32_t> eventIds_;
  85. };
  86.  
  87.  
  88. WorkTask* createWorkerTask(uint32_t delay, std::function<void(void)> f, bool reutilize)
  89. {
  90. return new WorkTask(delay, std::move(f), reutilize);
  91. }
  92.  
  93. bool periodSort(const WorkTask* lhs, const WorkTask* rhs)
  94. {
  95. return lhs->GetPeriod() < rhs->GetPeriod();
  96. }
  97.  
  98. uint32_t Worker::AddWork(WorkTask* task)
  99. {
  100. eventLock_.lock();
  101.  
  102. if (getState() != THREAD_STATE_RUNNING)
  103. {
  104. eventLock_.unlock();
  105. delete task;
  106. return 0;
  107. }
  108.  
  109. if (task->GetEventId() == 0)
  110. {
  111. if (++lastEventId_ == 0)
  112. {
  113. lastEventId_ = 1;
  114. }
  115.  
  116. task->SetEventId(lastEventId_);
  117. }
  118.  
  119.  
  120. // insert the event id in the list of active events
  121. uint32_t eventId = task->GetEventId();
  122. eventIds_.insert(eventId);
  123.  
  124. bool doSignal = workList_.empty();
  125.  
  126. // Set to the work list
  127. workList_.push_back(task);
  128. workList_.sort(&periodSort);
  129.  
  130. eventLock_.unlock();
  131.  
  132. if (doSignal)
  133. {
  134. eventSignal_.notify_one();
  135. }
  136.  
  137. return eventId;
  138. }
  139.  
  140. bool Worker::StopWork(uint32_t eventId)
  141. {
  142. if (eventId == 0)
  143. {
  144. return false;
  145. }
  146.  
  147. std::lock_guard<std::mutex> lockClass(eventLock_);
  148.  
  149. for (auto it = workList_.begin(); it != workList_.end(); it++)
  150. {
  151. if ((*it)->GetEventId() == eventId)
  152. {
  153. workList_.erase(it);
  154. return true;
  155. }
  156. }
  157.  
  158. return false;
  159. }
  160.  
  161. void Worker::Shutdown()
  162. {
  163. setState(THREAD_STATE_TERMINATED);
  164.  
  165. eventLock_.lock();
  166.  
  167. for (auto it = workList_.begin(); it != workList_.end(); it++)
  168. {
  169. workList_.erase(it);
  170. delete* it; // vai dar merda
  171. }
  172.  
  173. eventIds_.clear();
  174. eventLock_.unlock();
  175. eventSignal_.notify_one();
  176. }
  177.  
  178. void Worker::ThreadMain()
  179. {
  180. std::unique_lock<std::mutex> eventLockUnique(eventLock_, std::defer_lock);
  181.  
  182. while (getState() != THREAD_STATE_TERMINATED)
  183. {
  184. eventLockUnique.lock();
  185. if (workList_.empty())
  186. {
  187. eventSignal_.wait(eventLockUnique);
  188. }
  189.  
  190. WorkTask* workToRun = nullptr;
  191.  
  192. for (auto it = workList_.begin(); it != workList_.end(); it++)
  193. {
  194. int64_t now = W2SYS_TIME();
  195.  
  196. if (!(*it)->IsReutilizable())
  197. {
  198. workToRun = *it;
  199.  
  200. workList_.erase(it);
  201.  
  202. break;
  203. }
  204.  
  205. if((now - (*it)->GetLastExecution()) >= (*it)->GetPeriod())
  206. {
  207. workToRun = *it;
  208.  
  209. (*it)->SetLastExecution(now);
  210.  
  211. break;
  212. }
  213.  
  214. eventSignal_.wait_until(eventLockUnique,
  215. std::chrono::system_clock::time_point(std::chrono::system_clock::now()
  216. + std::chrono::milliseconds((*it)->GetPeriod())));
  217. }
  218.  
  219. if (workToRun != nullptr)
  220. {
  221. dispatcher_.AddTask(createTask(workToRun->GetFunc()));
  222. }
  223.  
  224. eventLockUnique.unlock();
  225. }
  226. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement