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