]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_asio_frontend_timer.h
b7d6a63b46f114fb5debdd042138ef5be1b646fe
[ceph.git] / ceph / src / rgw / rgw_asio_frontend_timer.h
1 #pragma once
2
3 #include <boost/asio/basic_waitable_timer.hpp>
4 #include <boost/intrusive_ptr.hpp>
5
6 #include "common/ceph_time.h"
7
8 namespace rgw {
9
10 // a WaitHandler that closes a stream if the timeout expires
11 template <typename Stream>
12 struct timeout_handler {
13 // this handler may outlive the timer/stream, so we need to hold a reference
14 // to keep the stream alive
15 boost::intrusive_ptr<Stream> stream;
16
17 explicit timeout_handler(boost::intrusive_ptr<Stream> stream) noexcept
18 : stream(std::move(stream)) {}
19
20 void operator()(boost::system::error_code ec) {
21 if (!ec) { // wait was not canceled
22 boost::system::error_code ec_ignored;
23 stream->close(ec_ignored);
24 }
25 }
26 };
27
28 // a timeout timer for stream operations
29 template <typename Clock, typename Executor, typename Stream>
30 class basic_timeout_timer {
31 public:
32 using clock_type = Clock;
33 using duration = typename clock_type::duration;
34 using executor_type = Executor;
35
36 explicit basic_timeout_timer(const executor_type& ex, duration dur,
37 boost::intrusive_ptr<Stream> stream)
38 : timer(ex), dur(dur), stream(std::move(stream))
39 {}
40
41 basic_timeout_timer(const basic_timeout_timer&) = delete;
42 basic_timeout_timer& operator=(const basic_timeout_timer&) = delete;
43
44 void start() {
45 if (dur.count() > 0) {
46 timer.expires_after(dur);
47 timer.async_wait(timeout_handler{stream});
48 }
49 }
50
51 void cancel() {
52 if (dur.count() > 0) {
53 timer.cancel();
54 }
55 }
56
57 private:
58 using Timer = boost::asio::basic_waitable_timer<clock_type,
59 boost::asio::wait_traits<clock_type>, executor_type>;
60 Timer timer;
61 duration dur;
62 boost::intrusive_ptr<Stream> stream;
63 };
64
65 } // namespace rgw