1*b5645947SKrzysztof Grobelny #include "dbus_environment.hpp"
2*b5645947SKrzysztof Grobelny 
3*b5645947SKrzysztof Grobelny #include <future>
4*b5645947SKrzysztof Grobelny #include <thread>
5*b5645947SKrzysztof Grobelny 
6*b5645947SKrzysztof Grobelny DbusEnvironment::~DbusEnvironment()
7*b5645947SKrzysztof Grobelny {
8*b5645947SKrzysztof Grobelny     teardown();
9*b5645947SKrzysztof Grobelny }
10*b5645947SKrzysztof Grobelny 
11*b5645947SKrzysztof Grobelny void DbusEnvironment::SetUp()
12*b5645947SKrzysztof Grobelny {
13*b5645947SKrzysztof Grobelny     if (setUp == false)
14*b5645947SKrzysztof Grobelny     {
15*b5645947SKrzysztof Grobelny         setUp = true;
16*b5645947SKrzysztof Grobelny 
17*b5645947SKrzysztof Grobelny         bus = std::make_shared<sdbusplus::asio::connection>(ioc);
18*b5645947SKrzysztof Grobelny         bus->request_name(serviceName());
19*b5645947SKrzysztof Grobelny 
20*b5645947SKrzysztof Grobelny         objServer = std::make_unique<sdbusplus::asio::object_server>(bus);
21*b5645947SKrzysztof Grobelny     }
22*b5645947SKrzysztof Grobelny }
23*b5645947SKrzysztof Grobelny 
24*b5645947SKrzysztof Grobelny void DbusEnvironment::TearDown()
25*b5645947SKrzysztof Grobelny {
26*b5645947SKrzysztof Grobelny     ioc.poll();
27*b5645947SKrzysztof Grobelny 
28*b5645947SKrzysztof Grobelny     futures.clear();
29*b5645947SKrzysztof Grobelny }
30*b5645947SKrzysztof Grobelny 
31*b5645947SKrzysztof Grobelny void DbusEnvironment::teardown()
32*b5645947SKrzysztof Grobelny {
33*b5645947SKrzysztof Grobelny     if (setUp == true)
34*b5645947SKrzysztof Grobelny     {
35*b5645947SKrzysztof Grobelny         setUp = false;
36*b5645947SKrzysztof Grobelny 
37*b5645947SKrzysztof Grobelny         objServer = nullptr;
38*b5645947SKrzysztof Grobelny         bus = nullptr;
39*b5645947SKrzysztof Grobelny     }
40*b5645947SKrzysztof Grobelny }
41*b5645947SKrzysztof Grobelny 
42*b5645947SKrzysztof Grobelny boost::asio::io_context& DbusEnvironment::getIoc()
43*b5645947SKrzysztof Grobelny {
44*b5645947SKrzysztof Grobelny     return ioc;
45*b5645947SKrzysztof Grobelny }
46*b5645947SKrzysztof Grobelny 
47*b5645947SKrzysztof Grobelny std::shared_ptr<sdbusplus::asio::connection> DbusEnvironment::getBus()
48*b5645947SKrzysztof Grobelny {
49*b5645947SKrzysztof Grobelny     return bus;
50*b5645947SKrzysztof Grobelny }
51*b5645947SKrzysztof Grobelny 
52*b5645947SKrzysztof Grobelny std::shared_ptr<sdbusplus::asio::object_server> DbusEnvironment::getObjServer()
53*b5645947SKrzysztof Grobelny {
54*b5645947SKrzysztof Grobelny     return objServer;
55*b5645947SKrzysztof Grobelny }
56*b5645947SKrzysztof Grobelny 
57*b5645947SKrzysztof Grobelny const char* DbusEnvironment::serviceName()
58*b5645947SKrzysztof Grobelny {
59*b5645947SKrzysztof Grobelny     return "telemetry.ut";
60*b5645947SKrzysztof Grobelny }
61*b5645947SKrzysztof Grobelny 
62*b5645947SKrzysztof Grobelny std::function<void()> DbusEnvironment::setPromise(std::string_view name)
63*b5645947SKrzysztof Grobelny {
64*b5645947SKrzysztof Grobelny     auto promise = std::make_shared<std::promise<bool>>();
65*b5645947SKrzysztof Grobelny 
66*b5645947SKrzysztof Grobelny     {
67*b5645947SKrzysztof Grobelny         futures[std::string(name)].emplace_back(promise->get_future());
68*b5645947SKrzysztof Grobelny     }
69*b5645947SKrzysztof Grobelny 
70*b5645947SKrzysztof Grobelny     return [p = std::move(promise)]() { p->set_value(true); };
71*b5645947SKrzysztof Grobelny }
72*b5645947SKrzysztof Grobelny 
73*b5645947SKrzysztof Grobelny bool DbusEnvironment::waitForFuture(std::string_view name,
74*b5645947SKrzysztof Grobelny                                     std::chrono::milliseconds timeout)
75*b5645947SKrzysztof Grobelny {
76*b5645947SKrzysztof Grobelny     return waitForFuture(getFuture(name), timeout).value_or(false);
77*b5645947SKrzysztof Grobelny }
78*b5645947SKrzysztof Grobelny 
79*b5645947SKrzysztof Grobelny std::future<bool> DbusEnvironment::getFuture(std::string_view name)
80*b5645947SKrzysztof Grobelny {
81*b5645947SKrzysztof Grobelny     auto& data = futures[std::string(name)];
82*b5645947SKrzysztof Grobelny     auto it = data.begin();
83*b5645947SKrzysztof Grobelny 
84*b5645947SKrzysztof Grobelny     if (it != data.end())
85*b5645947SKrzysztof Grobelny     {
86*b5645947SKrzysztof Grobelny         auto result = std::move(*it);
87*b5645947SKrzysztof Grobelny         data.erase(it);
88*b5645947SKrzysztof Grobelny         return result;
89*b5645947SKrzysztof Grobelny     }
90*b5645947SKrzysztof Grobelny 
91*b5645947SKrzysztof Grobelny     return {};
92*b5645947SKrzysztof Grobelny }
93*b5645947SKrzysztof Grobelny 
94*b5645947SKrzysztof Grobelny void DbusEnvironment::sleepFor(std::chrono::milliseconds timeout)
95*b5645947SKrzysztof Grobelny {
96*b5645947SKrzysztof Grobelny     auto end = std::chrono::high_resolution_clock::now() + timeout;
97*b5645947SKrzysztof Grobelny 
98*b5645947SKrzysztof Grobelny     while (std::chrono::high_resolution_clock::now() < end)
99*b5645947SKrzysztof Grobelny     {
100*b5645947SKrzysztof Grobelny         synchronizeIoc();
101*b5645947SKrzysztof Grobelny         std::this_thread::yield();
102*b5645947SKrzysztof Grobelny     }
103*b5645947SKrzysztof Grobelny 
104*b5645947SKrzysztof Grobelny     synchronizeIoc();
105*b5645947SKrzysztof Grobelny }
106*b5645947SKrzysztof Grobelny 
107*b5645947SKrzysztof Grobelny std::chrono::milliseconds
108*b5645947SKrzysztof Grobelny     DbusEnvironment::measureTime(std::function<void()> fun)
109*b5645947SKrzysztof Grobelny {
110*b5645947SKrzysztof Grobelny     auto begin = std::chrono::high_resolution_clock::now();
111*b5645947SKrzysztof Grobelny     fun();
112*b5645947SKrzysztof Grobelny     auto end = std::chrono::high_resolution_clock::now();
113*b5645947SKrzysztof Grobelny 
114*b5645947SKrzysztof Grobelny     return std::chrono::duration_cast<std::chrono::milliseconds>(end - begin);
115*b5645947SKrzysztof Grobelny }
116*b5645947SKrzysztof Grobelny 
117*b5645947SKrzysztof Grobelny boost::asio::io_context DbusEnvironment::ioc;
118*b5645947SKrzysztof Grobelny std::shared_ptr<sdbusplus::asio::connection> DbusEnvironment::bus;
119*b5645947SKrzysztof Grobelny std::shared_ptr<sdbusplus::asio::object_server> DbusEnvironment::objServer;
120*b5645947SKrzysztof Grobelny std::map<std::string, std::vector<std::future<bool>>> DbusEnvironment::futures;
121*b5645947SKrzysztof Grobelny bool DbusEnvironment::setUp = false;
122