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

100.0% Lines (6 / 6) 100.0% Branches (1 / 1) 100.0% Functions (3 / 3)
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 420x explicit win_timers(long* dispatch_required) noexcept
39 420x : dispatch_required_(dispatch_required)
40 {
41 420x }
42
43 420x virtual ~win_timers() = default;
44
45 /// Start delivering wakeups; return false, keeping nothing, if
46 /// the resources for them cannot be created.
47 virtual bool start() = 0;
48 virtual void stop() = 0;
49 virtual void update_timeout(time_point next_expiry) = 0;
50 };
51
52 std::unique_ptr<win_timers>
53 make_win_timers(void* iocp_handle, long* dispatch_required);
54
55 } // namespace boost::corosio::detail
56
57 // Include concrete implementations needed by make_win_timers
58 #include <boost/corosio/native/detail/iocp/win_timers_thread.hpp>
59
60 namespace boost::corosio::detail {
61
62 inline std::unique_ptr<win_timers>
63 420x make_win_timers(void* iocp_handle, long* dispatch_required)
64 {
65 // Thread-based over NtAssociateWaitCompletionPacket: the NT wait
66 // packet is one-shot, so it must be re-associated (SetWaitableTimer
67 // + NtAssociateWaitCompletionPacket) after every scheduler wakeup
68 // even in timer-free workloads, costing ~60% CPU overhead. Skipping
69 // the re-association is not a fix: a spent packet never fires again
70 // and pending timers hang the scheduler.
71
1/1
✓ Branch 2 → 3 taken 420 times.
420x return std::make_unique<win_timers_thread>(iocp_handle, dispatch_required);
72 }
73
74 } // namespace boost::corosio::detail
75
76 #endif // BOOST_COROSIO_HAS_IOCP
77
78 #endif // BOOST_COROSIO_NATIVE_DETAIL_IOCP_WIN_TIMERS_HPP
79