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