summaryrefslogtreecommitdiff
path: root/http/timer_queue.hpp
diff options
context:
space:
mode:
authorEd Tanous <ed@tanous.net>2020-10-03 18:06:26 +0300
committerEd Tanous <ed@tanous.net>2020-10-23 18:03:17 +0300
commit04e438cbad66838724d78ce12f28aff1fb892a63 (patch)
tree8d8c42a8b3d3e9f8e10c108dd6273e8185d04530 /http/timer_queue.hpp
parentdc511aa73001a593a16dbcdaa5d53f320e4c7818 (diff)
downloadbmcweb-04e438cbad66838724d78ce12f28aff1fb892a63.tar.xz
fix include names
cppcheck isn't smart enough to recognize these are c++ headers, not c headers. Considering we're already inconsistent about our naming, it's easier to just be consistent, and move the last few files to use .hpp instead of .h. Tested: Code builds, no changes. Signed-off-by: Ed Tanous <ed@tanous.net> Change-Id: Ic348d695f8527fa4a0ded53f433e1558c319db40
Diffstat (limited to 'http/timer_queue.hpp')
-rw-r--r--http/timer_queue.hpp92
1 files changed, 92 insertions, 0 deletions
diff --git a/http/timer_queue.hpp b/http/timer_queue.hpp
new file mode 100644
index 0000000000..5baf7beecb
--- /dev/null
+++ b/http/timer_queue.hpp
@@ -0,0 +1,92 @@
+#pragma once
+
+#include "logging.hpp"
+
+#include <boost/circular_buffer.hpp>
+#include <boost/circular_buffer/space_optimized.hpp>
+
+#include <chrono>
+#include <functional>
+
+namespace crow
+{
+
+constexpr const size_t timerQueueTimeoutSeconds = 5;
+namespace detail
+{
+
+constexpr const size_t maxSize = 100;
+// fast timer queue for fixed tick value.
+class TimerQueue
+{
+ public:
+ TimerQueue()
+ {
+ dq.set_capacity(maxSize);
+ }
+
+ void cancel(size_t k)
+ {
+ size_t index = k - step;
+ if (index < dq.size())
+ {
+ dq[index].second = nullptr;
+ }
+ }
+
+ std::optional<size_t> add(std::function<void()> f)
+ {
+ if (dq.size() == maxSize)
+ {
+ return std::nullopt;
+ }
+
+ dq.push_back(
+ std::make_pair(std::chrono::steady_clock::now(), std::move(f)));
+ size_t ret = step + dq.size() - 1;
+
+ BMCWEB_LOG_DEBUG << "timer add inside: " << this << ' ' << ret;
+ return ret;
+ }
+
+ void process()
+ {
+ auto now = std::chrono::steady_clock::now();
+ while (!dq.empty())
+ {
+ auto& x = dq.front();
+ // Check expiration time only for active handlers,
+ // remove canceled ones immediately
+ if (x.second)
+ {
+ if (now - x.first <
+ std::chrono::seconds(timerQueueTimeoutSeconds))
+ {
+ break;
+ }
+
+ BMCWEB_LOG_DEBUG << "timer call: " << this << ' ' << step;
+ // we know that timer handlers are very simple currently; call
+ // here
+ x.second();
+ }
+ dq.pop_front();
+ step++;
+ }
+ }
+
+ private:
+ using storage_type =
+ std::pair<std::chrono::time_point<std::chrono::steady_clock>,
+ std::function<void()>>;
+
+ boost::circular_buffer_space_optimized<storage_type,
+ std::allocator<storage_type>>
+ dq{};
+
+ // boost::circular_buffer<storage_type> dq{20};
+ // std::deque<storage_type> dq{};
+ size_t step{};
+};
+} // namespace detail
+} // namespace crow