summaryrefslogtreecommitdiffstats
path: root/src/rgw/rgw_asio_frontend_timer.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/rgw/rgw_asio_frontend_timer.h')
-rw-r--r--src/rgw/rgw_asio_frontend_timer.h65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/rgw/rgw_asio_frontend_timer.h b/src/rgw/rgw_asio_frontend_timer.h
new file mode 100644
index 000000000..b7d6a63b4
--- /dev/null
+++ b/src/rgw/rgw_asio_frontend_timer.h
@@ -0,0 +1,65 @@
+#pragma once
+
+#include <boost/asio/basic_waitable_timer.hpp>
+#include <boost/intrusive_ptr.hpp>
+
+#include "common/ceph_time.h"
+
+namespace rgw {
+
+// a WaitHandler that closes a stream if the timeout expires
+template <typename Stream>
+struct timeout_handler {
+ // this handler may outlive the timer/stream, so we need to hold a reference
+ // to keep the stream alive
+ boost::intrusive_ptr<Stream> stream;
+
+ explicit timeout_handler(boost::intrusive_ptr<Stream> stream) noexcept
+ : stream(std::move(stream)) {}
+
+ void operator()(boost::system::error_code ec) {
+ if (!ec) { // wait was not canceled
+ boost::system::error_code ec_ignored;
+ stream->close(ec_ignored);
+ }
+ }
+};
+
+// a timeout timer for stream operations
+template <typename Clock, typename Executor, typename Stream>
+class basic_timeout_timer {
+ public:
+ using clock_type = Clock;
+ using duration = typename clock_type::duration;
+ using executor_type = Executor;
+
+ explicit basic_timeout_timer(const executor_type& ex, duration dur,
+ boost::intrusive_ptr<Stream> stream)
+ : timer(ex), dur(dur), stream(std::move(stream))
+ {}
+
+ basic_timeout_timer(const basic_timeout_timer&) = delete;
+ basic_timeout_timer& operator=(const basic_timeout_timer&) = delete;
+
+ void start() {
+ if (dur.count() > 0) {
+ timer.expires_after(dur);
+ timer.async_wait(timeout_handler{stream});
+ }
+ }
+
+ void cancel() {
+ if (dur.count() > 0) {
+ timer.cancel();
+ }
+ }
+
+ private:
+ using Timer = boost::asio::basic_waitable_timer<clock_type,
+ boost::asio::wait_traits<clock_type>, executor_type>;
+ Timer timer;
+ duration dur;
+ boost::intrusive_ptr<Stream> stream;
+};
+
+} // namespace rgw