add support for timed fdio
For certain operations such as reading and writing to a fd for request
response flows, the fd needs to have a timeout to avoid everlasting
hangs in case of a unresponsive responder. To support this, the fdio has
been extended to add timeout support by throwing an exception in case of
timeout.
Tested: Unit Test
```
1/1 test_async_fdio_timed OK 10.03s
Ok: 1
Expected Fail: 0
Fail: 0
Unexpected Pass: 0
Skipped: 0
Timeout: 0
```
Change-Id: Ib219e4a4c55125785e6c1571488e445ba3379244
Signed-off-by: Jagpal Singh Gill <paligill@gmail.com>
diff --git a/src/async/fdio.cpp b/src/async/fdio.cpp
index e1c3ddc..94c79d1 100644
--- a/src/async/fdio.cpp
+++ b/src/async/fdio.cpp
@@ -2,7 +2,9 @@
namespace sdbusplus::async
{
-fdio::fdio(context& ctx, int fd) : context_ref(ctx)
+fdio::fdio(context& ctx, int fd, std::chrono::microseconds timeout) :
+ context_ref(ctx),
+ timeout(std::chrono::duration_cast<event_t::time_resolution>(timeout))
{
static auto eventHandler =
[](sd_event_source*, int, uint32_t, void* data) noexcept {
@@ -32,6 +34,18 @@
c->complete();
}
+void fdio::handleTimeout() noexcept
+{
+ std::unique_lock l{lock};
+ if (complete == nullptr)
+ {
+ return;
+ }
+ auto c = std::exchange(complete, nullptr);
+ l.unlock();
+ c->error(std::make_exception_ptr(fdio_timeout_exception()));
+}
+
namespace fdio_ns
{
@@ -65,6 +79,28 @@
std::terminate();
}
}
+
+ l.unlock();
+
+ // Schedule the timeout
+ if (fdioInstance.timeout != event_t::time_resolution::zero())
+ {
+ static auto eventHandler =
+ [](sd_event_source*, uint64_t, void* data) noexcept {
+ static_cast<fdio*>(data)->handleTimeout();
+ return 0;
+ };
+
+ try
+ {
+ source = fdioInstance.event_loop().add_oneshot_timer(
+ eventHandler, &fdioInstance, fdioInstance.timeout);
+ }
+ catch (...)
+ {
+ error(std::current_exception());
+ }
+ }
}
} // namespace fdio_ns