io_uring: Add wait functions

This makes it possible to write trivial applications that aren't
necessarily using a full blown event loop.

Change-Id: If19cc9f0c21c029a5fda6a0d4f3eae8677841999
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/test/io_uring.cpp b/test/io_uring.cpp
index 6e9981d..6b8290e 100644
--- a/test/io_uring.cpp
+++ b/test/io_uring.cpp
@@ -1,5 +1,7 @@
 #include <poll.h>
 
+#include <array>
+#include <chrono>
 #include <stdplus/io_uring.hpp>
 
 #include <gmock/gmock.h>
@@ -10,6 +12,16 @@
 
 using testing::_;
 
+TEST(Convert, ChronoToKTS)
+{
+    const auto ns = 700;
+    const auto s = 5;
+    const auto kts =
+        chronoToKTS(std::chrono::nanoseconds(ns) + std::chrono::seconds(s));
+    EXPECT_EQ(kts.tv_sec, s);
+    EXPECT_EQ(kts.tv_nsec, ns);
+}
+
 class MockHandler : public IoUring::CQEHandler
 {
   public:
@@ -123,6 +135,17 @@
     ASSERT_EQ(0, poll(&pfd, 1, 100));
 }
 
+TEST_F(IoUringTest, Wait)
+{
+    auto& sqe = ring.getSQE();
+    auto kts = chronoToKTS(std::chrono::milliseconds(1));
+    io_uring_prep_timeout(&sqe, &kts, 0, 0);
+    ring.setHandler(sqe, &h[0]);
+    ring.submit();
+    ring.wait(std::chrono::seconds(1));
+    EXPECT_CALL(h[0], handleCQE(_));
+}
+
 TEST_F(IoUringTest, HandleCalledOnDestroy)
 {
     auto& sqe = ring.getSQE();