xref: /openbmc/sdbusplus/src/async/fdio.cpp (revision 869230c608eaa7d3a4c401ce028661040830d567)
12a12ae12SJagpal Singh Gill #include <sdbusplus/async/fdio.hpp>
22a12ae12SJagpal Singh Gill 
32a12ae12SJagpal Singh Gill namespace sdbusplus::async
42a12ae12SJagpal Singh Gill {
fdio(context & ctx,int fd)5*869230c6SPatrick Williams fdio::fdio(context& ctx, int fd) : context_ref(ctx)
62a12ae12SJagpal Singh Gill {
72a12ae12SJagpal Singh Gill     static auto eventHandler =
82a12ae12SJagpal Singh Gill         [](sd_event_source*, int, uint32_t, void* data) noexcept {
92a12ae12SJagpal Singh Gill             static_cast<fdio*>(data)->handleEvent();
102a12ae12SJagpal Singh Gill             return 0;
112a12ae12SJagpal Singh Gill         };
122a12ae12SJagpal Singh Gill 
132a12ae12SJagpal Singh Gill     try
142a12ae12SJagpal Singh Gill     {
152a12ae12SJagpal Singh Gill         source = event_loop().add_io(fd, EPOLLIN, eventHandler, this);
162a12ae12SJagpal Singh Gill     }
172a12ae12SJagpal Singh Gill     catch (...)
182a12ae12SJagpal Singh Gill     {
192a12ae12SJagpal Singh Gill         throw std::runtime_error("Failed to add fd to event loop");
202a12ae12SJagpal Singh Gill     }
212a12ae12SJagpal Singh Gill }
222a12ae12SJagpal Singh Gill 
handleEvent()232a12ae12SJagpal Singh Gill void fdio::handleEvent() noexcept
242a12ae12SJagpal Singh Gill {
252a12ae12SJagpal Singh Gill     std::unique_lock l{lock};
262a12ae12SJagpal Singh Gill     if (complete == nullptr)
272a12ae12SJagpal Singh Gill     {
282a12ae12SJagpal Singh Gill         return;
292a12ae12SJagpal Singh Gill     }
302a12ae12SJagpal Singh Gill     auto c = std::exchange(complete, nullptr);
312a12ae12SJagpal Singh Gill     l.unlock();
322a12ae12SJagpal Singh Gill     c->complete();
332a12ae12SJagpal Singh Gill }
342a12ae12SJagpal Singh Gill 
352a12ae12SJagpal Singh Gill namespace fdio_ns
362a12ae12SJagpal Singh Gill {
372a12ae12SJagpal Singh Gill 
~fdio_completion()382a12ae12SJagpal Singh Gill fdio_completion::~fdio_completion()
392a12ae12SJagpal Singh Gill {
402a12ae12SJagpal Singh Gill     std::unique_lock l{fdioInstance.lock};
412a12ae12SJagpal Singh Gill 
422a12ae12SJagpal Singh Gill     if (fdioInstance.complete == this)
432a12ae12SJagpal Singh Gill     {
442a12ae12SJagpal Singh Gill         std::exchange(fdioInstance.complete, nullptr);
452a12ae12SJagpal Singh Gill     }
462a12ae12SJagpal Singh Gill }
472a12ae12SJagpal Singh Gill 
arm()482a12ae12SJagpal Singh Gill void fdio_completion::arm() noexcept
492a12ae12SJagpal Singh Gill {
502a12ae12SJagpal Singh Gill     // Set ourselves as the awaiting Receiver
512a12ae12SJagpal Singh Gill     std::unique_lock l{fdioInstance.lock};
522a12ae12SJagpal Singh Gill 
532a12ae12SJagpal Singh Gill     if (std::exchange(fdioInstance.complete, this) != nullptr)
542a12ae12SJagpal Singh Gill     {
552a12ae12SJagpal Singh Gill         // We do not support two awaiters; throw exception. Since we are in
562a12ae12SJagpal Singh Gill         // a noexcept context this will std::terminate anyhow, which is
572a12ae12SJagpal Singh Gill         // approximately the same as 'assert' but with better information.
582a12ae12SJagpal Singh Gill         try
592a12ae12SJagpal Singh Gill         {
602a12ae12SJagpal Singh Gill             throw std::logic_error(
612a12ae12SJagpal Singh Gill                 "fdio_completion started with another await already pending!");
622a12ae12SJagpal Singh Gill         }
632a12ae12SJagpal Singh Gill         catch (...)
642a12ae12SJagpal Singh Gill         {
652a12ae12SJagpal Singh Gill             std::terminate();
662a12ae12SJagpal Singh Gill         }
672a12ae12SJagpal Singh Gill     }
682a12ae12SJagpal Singh Gill }
692a12ae12SJagpal Singh Gill 
702a12ae12SJagpal Singh Gill } // namespace fdio_ns
712a12ae12SJagpal Singh Gill 
722a12ae12SJagpal Singh Gill } // namespace sdbusplus::async
73