include/boost/corosio/native/native_win_object_handle.hpp

100.0% Lines (14/14) 100.0% List of functions (5/5) 100.0% Branches (3/3)
native_win_object_handle.hpp
f(x) Functions (5)
Line Branch TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Michael Vandeberg
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/cppalliance/corosio
8 //
9
10 #ifndef BOOST_COROSIO_NATIVE_NATIVE_WIN_OBJECT_HANDLE_HPP
11 #define BOOST_COROSIO_NATIVE_NATIVE_WIN_OBJECT_HANDLE_HPP
12
13 #include <boost/corosio/detail/op_base.hpp>
14 #include <boost/corosio/win_object_handle.hpp>
15 #include <boost/corosio/backend.hpp>
16
17 #if BOOST_COROSIO_HAS_IOCP || defined(BOOST_COROSIO_MRDOCS)
18
19 #ifndef BOOST_COROSIO_MRDOCS
20 #include <boost/corosio/native/detail/iocp/win_object_handle_service.hpp>
21 #endif
22
23 namespace boost::corosio {
24
25 /** Waits on an already-open Windows kernel object, calling the backend directly.
26
27 This class template inherits from @ref win_object_handle and
28 shadows the async operation (`wait`) with a version that calls
29 the backend implementation directly. This lets the compiler
30 inline through the entire call chain.
31
32 Non-async operations (`assign`, `release`, `close`, `cancel`)
33 remain unchanged and dispatch through the compiled library.
34
35 A `native_win_object_handle` IS-A `win_object_handle` and can be
36 passed to any function expecting `win_object_handle&`, in which
37 case virtual dispatch is used transparently.
38
39 @tparam Backend A backend tag value (e.g., `iocp`) whose type
40 provides the concrete implementation types.
41
42 @par Thread Safety
43 Same as @ref win_object_handle.
44
45 @see win_object_handle, iocp_t
46 */
47 template<auto Backend>
48 class native_win_object_handle : public win_object_handle
49 {
50 using backend_type = decltype(Backend);
51 using impl_type = typename backend_type::object_handle_type;
52 using service_type = typename backend_type::object_handle_service_type;
53
54 1x impl_type& get_impl() noexcept
55 {
56 1x return *static_cast<impl_type*>(h_.get());
57 }
58
59 struct native_wait_awaitable : detail::void_op_base<native_wait_awaitable>
60 {
61 native_win_object_handle& self_;
62 mutable capy::continuation cont_;
63
64 1x explicit native_wait_awaitable(native_win_object_handle& self) noexcept
65 1x : self_(self)
66 {
67 1x }
68
69 std::coroutine_handle<>
70 1x dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
71 {
72 1x cont_.h = h;
73 2x return self_.get_impl().wait(
74
1/1
✓ Branch 4 → 5 taken 1 time.
2x cont_, ex, this->token_, &this->ec_);
75 }
76 };
77
78 public:
79 /** Construct a `native_win_object_handle` from an execution context.
80
81 @param ctx The execution context that owns this object.
82 */
83 1x explicit native_win_object_handle(capy::execution_context& ctx)
84
2/2
✓ Branch 2 → 3 taken 1 time.
✓ Branch 3 → 4 taken 1 time.
1x : win_object_handle(handle(ctx, ctx.use_service<service_type>()))
85 {
86 1x }
87
88 /** Construct a `native_win_object_handle` from an executor.
89
90 The overload excludes `native_win_object_handle` itself so
91 that it cannot displace the move constructor.
92
93 @tparam Ex A type satisfying `capy::Executor`.
94 @param ex The executor whose context owns this object.
95 */
96 template<class Ex>
97 requires(!std::same_as<
98 std::remove_cvref_t<Ex>,
99 native_win_object_handle>) &&
100 capy::Executor<Ex>
101 explicit native_win_object_handle(Ex const& ex)
102 : native_win_object_handle(ex.context())
103 {
104 }
105
106 /** Transfer ownership of the handle from the source.
107
108 After the move, the source is in a moved-from state and may
109 only be destroyed or assigned to.
110
111 @pre No awaitables returned by the source's methods exist.
112 */
113 native_win_object_handle(native_win_object_handle&&) noexcept = default;
114
115 /** Close any held handle and transfer ownership from the source.
116
117 After the move, the source is in a moved-from state and may
118 only be destroyed or assigned to.
119
120 @return `*this`.
121 @pre No awaitables returned by either object's methods exist.
122 */
123 native_win_object_handle&
124 operator=(native_win_object_handle&&) noexcept = default;
125
126 /// Copy construction is disabled; the handle is uniquely owned.
127 native_win_object_handle(native_win_object_handle const&) = delete;
128 /// Copy assignment is disabled; the handle is uniquely owned.
129 native_win_object_handle&
130 operator=(native_win_object_handle const&) = delete;
131
132 /** Wait for the object to become signaled.
133
134 Calls the backend implementation directly, bypassing virtual
135 dispatch. Otherwise identical to @ref win_object_handle::wait.
136
137 @return An awaitable yielding `io_result<>`.
138 */
139 1x [[nodiscard]] auto wait()
140 {
141 1x return native_wait_awaitable(*this);
142 }
143 };
144
145 } // namespace boost::corosio
146
147 #endif // BOOST_COROSIO_HAS_IOCP || BOOST_COROSIO_MRDOCS
148
149 #endif // BOOST_COROSIO_NATIVE_NATIVE_WIN_OBJECT_HANDLE_HPP
150