#pragma once #include "logging.h" #include #include #include #include namespace crow { namespace detail { constexpr const size_t timerQueueTimeoutSeconds = 5; 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 add(std::function 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 currenty; call // here x.second(); } dq.pop_front(); step++; } } private: using storage_type = std::pair, std::function>; boost::circular_buffer_space_optimized> dq{}; // boost::circular_buffer dq{20}; // std::deque dq{}; size_t step{}; }; } // namespace detail } // namespace crow