blob: 26eea138adc9b39c4aec5d3f4191f61c5e9fa37c [file] [log] [blame]
#pragma once
#include <boost/circular_buffer.hpp>
#include <boost/circular_buffer/space_optimized.hpp>
#include <chrono>
#include <functional>
#include "logging.h"
namespace crow
{
namespace detail
{
// fast timer queue for fixed tick value.
class TimerQueue
{
public:
TimerQueue()
{
dq.set_capacity(100);
}
void cancel(size_t k)
{
size_t index = k - step;
if (index < dq.size())
{
dq[index].second = nullptr;
}
}
size_t add(std::function<void()> f)
{
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();
if (now - x.first < std::chrono::seconds(5))
{
break;
}
if (x.second)
{
BMCWEB_LOG_DEBUG << "timer call: " << this << ' ' << step;
// we know that timer handlers are very simple currenty; 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