Line data Source code
1 : //
2 : // Copyright (c) 2026 Steve Gerbino
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_DETAIL_SOCKET_SERVICE_HPP
11 : #define BOOST_COROSIO_DETAIL_SOCKET_SERVICE_HPP
12 :
13 : #include <boost/corosio/detail/config.hpp>
14 : #include <boost/corosio/tcp_socket.hpp>
15 : #include <boost/corosio/tcp_acceptor.hpp>
16 : #include <boost/corosio/endpoint.hpp>
17 : #include <boost/capy/ex/execution_context.hpp>
18 : #include <system_error>
19 :
20 : /*
21 : Abstract Socket Service
22 : =======================
23 :
24 : These abstract base classes enable runtime backend selection for socket
25 : and acceptor operations. Both epoll_sockets and select_sockets derive
26 : from socket_service and use it as their key_type. This allows
27 : use_service<socket_service>() to return whichever implementation was
28 : installed first (by the context constructor).
29 :
30 : Design Pattern:
31 : - socket_service is the abstract base with key_type = socket_service
32 : - Concrete implementations (epoll_sockets, select_sockets) inherit from it
33 : - The concrete implementation's key_type is inherited from socket_service
34 : - Whichever context type is constructed first installs its implementation
35 : - socket.cpp and acceptor.cpp use the abstract interface
36 :
37 : This enables:
38 : - epoll_context installs epoll_sockets via make_service<epoll_sockets>()
39 : - select_context installs select_sockets via make_service<select_sockets>()
40 : - socket.cpp uses use_service<socket_service>() to get whichever is installed
41 : */
42 :
43 : namespace boost::corosio::detail {
44 :
45 : //------------------------------------------------------------------------------
46 :
47 : /** Abstract socket service base class.
48 :
49 : This is the service interface used by socket.cpp. Concrete implementations
50 : (epoll_socket_service, select_socket_service, etc.) inherit from this class
51 : and provide the actual socket operations.
52 :
53 : The key_type is socket_service itself, which enables runtime polymorphism:
54 : whichever concrete implementation is installed first by a context constructor
55 : will be returned by find_service<socket_service>().
56 : */
57 : class socket_service
58 : : public capy::execution_context::service
59 : , public io_object::io_service
60 : {
61 : public:
62 : using key_type = socket_service;
63 :
64 0 : void open(io_object::handle&) override {}
65 0 : void close(io_object::handle&) override {}
66 0 : void destroy(io_object::implementation*) override {}
67 0 : io_object::implementation* construct() override { return nullptr; }
68 :
69 : /** Create a new socket implementation.
70 :
71 : @return Reference to the newly created socket implementation.
72 : */
73 : virtual tcp_socket::socket_impl& create_impl() = 0;
74 :
75 : /** Destroy a socket implementation.
76 :
77 : @param impl The socket implementation to destroy.
78 : */
79 : virtual void destroy_impl(tcp_socket::socket_impl& impl) = 0;
80 :
81 : /** Open a socket.
82 :
83 : Creates an IPv4 TCP socket and associates it with the platform reactor.
84 :
85 : @param impl The socket implementation to open.
86 : @return Error code on failure, empty on success.
87 : */
88 : virtual std::error_code open_socket(tcp_socket::socket_impl& impl) = 0;
89 :
90 : protected:
91 304 : socket_service() = default;
92 304 : ~socket_service() override = default;
93 : };
94 :
95 : //------------------------------------------------------------------------------
96 :
97 : /** Abstract acceptor service base class.
98 :
99 : This is the service interface used by acceptor.cpp. Concrete implementations
100 : (epoll_acceptor_service, select_acceptor_service, etc.) inherit from this class
101 : and provide the actual acceptor operations.
102 :
103 : The key_type is acceptor_service itself, which enables runtime polymorphism.
104 : */
105 : class acceptor_service : public capy::execution_context::service
106 : {
107 : public:
108 : using key_type = acceptor_service;
109 :
110 : /** Create a new acceptor implementation.
111 :
112 : @return Reference to the newly created acceptor implementation.
113 : */
114 : virtual tcp_acceptor::acceptor_impl& create_acceptor_impl() = 0;
115 :
116 : /** Destroy an acceptor implementation.
117 :
118 : @param impl The acceptor implementation to destroy.
119 : */
120 : virtual void destroy_acceptor_impl(tcp_acceptor::acceptor_impl& impl) = 0;
121 :
122 : /** Open an acceptor.
123 :
124 : Creates an IPv4 TCP socket, binds it to the specified endpoint,
125 : and begins listening for incoming connections.
126 :
127 : @param impl The acceptor implementation to open.
128 : @param ep The local endpoint to bind to.
129 : @param backlog The maximum length of the queue of pending connections.
130 : @return Error code on failure, empty on success.
131 : */
132 : virtual std::error_code open_acceptor(
133 : tcp_acceptor::acceptor_impl& impl,
134 : endpoint ep,
135 : int backlog) = 0;
136 :
137 : protected:
138 304 : acceptor_service() = default;
139 304 : ~acceptor_service() override = default;
140 : };
141 :
142 : } // namespace boost::corosio::detail
143 :
144 : #endif // BOOST_COROSIO_DETAIL_SOCKET_SERVICE_HPP
|