xref: /openbmc/sdeventplus/src/sdeventplus/utility/sdbus.hpp (revision a8c11e3ca342b090aec615c832b85686bd4655f6)
1 #include <sdbusplus/bus.hpp>
2 #include <sdeventplus/event.hpp>
3 #include <sdeventplus/exception.hpp>
4 
5 #include <stdexcept>
6 
7 namespace sdeventplus::utility
8 {
9 
10 /**
11  * @brief Run and event loop with a given bus, bug workaround
12  * @detail There is a known issue with systemd not correctly dispatching
13  *         all of the events for a given bus. We need a workaround to
14  *         prevent memory leaks.
15  *         https://github.com/systemd/systemd/issues/22046
16  */
loopWithBus(Event & event,sdbusplus::bus_t & bus)17 inline int loopWithBus(Event& event, sdbusplus::bus_t& bus)
18 {
19     bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
20     try
21     {
22         do
23         {
24             if (bus.is_open())
25             {
26                 // Process all outstanding bus events before running the loop.
27                 // This prevents the sd-bus handling logic from leaking memory.
28                 while (bus.process_discard() > 0)
29                     ;
30             }
31         } while (event.run(std::nullopt) > 0);
32     }
33     catch (const SdEventError& e)
34     {
35         if (e.code().value() == ESTALE)
36         {
37             return event.get_exit_code();
38         }
39         throw;
40     }
41     throw std::runtime_error("Unknown sd-event terminaton");
42 }
43 
44 } // namespace sdeventplus::utility
45