blob: 26eea138adc9b39c4aec5d3f4191f61c5e9fa37c [file] [log] [blame]
Ed Tanouse0d918b2018-03-27 17:41:04 -07001#pragma once
2
Ed Tanouse0d918b2018-03-27 17:41:04 -07003#include <boost/circular_buffer.hpp>
4#include <boost/circular_buffer/space_optimized.hpp>
Ed Tanous1abe55e2018-09-05 08:30:59 -07005#include <chrono>
6#include <functional>
Ed Tanouse0d918b2018-03-27 17:41:04 -07007
Ed Tanousc94ad492019-10-10 15:39:33 -07008#include "logging.h"
Ed Tanous1abe55e2018-09-05 08:30:59 -07009
10namespace crow
11{
12namespace detail
13{
Ed Tanouse0d918b2018-03-27 17:41:04 -070014// fast timer queue for fixed tick value.
Ed Tanous1abe55e2018-09-05 08:30:59 -070015class TimerQueue
16{
17 public:
18 TimerQueue()
19 {
20 dq.set_capacity(100);
Ed Tanouse0d918b2018-03-27 17:41:04 -070021 }
Ed Tanouse0d918b2018-03-27 17:41:04 -070022
Ed Tanous271584a2019-07-09 16:24:22 -070023 void cancel(size_t k)
Ed Tanous1abe55e2018-09-05 08:30:59 -070024 {
Ed Tanous271584a2019-07-09 16:24:22 -070025 size_t index = k - step;
Ed Tanousb01bf292019-03-25 19:25:26 +000026 if (index < dq.size())
Ed Tanous1abe55e2018-09-05 08:30:59 -070027 {
Ed Tanousb01bf292019-03-25 19:25:26 +000028 dq[index].second = nullptr;
Ed Tanous1abe55e2018-09-05 08:30:59 -070029 }
Ed Tanouse0d918b2018-03-27 17:41:04 -070030 }
Ed Tanouse0d918b2018-03-27 17:41:04 -070031
Ed Tanous271584a2019-07-09 16:24:22 -070032 size_t add(std::function<void()> f)
Ed Tanous1abe55e2018-09-05 08:30:59 -070033 {
34 dq.push_back(
35 std::make_pair(std::chrono::steady_clock::now(), std::move(f)));
Ed Tanous271584a2019-07-09 16:24:22 -070036 size_t ret = step + dq.size() - 1;
Ed Tanouse0d918b2018-03-27 17:41:04 -070037
Ed Tanous1abe55e2018-09-05 08:30:59 -070038 BMCWEB_LOG_DEBUG << "timer add inside: " << this << ' ' << ret;
39 return ret;
40 }
Ed Tanouse0d918b2018-03-27 17:41:04 -070041
Ed Tanous1abe55e2018-09-05 08:30:59 -070042 void process()
43 {
44 auto now = std::chrono::steady_clock::now();
45 while (!dq.empty())
46 {
47 auto& x = dq.front();
48 if (now - x.first < std::chrono::seconds(5))
49 {
50 break;
51 }
52 if (x.second)
53 {
54 BMCWEB_LOG_DEBUG << "timer call: " << this << ' ' << step;
55 // we know that timer handlers are very simple currenty; call
56 // here
57 x.second();
58 }
59 dq.pop_front();
60 step++;
61 }
62 }
63
64 private:
65 using storage_type =
66 std::pair<std::chrono::time_point<std::chrono::steady_clock>,
67 std::function<void()>>;
68
69 boost::circular_buffer_space_optimized<storage_type,
70 std::allocator<storage_type>>
71 dq{};
72
73 // boost::circular_buffer<storage_type> dq{20};
74 // std::deque<storage_type> dq{};
Ed Tanous271584a2019-07-09 16:24:22 -070075 size_t step{};
Ed Tanouse0d918b2018-03-27 17:41:04 -070076};
Ed Tanous1abe55e2018-09-05 08:30:59 -070077} // namespace detail
78} // namespace crow