cppnet
C++ network utilities for asynchronous servers.
Loading...
Searching...
No Matches
timers.hpp
1// Copyright 2025 Kevin Exton
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14#pragma once
15#ifndef CPPNET_TIMERS_HPP
16#define CPPNET_TIMERS_HPP
17#include "interrupt.hpp"
18#include "net/detail/concepts.hpp"
19
20#include <chrono>
21#include <functional>
22#include <queue>
23#include <stack>
24namespace net::timers {
25
27using timer_id = std::size_t;
29static constexpr timer_id INVALID_TIMER = -1;
31using handler_t = std::function<void(timer_id)>;
33using clock = std::chrono::steady_clock;
35using timestamp = std::chrono::time_point<clock>;
37using duration = std::chrono::microseconds;
38
40namespace detail {
42struct event {
46 timer_id id = INVALID_TIMER;
52 std::atomic_flag armed;
53};
54
56struct event_ref {
60 timer_id id = INVALID_TIMER;
61};
62
70inline auto operator<=>(const event_ref &lhs,
71 const event_ref &rhs) -> std::strong_ordering;
79inline auto operator==(const event_ref &lhs, const event_ref &rhs) -> bool;
80} // namespace detail.
81
98template <InterruptSource Interrupt>
99class timers : public interrupt<Interrupt> {
100public:
103
105 timers() = default;
107 timers(const timers &other) = delete;
109 timers(timers &&other) noexcept;
110
112 auto operator=(const timers &other) = delete;
114 auto operator=(timers &&other) noexcept -> timers &;
115
117 template <InterruptSource I>
118 friend auto swap(timers<I> &lhs, timers<I> &rhs) noexcept -> void;
119
128 auto add(timestamp when, handler_t handler,
129 duration period = duration::zero()) -> timer_id;
130
141 template <class Rep, class Period>
142 auto add(std::chrono::duration<Rep, Period> when, handler_t handler,
143 duration period = duration::zero()) -> timer_id;
144
154 auto add(std::uint64_t when, handler_t handler,
155 std::uint64_t period = 0) -> timer_id;
156
171 auto remove(timer_id tid) noexcept -> timer_id;
172
178 auto resolve() -> duration;
179
181 ~timers() = default;
182
183private:
185 template <typename T>
186 using minheap = std::priority_queue<T, std::vector<T>, std::greater<>>;
187
189 struct {
191 std::deque<detail::event> events;
193 minheap<detail::event_ref> eventq;
195 std::stack<timer_id> free_ids;
196 } state_;
197
199 mutable std::mutex mtx_;
200};
201
202} // namespace net::timers
203
204#include "impl/timers_impl.hpp" // IWYU pragma: export
205
206#endif // CPPNET_TIMERS_HPP
Provides event-loop timers.
Definition timers.hpp:99
auto add(timestamp when, handler_t handler, duration period=duration::zero()) -> timer_id
Add a new timer.
friend auto swap(timers< I > &lhs, timers< I > &rhs) noexcept -> void
Swap function.
auto resolve() -> duration
Resolves all expired event handles.
auto operator=(const timers &other)=delete
Deleted copy assignment.
~timers()=default
Default destructor.
minheap< detail::event_ref > eventq
The minheap that stores timeouts.
Definition timers.hpp:193
auto add(std::uint64_t when, handler_t handler, std::uint64_t period=0) -> timer_id
Overloaded add function that uses a uint64_t instead of a time_point for the first timeout and the pe...
std::stack< timer_id > free_ids
A pool of recyclable timer_ids.
Definition timers.hpp:195
timers(timers &&other) noexcept
Move constructor.
auto add(std::chrono::duration< Rep, Period > when, handler_t handler, duration period=duration::zero()) -> timer_id
Overloaded add function that uses a std::chrono::duration instead of a time_point for the first timeo...
auto remove(timer_id tid) noexcept -> timer_id
Removes the timer with the given id.
timers(const timers &other)=delete
Deleted copy constructor.
std::deque< detail::event > events
The vector that holds all active events.
Definition timers.hpp:191
auto operator=(timers &&other) noexcept -> timers &
Move assignment.
timers()=default
Default constructor.
This file declares interrupt related types..
auto operator==(const event_ref &lhs, const event_ref &rhs) -> bool
An equality operator to determine event_ref ordering.
auto operator<=>(const event_ref &lhs, const event_ref &rhs) -> std::strong_ordering
The spaceship operator to determine event_ref ordering.
This namespace is for timers and interrupts.
Definition interrupt.hpp:25
std::chrono::microseconds duration
duration type.
Definition timers.hpp:37
std::size_t timer_id
timer_id type.
Definition timers.hpp:27
std::function< void(timer_id)> handler_t
handler type.
Definition timers.hpp:31
std::chrono::time_point< clock > timestamp
time type.
Definition timers.hpp:35
std::chrono::steady_clock clock
clock type.
Definition timers.hpp:33
event_ref to be inserted into the priority queue.
Definition timers.hpp:56
timestamp expires_at
The timer expiry time.
Definition timers.hpp:58
The event structure.
Definition timers.hpp:42
duration period
The timer period.
Definition timers.hpp:50
timestamp start
The first time the event fired.
Definition timers.hpp:48
std::atomic_flag armed
A flag to determine if the timer is armed.
Definition timers.hpp:52
handler_t handler
An event handler.
Definition timers.hpp:44
An interrupt is an immediately run timer event.
Definition interrupt.hpp:48