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