Line data Source code
1 : //
2 : // Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
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_IO_OBJECT_HPP
11 : #define BOOST_COROSIO_IO_OBJECT_HPP
12 :
13 : #include <boost/corosio/detail/config.hpp>
14 : #include <boost/capy/ex/execution_context.hpp>
15 :
16 : namespace boost::corosio {
17 :
18 : /** Base class for platform I/O objects.
19 :
20 : Provides common infrastructure for I/O objects that wrap kernel
21 : resources (sockets, timers, signal handlers, acceptors). Derived
22 : classes dispatch operations through a platform-specific vtable
23 : (IOCP, epoll, kqueue, io_uring).
24 :
25 : @par Semantics
26 : Only concrete platform I/O types should inherit from `io_object`.
27 : Test mocks, decorators, and stream adapters must not inherit from
28 : this class. Use concepts or templates for generic I/O algorithms.
29 :
30 : @par Thread Safety
31 : Distinct objects: Safe.
32 : Shared objects: Unsafe. All operations on a single I/O object
33 : must be serialized.
34 :
35 : @note Intended as a protected base class. The implementation
36 : pointer `impl_` is accessible to derived classes.
37 :
38 : @see io_stream, tcp_socket, tcp_acceptor
39 : */
40 : class BOOST_COROSIO_DECL io_object
41 : {
42 : public:
43 : /// Forward declaration for platform-specific implementation.
44 : struct implementation;
45 :
46 : class handle;
47 :
48 : /** Service interface for I/O object lifecycle management.
49 :
50 : Platform backends implement this interface to manage the
51 : creation, opening, closing, and destruction of I/O object
52 : implementations.
53 : */
54 : struct io_service
55 : {
56 : /// Open the I/O object for use.
57 : virtual void open(handle&) = 0;
58 :
59 : /// Close the I/O object, releasing kernel resources.
60 : virtual void close(handle&) = 0;
61 :
62 : /// Destroy the implementation, freeing memory.
63 : virtual void destroy(implementation*) = 0;
64 :
65 : /// Construct a new implementation instance.
66 : virtual implementation* construct() = 0;
67 : };
68 :
69 : /** RAII wrapper for I/O object implementation lifetime.
70 :
71 : Manages ownership of the platform-specific implementation,
72 : automatically destroying it when the handle goes out of scope.
73 : */
74 : class handle
75 : {
76 : capy::execution_context* ctx_ = nullptr;
77 : io_service* svc_ = nullptr;
78 : implementation* impl_ = nullptr;
79 :
80 : public:
81 : /// Destroy the handle and its implementation.
82 : ~handle()
83 : {
84 : if(impl_)
85 : svc_->destroy(impl_);
86 : }
87 :
88 : /// Construct an empty handle.
89 : handle() = default;
90 :
91 : /// Construct a handle bound to a context and service.
92 : handle(
93 : capy::execution_context& ctx,
94 : io_service& svc)
95 : : ctx_(&ctx)
96 : , svc_(&svc)
97 : , impl_(svc_->construct())
98 : {
99 : }
100 :
101 : /// Move construct from another handle.
102 : handle(handle&& other)
103 : : ctx_(std::exchange(other.ctx_, nullptr))
104 : , svc_(std::exchange(other.svc_, nullptr))
105 : , impl_(std::exchange(other.impl_, nullptr))
106 : {
107 : }
108 :
109 : /// Move assign from another handle.
110 : handle& operator=(handle&& other) noexcept
111 : {
112 : ctx_ = std::exchange(other.ctx_, nullptr);
113 : svc_ = std::exchange(other.svc_, nullptr);
114 : impl_ = std::exchange(other.impl_, nullptr);
115 : return *this;
116 : }
117 :
118 : /// Return the execution context.
119 : capy::execution_context& context() const noexcept
120 : {
121 : return *ctx_;
122 : }
123 :
124 : /// Return the associated I/O service.
125 : io_service& service() const noexcept
126 : {
127 : return *svc_;
128 : }
129 :
130 : /// Return the platform implementation.
131 : implementation& get() const noexcept
132 : {
133 : return *impl_;
134 : }
135 : };
136 :
137 : /** Base interface for platform I/O implementations.
138 :
139 : Derived classes provide platform-specific operation dispatch.
140 : */
141 : struct io_object_impl
142 : {
143 18098 : virtual ~io_object_impl() = default;
144 :
145 : /// Release associated resources without closing.
146 : virtual void release() = 0;
147 : };
148 :
149 : /// Return the execution context.
150 : capy::execution_context&
151 195 : context() const noexcept
152 : {
153 195 : return *ctx_;
154 : }
155 :
156 : protected:
157 27563 : virtual ~io_object() = default;
158 :
159 : /// Construct an I/O object bound to the given context.
160 : explicit
161 27561 : io_object(
162 : capy::execution_context& ctx) noexcept
163 27561 : : ctx_(&ctx)
164 : {
165 27561 : }
166 :
167 : capy::execution_context* ctx_ = nullptr;
168 : io_object_impl* impl_ = nullptr;
169 : };
170 :
171 : } // namespace boost::corosio
172 :
173 : #endif
|