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
8namespace Eris
9{
10
11TimedEvent::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
25TimedEvent::~TimedEvent() = default;
26
27EventService::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
42std::unique_ptr<boost::asio::steady_timer> EventService::createTimer()
43{
44 return std::make_unique<boost::asio::steady_timer>(m_io_service);
45}
46
47void 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
57void 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
85size_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
size_t processAllHandlers()
Processes all registered handlers.
size_t processOneHandler()
Processes one handler, if possible.
void runOnMainThreadDelayed(const std::function< void()> &handler, const std::chrono::steady_clock::duration &duration, std::shared_ptr< bool > activeMarker=std::make_shared< bool >(true))
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.
A queue optimized for insertion from background threads and consumption from one main thread.
Definition: WaitFreeQueue.h:40
Definition: Account.cpp:33