include/boost/corosio/native/detail/iocp/win_timers.hpp

100.0% Lines (6/6) 100.0% List of functions (3/3) 100.0% Branches (1/1)
win_timers.hpp
f(x) Functions (3)
Line Branch TLA Hits Source Code
1 //
2 // Copyright (c) 2025 Vinnie Falco ([email protected])
3 // Copyright (c) 2026 Steve Gerbino
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/cppalliance/corosio
9 //
10
11 #ifndef BOOST_COROSIO_NATIVE_DETAIL_IOCP_WIN_TIMERS_HPP
12 #define BOOST_COROSIO_NATIVE_DETAIL_IOCP_WIN_TIMERS_HPP
13
14 #include <boost/corosio/detail/platform.hpp>
15
16 #if BOOST_COROSIO_HAS_IOCP
17
18 #include <boost/corosio/native/detail/iocp/win_completion_key.hpp>
19 #include <boost/corosio/native/detail/iocp/win_windows.hpp>
20
21 #include <chrono>
22 #include <memory>
23
24 namespace boost::corosio::detail {
25
26 /** Abstract interface for timer wakeup mechanisms.
27
28 Posts key_wake_dispatch to the IOCP to trigger timer processing.
29 */
30 class win_timers
31 {
32 protected:
33 long* dispatch_required_;
34
35 public:
36 using time_point = std::chrono::steady_clock::time_point;
37
38 1121x explicit win_timers(long* dispatch_required) noexcept
39 1121x : dispatch_required_(dispatch_required)
40 {
41 1121x }
42
43 1121x virtual ~win_timers() = default;
44
45 virtual void start() = 0;
46 virtual void stop() = 0;
47 virtual void update_timeout(time_point next_expiry) = 0;
48 };
49
50 std::unique_ptr<win_timers>
51 make_win_timers(void* iocp_handle, long* dispatch_required);
52
53 } // namespace boost::corosio::detail
54
55 // Include concrete implementations needed by make_win_timers
56 #include <boost/corosio/native/detail/iocp/win_timers_thread.hpp>
57
58 namespace boost::corosio::detail {
59
60 inline std::unique_ptr<win_timers>
61 1121x make_win_timers(void* iocp_handle, long* dispatch_required)
62 {
63 // Thread-based over NtAssociateWaitCompletionPacket: the NT wait
64 // packet is one-shot, so it must be re-associated (SetWaitableTimer
65 // + NtAssociateWaitCompletionPacket) after every scheduler wakeup
66 // even in timer-free workloads, costing ~60% CPU overhead. Skipping
67 // the re-association is not a fix: a spent packet never fires again
68 // and pending timers hang the scheduler.
69
1/1
✓ Branch 2 → 3 taken 1121 times.
1121x return std::make_unique<win_timers_thread>(iocp_handle, dispatch_required);
70 }
71
72 } // namespace boost::corosio::detail
73
74 #endif // BOOST_COROSIO_HAS_IOCP
75
76 #endif // BOOST_COROSIO_NATIVE_DETAIL_IOCP_WIN_TIMERS_HPP
77