xref: /openbmc/sdbusplus/src/async/fdio.cpp (revision 2a12ae12)
1*2a12ae12SJagpal Singh Gill #include <sdbusplus/async/fdio.hpp>
2*2a12ae12SJagpal Singh Gill 
3*2a12ae12SJagpal Singh Gill namespace sdbusplus::async
4*2a12ae12SJagpal Singh Gill {
fdio(context & ctx,int fd)5*2a12ae12SJagpal Singh Gill fdio::fdio(context& ctx, int fd) : context_ref(ctx), fd(fd)
6*2a12ae12SJagpal Singh Gill {
7*2a12ae12SJagpal Singh Gill     static auto eventHandler =
8*2a12ae12SJagpal Singh Gill         [](sd_event_source*, int, uint32_t, void* data) noexcept {
9*2a12ae12SJagpal Singh Gill             static_cast<fdio*>(data)->handleEvent();
10*2a12ae12SJagpal Singh Gill             return 0;
11*2a12ae12SJagpal Singh Gill         };
12*2a12ae12SJagpal Singh Gill 
13*2a12ae12SJagpal Singh Gill     try
14*2a12ae12SJagpal Singh Gill     {
15*2a12ae12SJagpal Singh Gill         source = event_loop().add_io(fd, EPOLLIN, eventHandler, this);
16*2a12ae12SJagpal Singh Gill     }
17*2a12ae12SJagpal Singh Gill     catch (...)
18*2a12ae12SJagpal Singh Gill     {
19*2a12ae12SJagpal Singh Gill         throw std::runtime_error("Failed to add fd to event loop");
20*2a12ae12SJagpal Singh Gill     }
21*2a12ae12SJagpal Singh Gill }
22*2a12ae12SJagpal Singh Gill 
handleEvent()23*2a12ae12SJagpal Singh Gill void fdio::handleEvent() noexcept
24*2a12ae12SJagpal Singh Gill {
25*2a12ae12SJagpal Singh Gill     std::unique_lock l{lock};
26*2a12ae12SJagpal Singh Gill     if (complete == nullptr)
27*2a12ae12SJagpal Singh Gill     {
28*2a12ae12SJagpal Singh Gill         return;
29*2a12ae12SJagpal Singh Gill     }
30*2a12ae12SJagpal Singh Gill     auto c = std::exchange(complete, nullptr);
31*2a12ae12SJagpal Singh Gill     l.unlock();
32*2a12ae12SJagpal Singh Gill     c->complete();
33*2a12ae12SJagpal Singh Gill }
34*2a12ae12SJagpal Singh Gill 
35*2a12ae12SJagpal Singh Gill namespace fdio_ns
36*2a12ae12SJagpal Singh Gill {
37*2a12ae12SJagpal Singh Gill 
~fdio_completion()38*2a12ae12SJagpal Singh Gill fdio_completion::~fdio_completion()
39*2a12ae12SJagpal Singh Gill {
40*2a12ae12SJagpal Singh Gill     std::unique_lock l{fdioInstance.lock};
41*2a12ae12SJagpal Singh Gill 
42*2a12ae12SJagpal Singh Gill     if (fdioInstance.complete == this)
43*2a12ae12SJagpal Singh Gill     {
44*2a12ae12SJagpal Singh Gill         std::exchange(fdioInstance.complete, nullptr);
45*2a12ae12SJagpal Singh Gill     }
46*2a12ae12SJagpal Singh Gill }
47*2a12ae12SJagpal Singh Gill 
arm()48*2a12ae12SJagpal Singh Gill void fdio_completion::arm() noexcept
49*2a12ae12SJagpal Singh Gill {
50*2a12ae12SJagpal Singh Gill     // Set ourselves as the awaiting Receiver
51*2a12ae12SJagpal Singh Gill     std::unique_lock l{fdioInstance.lock};
52*2a12ae12SJagpal Singh Gill 
53*2a12ae12SJagpal Singh Gill     if (std::exchange(fdioInstance.complete, this) != nullptr)
54*2a12ae12SJagpal Singh Gill     {
55*2a12ae12SJagpal Singh Gill         // We do not support two awaiters; throw exception. Since we are in
56*2a12ae12SJagpal Singh Gill         // a noexcept context this will std::terminate anyhow, which is
57*2a12ae12SJagpal Singh Gill         // approximately the same as 'assert' but with better information.
58*2a12ae12SJagpal Singh Gill         try
59*2a12ae12SJagpal Singh Gill         {
60*2a12ae12SJagpal Singh Gill             throw std::logic_error(
61*2a12ae12SJagpal Singh Gill                 "fdio_completion started with another await already pending!");
62*2a12ae12SJagpal Singh Gill         }
63*2a12ae12SJagpal Singh Gill         catch (...)
64*2a12ae12SJagpal Singh Gill         {
65*2a12ae12SJagpal Singh Gill             std::terminate();
66*2a12ae12SJagpal Singh Gill         }
67*2a12ae12SJagpal Singh Gill     }
68*2a12ae12SJagpal Singh Gill }
69*2a12ae12SJagpal Singh Gill 
70*2a12ae12SJagpal Singh Gill } // namespace fdio_ns
71*2a12ae12SJagpal Singh Gill 
72*2a12ae12SJagpal Singh Gill } // namespace sdbusplus::async
73