include/boost/corosio/io/io_object.hpp

100.0% Lines (67/67) 100.0% List of functions (46/47) 42.0% Branches (21/50)
io_object.hpp
f(x) Functions (47)
Function Calls Lines Branches Blocks
boost::corosio::io_object::implementation::implementation() :53 24597x 100.0% 100.0% boost::corosio::io_object::implementation::~implementation() :55 24597x 100.0% 100.0% boost::corosio::io_object::io_service::io_service() :64 25201x 100.0% 100.0% boost::corosio::io_object::io_service::~io_service() :66 25201x 100.0% 100.0% boost::corosio::io_object::io_service::close(boost::corosio::io_object::handle&) :75 11522x 100.0% 100.0% <unknown function 85> :85 boost::corosio::io_object::handle::~handle() :91 116875x 100.0% 100.0% 100.0% boost::corosio::io_object::handle::handle() :101 20x 100.0% 100.0% boost::corosio::io_object::handle::handle(boost::capy::execution_context&, boost::corosio::io_object::io_service&) :104 55384x 100.0% 100.0% boost::corosio::io_object::handle::handle(boost::corosio::io_object::handle&&) :112 61512x 100.0% 100.0% boost::corosio::io_object::handle::operator=(boost::corosio::io_object::handle&&) :120 357x 100.0% 62.5% 87.0% boost::corosio::io_object::handle::operator bool() const :140 68715x 100.0% 100.0% boost::corosio::io_object::handle::service() const :146 28039x 100.0% 100.0% boost::corosio::io_object::handle::get() const :152 1132079x 100.0% 100.0% boost::corosio::io_object::handle::reset(boost::corosio::io_object::implementation*) :161 6370x 100.0% 50.0% 83.0% boost::corosio::io_object::handle::context() const :172 39x 100.0% 100.0% boost::corosio::io_object::context() const :179 39x 100.0% 100.0% boost::corosio::io_object::~io_object() :185 30425x 100.0% 100.0% boost::corosio::io_object::io_object() :188 10x 100.0% 100.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::file_service>(boost::capy::execution_context&) :200 109x 80.0% 50.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::kqueue_local_datagram_service>(boost::capy::execution_context&) :200 15x 100.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::kqueue_local_stream_acceptor_service>(boost::capy::execution_context&) :200 9x 100.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::kqueue_local_stream_service>(boost::capy::execution_context&) :200 20x 100.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::kqueue_tcp_acceptor_service>(boost::capy::execution_context&) :200 19x 80.0% 50.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::kqueue_tcp_service>(boost::capy::execution_context&) :200 29x 100.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::kqueue_udp_service>(boost::capy::execution_context&) :200 21x 100.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::local_datagram_service>(boost::capy::execution_context&) :200 214x 80.0% 50.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::local_stream_acceptor_service>(boost::capy::execution_context&) :200 86x 80.0% 50.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::local_stream_service>(boost::capy::execution_context&) :200 246x 80.0% 50.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::posix_random_access_file_service>(boost::capy::execution_context&) :200 16x 80.0% 50.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::posix_resolver_service>(boost::capy::execution_context&) :200 57x 80.0% 50.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::posix_signal_service>(boost::capy::execution_context&) :200 178x 80.0% 50.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::posix_stream_file_service>(boost::capy::execution_context&) :200 16x 0.0% 0.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::random_access_file_service>(boost::capy::execution_context&) :200 94x 80.0% 50.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::select_local_datagram_service>(boost::capy::execution_context&) :200 15x 80.0% 17.9% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::select_local_stream_acceptor_service>(boost::capy::execution_context&) :200 9x 80.0% 50.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::select_local_stream_service>(boost::capy::execution_context&) :200 20x 100.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::select_tcp_acceptor_service>(boost::capy::execution_context&) :200 18x 0.0% 0.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::select_tcp_service>(boost::capy::execution_context&) :200 26x 80.0% 50.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::select_udp_service>(boost::capy::execution_context&) :200 21x 0.0% 0.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::tcp_acceptor_service>(boost::capy::execution_context&) :200 1604x 80.0% 50.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::tcp_service>(boost::capy::execution_context&) :200 13283x 80.0% 50.0% 66.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::timer_service>(boost::capy::execution_context&) :200 11298x 100.0% 100.0% 100.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::udp_service>(boost::capy::execution_context&) :200 273x 80.0% 50.0% 66.0% boost::corosio::io_object::io_object(boost::corosio::io_object::handle) :210 27691x 100.0% 100.0% boost::corosio::io_object::io_object(boost::corosio::io_object&&) :213 2744x 100.0% 100.0% boost::corosio::io_object::operator=(boost::corosio::io_object&&) :216 4x 100.0% 50.0% 100.0%
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_IO_IO_OBJECT_HPP
12 #define BOOST_COROSIO_IO_IO_OBJECT_HPP
13
14 #include <boost/corosio/detail/config.hpp>
15 #include <boost/corosio/detail/except.hpp>
16 #include <boost/capy/ex/execution_context.hpp>
17
18 #include <utility>
19
20 namespace boost::corosio {
21
22 /** Base class for platform I/O objects.
23
24 Provides common infrastructure for I/O objects that wrap kernel
25 resources (sockets, timers, signal handlers, acceptors). Derived
26 classes dispatch operations through a platform-specific vtable
27 (IOCP, epoll, kqueue, io_uring).
28
29 @par Semantics
30 Only concrete platform I/O types should inherit from `io_object`.
31 Test mocks, decorators, and stream adapters must not inherit from
32 this class. Use concepts or templates for generic I/O algorithms.
33
34 @par Thread Safety
35 Distinct objects: Safe.
36 Shared objects: Unsafe. All operations on a single I/O object
37 must be serialized.
38
39 @note Intended as a protected base class. The handle member
40 `h_` is accessible to derived classes.
41
42 @see io_stream, tcp_socket, tcp_acceptor
43 */
44 class BOOST_COROSIO_DECL io_object
45 {
46 public:
47 class handle;
48
49 /** Base interface for platform I/O implementations.
50
51 Derived classes provide platform-specific operation dispatch.
52 */
53 struct implementation
54 {
55 24597x virtual ~implementation() = default;
56 };
57
58 /** Service interface for I/O object lifecycle management.
59
60 Platform backends implement this interface to manage the
61 creation, closing, and destruction of I/O object
62 implementations.
63 */
64 struct BOOST_COROSIO_DECL io_service
65 {
66 25201x virtual ~io_service() = default;
67
68 /// Construct a new implementation instance.
69 virtual implementation* construct() = 0;
70
71 /// Destroy the implementation, closing kernel resources and freeing memory.
72 virtual void destroy(implementation*) = 0;
73
74 /// Close the I/O object, releasing kernel resources without deallocating.
75 11522x virtual void close(handle&) {}
76 };
77
78 /** RAII wrapper for I/O object implementation lifetime.
79
80 Manages ownership of the platform-specific implementation,
81 automatically destroying it when the handle goes out of scope.
82 */
83 class handle
84 {
85 10x capy::execution_context* ctx_ = nullptr;
86 10x io_service* svc_ = nullptr;
87 10x implementation* impl_ = nullptr;
88
89 public:
90 /// Destroy the handle and its implementation.
91 116875x ~handle()
92 58438x {
93
2/2
✓ Branch 0 taken 31121 times.
✓ Branch 1 taken 27316 times.
58437x if (impl_)
94 {
95
2/2
✓ Branch 0 taken 27315 times.
✓ Branch 1 taken 1 time.
27317x svc_->close(*this);
96
2/2
✓ Branch 0 taken 27314 times.
✓ Branch 1 taken 1 time.
27315x svc_->destroy(impl_);
97 27314x }
98 116873x }
99
100 /// Construct an empty handle.
101 30x handle() = default;
102
103 /// Construct a handle bound to a context and service.
104 55384x handle(capy::execution_context& ctx, io_service& svc)
105 27692x : ctx_(&ctx)
106 27692x , svc_(&svc)
107 27692x , impl_(svc_->construct())
108 27692x {
109 55384x }
110
111 /// Move construct from another handle.
112 61512x handle(handle&& other) noexcept
113 30756x : ctx_(std::exchange(other.ctx_, nullptr))
114 30756x , svc_(std::exchange(other.svc_, nullptr))
115 30756x , impl_(std::exchange(other.impl_, nullptr))
116 30756x {
117 61512x }
118
119 /// Move assign from another handle.
120 357x handle& operator=(handle&& other) noexcept
121 {
122
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 357 times.
357x if (this != &other)
123 {
124
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 356 times.
357x if (impl_)
125 {
126
1/2
✓ Branch 0 taken 356 times.
✗ Branch 1 not taken.
356x svc_->close(*this);
127
1/2
✓ Branch 0 taken 356 times.
✗ Branch 1 not taken.
356x svc_->destroy(impl_);
128 356x }
129 357x ctx_ = std::exchange(other.ctx_, nullptr);
130 357x svc_ = std::exchange(other.svc_, nullptr);
131 357x impl_ = std::exchange(other.impl_, nullptr);
132 357x }
133 357x return *this;
134 }
135
136 handle(handle const&) = delete;
137 handle& operator=(handle const&) = delete;
138
139 /// Return true if the handle owns an implementation.
140 68715x explicit operator bool() const noexcept
141 {
142 68715x return impl_ != nullptr;
143 }
144
145 /// Return the associated I/O service.
146 28039x io_service& service() const noexcept
147 {
148 28039x return *svc_;
149 }
150
151 /// Return the platform implementation.
152 1132079x implementation* get() const noexcept
153 {
154 1132079x return impl_;
155 }
156
157 /** Replace the implementation, destroying the old one.
158
159 @param p The new implementation to own. May be nullptr.
160 */
161 6370x void reset(implementation* p) noexcept
162 {
163
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6291 times.
6370x if (impl_)
164 {
165
1/2
✓ Branch 0 taken 6291 times.
✗ Branch 1 not taken.
6370x svc_->close(*this);
166
1/2
✓ Branch 0 taken 6291 times.
✗ Branch 1 not taken.
6370x svc_->destroy(impl_);
167 6370x }
168 6370x impl_ = p;
169 6370x }
170
171 /// Return the execution context.
172 39x capy::execution_context& context() const noexcept
173 {
174 39x return *ctx_;
175 }
176 };
177
178 /// Return the execution context.
179 39x capy::execution_context& context() const noexcept
180 {
181 39x return h_.context();
182 }
183
184 protected:
185 30425x virtual ~io_object() = default;
186
187 /// Default construct for virtual base initialization.
188 10x io_object() noexcept = default;
189
190 /** Create a handle bound to a service found in the context.
191
192 @tparam Service The service type whose key_type is used for lookup.
193 @param ctx The execution context to search for the service.
194
195 @return A handle owning a freshly constructed implementation.
196
197 @throws std::logic_error if the service is not installed.
198 */
199 template<class Service>
200 27696x static handle create_handle(capy::execution_context& ctx)
201 {
202 27696x auto* svc = ctx.find_service<Service>();
203
6/28
✓ Branch 0 taken 27510 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 51 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 59 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 51 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 21 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
27696x if (!svc)
204 4x detail::throw_logic_error(
205 "io_object::create_handle: service not installed");
206 27692x return handle(ctx, *svc);
207 }
208
209 /// Construct an I/O object from a handle.
210 27691x explicit io_object(handle h) noexcept : h_(std::move(h)) {}
211
212 /// Move construct from another I/O object.
213 2744x io_object(io_object&& other) noexcept : h_(std::move(other.h_)) {}
214
215 /// Move assign from another I/O object.
216 4x io_object& operator=(io_object&& other) noexcept
217 {
218
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4x if (this != &other)
219 4x h_ = std::move(other.h_);
220 4x return *this;
221 }
222
223 io_object(io_object const&) = delete;
224 io_object& operator=(io_object const&) = delete;
225
226 /// The platform I/O handle owned by this object.
227 BOOST_COROSIO_MSVC_WARNING_PUSH
228 BOOST_COROSIO_MSVC_WARNING_DISABLE(4251)
229 handle h_;
230 BOOST_COROSIO_MSVC_WARNING_POP
231 };
232
233 } // namespace boost::corosio
234
235 #endif
236