include/boost/corosio/io/io_object.hpp

100.0% Lines (57 / 57) 100.0% Functions (44 / 44)
io_object.hpp
f(x) Functions (44)
Function Calls Lines Blocks
boost::corosio::io_object::implementation::~implementation() :56 12470x 100.0% 100.0% boost::corosio::io_object::io_service::~io_service() :66 24651x 100.0% 100.0% boost::corosio::io_object::io_service::close(boost::corosio::io_object::handle&) :75 13496x 100.0% 100.0% boost::corosio::io_object::handle::~handle() :89 44122x 100.0% 100.0% boost::corosio::io_object::handle::handle() :99 10x 100.0% 100.0% boost::corosio::io_object::handle::handle(boost::capy::execution_context&, boost::corosio::io_object::io_service&) :102 21531x 100.0% 100.0% boost::corosio::io_object::handle::handle(boost::corosio::io_object::handle&&) :110 22602x 100.0% 100.0% boost::corosio::io_object::handle::operator=(boost::corosio::io_object::handle&&) :118 42x 100.0% 100.0% boost::corosio::io_object::handle::operator bool() const :140 31751x 100.0% 100.0% boost::corosio::io_object::handle::service() const :146 14038x 100.0% 100.0% boost::corosio::io_object::handle::get() const :152 500098x 100.0% 100.0% boost::corosio::io_object::handle::reset(boost::corosio::io_object::implementation*) :161 2781x 100.0% 100.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() :186 22260x 100.0% 100.0% boost::corosio::io_object::io_object() :189 10x 100.0% 100.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::epoll_local_datagram_service>(boost::capy::execution_context&) :201 15x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::epoll_local_stream_acceptor_service>(boost::capy::execution_context&) :201 9x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::epoll_local_stream_service>(boost::capy::execution_context&) :201 20x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::epoll_tcp_acceptor_service>(boost::capy::execution_context&) :201 18x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::epoll_tcp_service>(boost::capy::execution_context&) :201 26x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::epoll_udp_service>(boost::capy::execution_context&) :201 21x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::file_service>(boost::capy::execution_context&) :201 248x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::local_datagram_service>(boost::capy::execution_context&) :201 239x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::local_stream_acceptor_service>(boost::capy::execution_context&) :201 92x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::local_stream_service>(boost::capy::execution_context&) :201 284x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::posix_random_access_file_service>(boost::capy::execution_context&) :201 16x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::posix_resolver_service>(boost::capy::execution_context&) :201 64x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::posix_signal_service>(boost::capy::execution_context&) :201 190x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::posix_stream_file_service>(boost::capy::execution_context&) :201 16x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::random_access_file_service>(boost::capy::execution_context&) :201 197x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::select_local_datagram_service>(boost::capy::execution_context&) :201 15x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::select_local_stream_acceptor_service>(boost::capy::execution_context&) :201 9x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::select_local_stream_service>(boost::capy::execution_context&) :201 20x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::select_tcp_acceptor_service>(boost::capy::execution_context&) :201 17x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::select_tcp_service>(boost::capy::execution_context&) :201 23x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::select_udp_service>(boost::capy::execution_context&) :201 21x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::tcp_acceptor_service>(boost::capy::execution_context&) :201 627x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::tcp_service>(boost::capy::execution_context&) :201 5778x 80.0% 80.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::timer_service>(boost::capy::execution_context&) :201 13253x 100.0% 100.0% boost::corosio::io_object::handle boost::corosio::io_object::create_handle<boost::corosio::detail::udp_service>(boost::capy::execution_context&) :201 317x 80.0% 80.0% boost::corosio::io_object::io_object(boost::corosio::io_object::handle) :211 21531x 100.0% 100.0% boost::corosio::io_object::io_object(boost::corosio::io_object&&) :214 740x 100.0% 100.0% boost::corosio::io_object::operator=(boost::corosio::io_object&&) :217 4x 100.0% 100.0%
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
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 /** Owns the platform-specific handle and execution context that a derived
23 socket, timer, signal handler, or acceptor type uses to dispatch
24 operations.
25
26 Provides common infrastructure for I/O objects that wrap kernel
27 resources (sockets, timers, signal handlers, acceptors). Derived
28 classes dispatch operations through a platform-specific vtable
29 (IOCP, epoll, kqueue, io_uring).
30
31 @par Semantics
32 Only concrete platform I/O types should inherit from `io_object`.
33 Test mocks, decorators, and stream adapters must not inherit from
34 this class. Use concepts or templates for generic I/O algorithms.
35
36 @par Thread Safety
37 Distinct objects: Safe.
38 Shared objects: Unsafe. All operations on a single I/O object
39 must be serialized.
40
41 @note Intended as a protected base class. The handle member
42 `h_` is accessible to derived classes.
43
44 @see io_stream, tcp_socket, tcp_acceptor
45 */
46 class BOOST_COROSIO_DECL io_object
47 {
48 public:
49 class handle;
50
51 /** Derived types dispatch platform-specific I/O operations through it.
52 */
53 struct implementation
54 {
55 /// Destroy the implementation; called only through @ref io_service.
56 12470x virtual ~implementation() = default;
57 };
58
59 /** Constructs, closes, and destroys platform implementations on
60 behalf of an I/O object. Platform backends implement this
61 interface.
62 */
63 struct BOOST_COROSIO_DECL io_service
64 {
65 /// Destroy the service; the execution context outlives it.
66 24651x 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* impl) = 0;
73
74 /// Close the I/O object, releasing kernel resources without deallocating.
75 13496x virtual void close([[maybe_unused]] handle& h) {}
76 };
77
78 /** Owns a platform-specific I/O implementation and destroys it
79 when the handle goes out of scope.
80 */
81 class handle
82 {
83 capy::execution_context* ctx_ = nullptr;
84 io_service* svc_ = nullptr;
85 implementation* impl_ = nullptr;
86
87 public:
88 /// Destroy the handle and its implementation.
89 44122x ~handle()
90 {
91 44122x if (impl_)
92 {
93 21469x svc_->close(*this);
94 21469x svc_->destroy(impl_);
95 }
96 44122x }
97
98 /// Construct an empty handle.
99 10x handle() = default;
100
101 /// Construct a handle bound to a context and service.
102 21531x handle(capy::execution_context& ctx, io_service& svc)
103 21531x : ctx_(&ctx)
104 21531x , svc_(&svc)
105 21531x , impl_(svc_->construct())
106 {
107 21531x }
108
109 /// Move construct from another handle.
110 22602x handle(handle&& other) noexcept
111 22602x : ctx_(std::exchange(other.ctx_, nullptr))
112 22602x , svc_(std::exchange(other.svc_, nullptr))
113 22602x , impl_(std::exchange(other.impl_, nullptr))
114 {
115 22602x }
116
117 /// Move assign from another handle.
118 42x handle& operator=(handle&& other) noexcept
119 {
120 42x if (this != &other)
121 {
122 42x if (impl_)
123 {
124 41x svc_->close(*this);
125 41x svc_->destroy(impl_);
126 }
127 42x ctx_ = std::exchange(other.ctx_, nullptr);
128 42x svc_ = std::exchange(other.svc_, nullptr);
129 42x impl_ = std::exchange(other.impl_, nullptr);
130 }
131 42x return *this;
132 }
133
134 /// Copy construction is disabled; the implementation is uniquely owned.
135 handle(handle const&) = delete;
136 /// Copy assignment is disabled; the implementation is uniquely owned.
137 handle& operator=(handle const&) = delete;
138
139 /// Return true if the handle owns an implementation.
140 31751x explicit operator bool() const noexcept
141 {
142 31751x return impl_ != nullptr;
143 }
144
145 /// Return the associated I/O service.
146 14038x io_service& service() const noexcept
147 {
148 14038x return *svc_;
149 }
150
151 /// Return the platform implementation.
152 500098x implementation* get() const noexcept
153 {
154 500098x 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 2781x void reset(implementation* p) noexcept
162 {
163 2781x if (impl_)
164 {
165 2781x svc_->close(*this);
166 2781x svc_->destroy(impl_);
167 }
168 2781x impl_ = p;
169 2781x }
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 /// Destroy the object; protected, so only a derived type destroys one.
186 22260x virtual ~io_object() = default;
187
188 /// Default construct for virtual base initialization.
189 10x io_object() noexcept = default;
190
191 /** Create a handle bound to a service found in the context.
192
193 @tparam Service The service type whose key_type is used for lookup.
194 @param ctx The execution context to search for the service.
195
196 @return A handle owning a freshly constructed implementation.
197
198 @throws std::logic_error if the service is not installed.
199 */
200 template<class Service>
201 21535x static handle create_handle(capy::execution_context& ctx)
202 {
203 21535x auto* svc = ctx.find_service<Service>();
204 21535x if (!svc)
205 4x detail::throw_logic_error(
206 "io_object::create_handle: service not installed");
207 21531x return handle(ctx, *svc);
208 }
209
210 /// Construct an I/O object from a handle.
211 21531x explicit io_object(handle h) noexcept : h_(std::move(h)) {}
212
213 /// Move construct from another I/O object.
214 740x io_object(io_object&& other) noexcept : h_(std::move(other.h_)) {}
215
216 /// Move assign from another I/O object.
217 4x io_object& operator=(io_object&& other) noexcept
218 {
219 4x if (this != &other)
220 4x h_ = std::move(other.h_);
221 4x return *this;
222 }
223
224 /// Copy construction is disabled; the handle is uniquely owned.
225 io_object(io_object const&) = delete;
226 /// Copy assignment is disabled; the handle is uniquely owned.
227 io_object& operator=(io_object const&) = delete;
228
229 /// The platform I/O handle owned by this object.
230 BOOST_COROSIO_MSVC_WARNING_PUSH
231 BOOST_COROSIO_MSVC_WARNING_DISABLE(4251)
232 handle h_;
233 BOOST_COROSIO_MSVC_WARNING_POP
234 };
235
236 } // namespace boost::corosio
237
238 #endif
239