eris  1.4.0
A WorldForge client library.
EventService.cpp
1 #include "EventService.h"
2 #include "WaitFreeQueue.h"
3 #include "ActiveMarker.h"
4 
5 #include <cassert>
6 #include <iostream>
7 
8 namespace Eris
9 {
10 
11 TimedEvent::TimedEvent(EventService& eventService,
12  const std::chrono::steady_clock::duration& duration,
13  const std::function<void()>& callback) :
14  m_timer(eventService.createTimer())
15 {
16  assert(m_timer);
17  m_timer->expires_from_now(duration);
18  m_timer->async_wait([&, callback](const boost::system::error_code& ec) {
19  if (!ec) {
20  callback();
21  }
22  });
23 }
24 
25 TimedEvent::~TimedEvent() = default;
26 
27 EventService::EventService(boost::asio::io_service& io_service) :
28  m_io_service(io_service),
29  m_work(new boost::asio::io_service::work(io_service)),
30  m_background_handlers_queue(new WaitFreeQueue<std::function<void()>>())
31 {
32 }
33 
35 {
36  m_work.reset();
37  //Poll to make sure that all pending asio handlers are processed, since these might create handlers which needs to be processed.
38  m_io_service.poll();
40 }
41 
42 std::unique_ptr<boost::asio::steady_timer> EventService::createTimer()
43 {
44  return std::make_unique<boost::asio::steady_timer>(m_io_service);
45 }
46 
47 void EventService::runOnMainThread(const std::function<void()>& handler,
48  std::shared_ptr<bool> activeMarker)
49 {
50  m_background_handlers_queue->push([handler, activeMarker]() {
51  if (*activeMarker) {
52  handler();
53  }
54  });
55 }
56 
57 void EventService::runOnMainThreadDelayed(const std::function<void()>& handler,
58  const std::chrono::steady_clock::duration& duration,
59  std::shared_ptr<bool> activeMarker) {
60  auto timer = std::make_shared<boost::asio::steady_timer>(m_io_service);
61  timer->expires_from_now(duration);
62  timer->async_wait([&, handler, activeMarker, timer](const boost::system::error_code& ec) {
63  if (!ec) {
64  runOnMainThread(handler, activeMarker);
65  }
66  });
67 
68 }
69 
71 {
72  collectHandlersQueue();
73 
74  size_t count = 0;
75  while (!m_handlers.empty()) {
76  std::function<void()> handler = std::move(this->m_handlers.front());
77  m_handlers.pop_front();
78  count++;
79  handler();
80  collectHandlersQueue();
81  }
82  return count;
83 }
84 
85 size_t EventService::collectHandlersQueue()
86 {
87  size_t count = 0;
88  WaitFreeQueue<std::function<void()>>::node * x = m_background_handlers_queue->pop_all();
89  while (x) {
90  WaitFreeQueue<std::function<void()>>::node* tmp = x;
91  x = x->next;
92  m_handlers.push_back(std::move(tmp->data));
93  delete tmp;
94  count++;
95  }
96  return count;
97 }
98 
100  collectHandlersQueue();
101  //If there are handlers registered, execute one of them now
102  if (!m_handlers.empty()) {
103  std::function<void()> handler = std::move(this->m_handlers.front());
104  m_handlers.pop_front();
105  handler();
106  return 1;
107  }
108  return 0;
109 }
110 
111 } // of namespace Eris
Eris::EventService::~EventService
~EventService()
Dtor.
Definition: EventService.cpp:34
Eris::EventService::runOnMainThreadDelayed
void runOnMainThreadDelayed(const std::function< void()> &handler, const std::chrono::steady_clock::duration &duration, std::shared_ptr< bool > activeMarker=std::make_shared< bool >(true))
Definition: EventService.cpp:57
Eris
Definition: Account.cpp:33
Eris::WaitFreeQueue
A queue optimized for insertion from background threads and consumption from one main thread.
Definition: EventService.h:34
Eris::EventService::processAllHandlers
size_t processAllHandlers()
Processes all registered handlers.
Definition: EventService.cpp:70
Eris::EventService::runOnMainThread
void runOnMainThread(const std::function< void()> &handler, std::shared_ptr< bool > activeMarker=std::make_shared< bool >(true))
Adds a handler which will be run on the main thread.
Definition: EventService.cpp:47
Eris::EventService::EventService
EventService(boost::asio::io_service &io_service)
Ctor.
Definition: EventService.cpp:27
Eris::EventService::processOneHandler
size_t processOneHandler()
Processes one handler, if possible.
Definition: EventService.cpp:99