LCOV - code coverage report
Current view: top level - corosio/native/detail/reactor - reactor_socket_finals.hpp (source / functions) Coverage Total Hit Missed
Test: coverage_remapped.info Lines: 72.4 % 29 21 8
Test Date: 2026-04-10 22:36:12 Functions: 59.3 % 54 32 22

           TLA  Line data    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_DETAIL_REACTOR_REACTOR_SOCKET_FINALS_HPP
      11                 : #define BOOST_COROSIO_NATIVE_DETAIL_REACTOR_REACTOR_SOCKET_FINALS_HPP
      12                 : 
      13                 : /* Parameterized final socket and acceptor types for reactor backends.
      14                 : 
      15                 :    These templates are instantiated per-backend via Traits to produce
      16                 :    the concrete socket types used by the public API. Each final type
      17                 :    is a thin wrapper adding only protocol-specific details (ImplBase,
      18                 :    Endpoint) to the CRTP base classes.
      19                 : */
      20                 : 
      21                 : #include <boost/corosio/tcp_socket.hpp>
      22                 : #include <boost/corosio/udp_socket.hpp>
      23                 : #include <boost/corosio/local_stream_socket.hpp>
      24                 : #include <boost/corosio/local_datagram_socket.hpp>
      25                 : #include <boost/corosio/tcp_acceptor.hpp>
      26                 : #include <boost/corosio/local_stream_acceptor.hpp>
      27                 : #include <boost/corosio/shutdown_type.hpp>
      28                 : 
      29                 : #include <boost/corosio/native/detail/reactor/reactor_stream_socket.hpp>
      30                 : #include <boost/corosio/native/detail/reactor/reactor_datagram_socket.hpp>
      31                 : #include <boost/corosio/native/detail/reactor/reactor_acceptor.hpp>
      32                 : #include <boost/corosio/native/detail/reactor/reactor_stream_ops.hpp>
      33                 : #include <boost/corosio/native/detail/reactor/reactor_datagram_ops.hpp>
      34                 : 
      35                 : #include <boost/corosio/detail/tcp_acceptor_service.hpp>
      36                 : #include <boost/corosio/detail/local_stream_acceptor_service.hpp>
      37                 : #include <boost/corosio/native/detail/make_err.hpp>
      38                 : 
      39                 : namespace boost::corosio::detail {
      40                 : 
      41                 : // ============================================================
      42                 : // Forward declarations
      43                 : // ============================================================
      44                 : 
      45                 : template<class Traits, class ImplBase, class Endpoint> class reactor_stream_socket_final;
      46                 : template<class Traits, class ImplBase, class Endpoint> class reactor_dgram_socket_final;
      47                 : template<class Traits, class AccImplBase, class Endpoint> class reactor_acceptor_final;
      48                 : 
      49                 : template<class Traits, class SocketFinal> class reactor_tcp_service_final;
      50                 : template<class Traits, class SocketFinal> class reactor_local_stream_service_final;
      51                 : template<class Traits, class SocketFinal> class reactor_udp_service_final;
      52                 : template<class Traits, class SocketFinal> class reactor_local_dgram_service_final;
      53                 : template<class Traits, class ServiceBase, class AccFinal, class StreamServiceFinal, class Endpoint> class reactor_acceptor_service_final;
      54                 : 
      55                 : // ============================================================
      56                 : // Op type aliases
      57                 : // ============================================================
      58                 : 
      59                 : template<class Traits, class Endpoint>
      60                 : using stream_socket_t = reactor_stream_socket_final<Traits,
      61                 :     std::conditional_t<std::is_same_v<Endpoint, endpoint>,
      62                 :         tcp_socket::implementation,
      63                 :         local_stream_socket::implementation>,
      64                 :     Endpoint>;
      65                 : 
      66                 : template<class Traits, class Endpoint>
      67                 : using stream_acceptor_t = reactor_acceptor_final<Traits,
      68                 :     std::conditional_t<std::is_same_v<Endpoint, endpoint>,
      69                 :         tcp_acceptor::implementation,
      70                 :         local_stream_acceptor::implementation>,
      71                 :     Endpoint>;
      72                 : 
      73                 : template<class Traits, class Endpoint>
      74                 : using stream_base_op = reactor_stream_base_op<
      75                 :     Traits, stream_socket_t<Traits, Endpoint>,
      76                 :     stream_acceptor_t<Traits, Endpoint>, Endpoint>;
      77                 : 
      78                 : template<class Traits, class Endpoint>
      79                 : using stream_connect_op = reactor_stream_connect_op<
      80                 :     Traits, stream_socket_t<Traits, Endpoint>,
      81                 :     stream_acceptor_t<Traits, Endpoint>, Endpoint>;
      82                 : 
      83                 : template<class Traits, class Endpoint>
      84                 : using stream_read_op = reactor_stream_read_op<
      85                 :     Traits, stream_socket_t<Traits, Endpoint>,
      86                 :     stream_acceptor_t<Traits, Endpoint>, Endpoint>;
      87                 : 
      88                 : template<class Traits, class Endpoint>
      89                 : using stream_write_op = reactor_stream_write_op<
      90                 :     Traits, stream_socket_t<Traits, Endpoint>,
      91                 :     stream_acceptor_t<Traits, Endpoint>, Endpoint>;
      92                 : 
      93                 : template<class Traits, class Endpoint>
      94                 : using stream_accept_op = reactor_stream_accept_op<
      95                 :     Traits, stream_socket_t<Traits, Endpoint>,
      96                 :     stream_acceptor_t<Traits, Endpoint>, Endpoint>;
      97                 : 
      98                 : template<class Traits, class Endpoint>
      99                 : using dgram_socket_t = reactor_dgram_socket_final<Traits,
     100                 :     std::conditional_t<std::is_same_v<Endpoint, endpoint>,
     101                 :         udp_socket::implementation,
     102                 :         local_datagram_socket::implementation>,
     103                 :     Endpoint>;
     104                 : 
     105                 : template<class Traits, class Endpoint>
     106                 : using dgram_connect_op = reactor_dgram_connect_op<
     107                 :     Traits, dgram_socket_t<Traits, Endpoint>,
     108                 :     stream_acceptor_t<Traits, endpoint>, Endpoint>;
     109                 : 
     110                 : template<class Traits, class Endpoint>
     111                 : using dgram_send_to_op = reactor_dgram_send_to_op<
     112                 :     Traits, dgram_socket_t<Traits, Endpoint>,
     113                 :     stream_acceptor_t<Traits, endpoint>, Endpoint>;
     114                 : 
     115                 : template<class Traits, class Endpoint>
     116                 : using dgram_recv_from_op = reactor_dgram_recv_from_op<
     117                 :     Traits, dgram_socket_t<Traits, Endpoint>,
     118                 :     stream_acceptor_t<Traits, endpoint>, Endpoint>;
     119                 : 
     120                 : template<class Traits, class Endpoint>
     121                 : using dgram_send_op = reactor_dgram_send_op<
     122                 :     Traits, dgram_socket_t<Traits, Endpoint>,
     123                 :     stream_acceptor_t<Traits, endpoint>, Endpoint>;
     124                 : 
     125                 : template<class Traits, class Endpoint>
     126                 : using dgram_recv_op = reactor_dgram_recv_op<
     127                 :     Traits, dgram_socket_t<Traits, Endpoint>,
     128                 :     stream_acceptor_t<Traits, endpoint>, Endpoint>;
     129                 : 
     130                 : // ============================================================
     131                 : // Stream socket final
     132                 : // ============================================================
     133                 : 
     134                 : // release_socket below cannot be marked 'override' unconditionally: it
     135                 : // overrides a pure virtual only when ImplBase is local_stream_socket::
     136                 : // implementation. For the tcp_socket::implementation instantiation the
     137                 : // base has no such virtual, so 'override' would fail to compile. Scope-
     138                 : // suppress clang's -Winconsistent-missing-override for the overriding
     139                 : // instantiation. clang-tidy's modernize-use-override is silenced
     140                 : // separately via NOLINTNEXTLINE below.
     141                 : BOOST_COROSIO_CLANG_WARNING_PUSH
     142                 : BOOST_COROSIO_CLANG_WARNING_DISABLE("-Winconsistent-missing-override")
     143                 : 
     144                 : template<class Traits, class ImplBase, class Endpoint>
     145                 : class reactor_stream_socket_final final
     146                 :     : public reactor_stream_socket<
     147                 :           reactor_stream_socket_final<Traits, ImplBase, Endpoint>,
     148                 :           std::conditional_t<std::is_same_v<Endpoint, endpoint>,
     149                 :               reactor_tcp_service_final<
     150                 :                   Traits, reactor_stream_socket_final<Traits, ImplBase, Endpoint>>,
     151                 :               reactor_local_stream_service_final<
     152                 :                   Traits, reactor_stream_socket_final<Traits, ImplBase, Endpoint>>>,
     153                 :           stream_connect_op<Traits, Endpoint>,
     154                 :           stream_read_op<Traits, Endpoint>,
     155                 :           stream_write_op<Traits, Endpoint>,
     156                 :           typename Traits::desc_state_type,
     157                 :           ImplBase,
     158                 :           Endpoint>
     159                 : {
     160                 :     using service_type = std::conditional_t<std::is_same_v<Endpoint, endpoint>,
     161                 :         reactor_tcp_service_final<Traits, reactor_stream_socket_final>,
     162                 :         reactor_local_stream_service_final<Traits, reactor_stream_socket_final>>;
     163                 :     friend service_type;
     164                 : 
     165                 : public:
     166                 :     using impl_base_type = ImplBase;
     167                 : 
     168                 :     /// Per-socket hook state (e.g., kqueue SO_LINGER tracking).
     169                 :     [[no_unique_address]] typename Traits::stream_socket_hook hook_;
     170                 : 
     171 HIT       24072 :     explicit reactor_stream_socket_final(service_type& svc) noexcept
     172           24072 :         : reactor_stream_socket_final::reactor_stream_socket(svc)
     173                 :     {
     174           24072 :     }
     175                 : 
     176           24072 :     ~reactor_stream_socket_final() override = default;
     177                 : 
     178              60 :     std::error_code set_option(
     179                 :         int level, int optname,
     180                 :         void const* data, std::size_t size) noexcept override
     181                 :     {
     182              60 :         return hook_.on_set_option(this->fd_, level, optname, data, size);
     183                 :     }
     184                 : 
     185                 :     // Shadows reactor_stream_socket::close_socket so the hook fires on
     186                 :     // every fd close path (user close(), service shutdown/destroy,
     187                 :     // do_assign_fd reuse). The hook needs the fd before do_close_socket
     188                 :     // resets it to -1.
     189           72219 :     void close_socket() noexcept
     190                 :     {
     191           72219 :         hook_.pre_shutdown(this->fd_);
     192           72219 :         this->do_close_socket();
     193           72219 :     }
     194                 : 
     195                 :     // Overrides local_stream_socket::implementation::release_socket().
     196                 :     // Cannot use 'override' — tcp_socket::implementation has no such method.
     197                 :     // NOLINTNEXTLINE(modernize-use-override)
     198               2 :     native_handle_type release_socket() noexcept
     199                 :     {
     200               2 :         hook_ = {};
     201               2 :         return this->do_release_socket();
     202                 :     }
     203                 : };
     204                 : 
     205                 : BOOST_COROSIO_CLANG_WARNING_POP
     206                 : 
     207                 : // ============================================================
     208                 : // Datagram socket final
     209                 : // ============================================================
     210                 : 
     211                 : // shutdown/bind/release_socket below cannot be marked 'override'
     212                 : // unconditionally: they override pure virtuals only when ImplBase is
     213                 : // local_datagram_socket::implementation. For the udp_socket::implementation
     214                 : // instantiation the base has no such virtuals, so 'override' would fail
     215                 : // to compile. Scope-suppress clang's -Winconsistent-missing-override for
     216                 : // the overriding instantiation. clang-tidy's modernize-use-override is
     217                 : // silenced separately via NOLINTNEXTLINE below.
     218                 : BOOST_COROSIO_CLANG_WARNING_PUSH
     219                 : BOOST_COROSIO_CLANG_WARNING_DISABLE("-Winconsistent-missing-override")
     220                 : 
     221                 : template<class Traits, class ImplBase, class Endpoint>
     222                 : class reactor_dgram_socket_final final
     223                 :     : public reactor_datagram_socket<
     224                 :           reactor_dgram_socket_final<Traits, ImplBase, Endpoint>,
     225                 :           std::conditional_t<std::is_same_v<Endpoint, endpoint>,
     226                 :               reactor_udp_service_final<
     227                 :                   Traits, reactor_dgram_socket_final<Traits, ImplBase, Endpoint>>,
     228                 :               reactor_local_dgram_service_final<
     229                 :                   Traits, reactor_dgram_socket_final<Traits, ImplBase, Endpoint>>>,
     230                 :           dgram_connect_op<Traits, Endpoint>,
     231                 :           dgram_send_to_op<Traits, Endpoint>,
     232                 :           dgram_recv_from_op<Traits, Endpoint>,
     233                 :           dgram_send_op<Traits, Endpoint>,
     234                 :           dgram_recv_op<Traits, Endpoint>,
     235                 :           typename Traits::desc_state_type,
     236                 :           ImplBase,
     237                 :           Endpoint>
     238                 : {
     239                 :     using service_type = std::conditional_t<std::is_same_v<Endpoint, endpoint>,
     240                 :         reactor_udp_service_final<Traits, reactor_dgram_socket_final>,
     241                 :         reactor_local_dgram_service_final<Traits, reactor_dgram_socket_final>>;
     242                 :     friend service_type;
     243                 : 
     244                 : public:
     245                 :     using impl_base_type = ImplBase;
     246                 : 
     247             128 :     explicit reactor_dgram_socket_final(service_type& svc) noexcept
     248             128 :         : reactor_dgram_socket_final::reactor_datagram_socket(svc)
     249                 :     {
     250             128 :     }
     251                 : 
     252             128 :     ~reactor_dgram_socket_final() override = default;
     253                 : 
     254                 :     // Overrides local_datagram_socket pure virtuals.
     255                 :     // Cannot use 'override' — udp_socket::implementation has no such methods.
     256                 :     // NOLINTNEXTLINE(modernize-use-override)
     257 MIS           0 :     std::error_code shutdown(corosio::shutdown_type what) noexcept
     258                 :     {
     259               0 :         return this->do_shutdown(static_cast<int>(what));
     260                 :     }
     261                 : 
     262                 :     // NOLINTNEXTLINE(modernize-use-override)
     263               0 :     std::error_code bind(Endpoint ep) noexcept
     264                 :     {
     265               0 :         return this->do_bind(ep);
     266                 :     }
     267                 : 
     268                 :     // NOLINTNEXTLINE(modernize-use-override)
     269               0 :     native_handle_type release_socket() noexcept
     270                 :     {
     271               0 :         return this->do_release_socket();
     272                 :     }
     273                 : };
     274                 : 
     275                 : BOOST_COROSIO_CLANG_WARNING_POP
     276                 : 
     277                 : // ============================================================
     278                 : // Acceptor final
     279                 : // ============================================================
     280                 : 
     281                 : template<class Traits, class Endpoint>
     282                 : using stream_service_for = std::conditional_t<std::is_same_v<Endpoint, endpoint>,
     283                 :     reactor_tcp_service_final<Traits, stream_socket_t<Traits, Endpoint>>,
     284                 :     reactor_local_stream_service_final<Traits, stream_socket_t<Traits, Endpoint>>>;
     285                 : 
     286                 : // release_socket below cannot be marked 'override' unconditionally: it
     287                 : // overrides a pure virtual only when AccImplBase is
     288                 : // local_stream_acceptor::implementation. For the tcp_acceptor::implementation
     289                 : // instantiation the base has no such virtual, so 'override' would fail to
     290                 : // compile. Scope-suppress clang's -Winconsistent-missing-override for the
     291                 : // overriding instantiation. clang-tidy's modernize-use-override is silenced
     292                 : // separately via NOLINTNEXTLINE below.
     293                 : BOOST_COROSIO_CLANG_WARNING_PUSH
     294                 : BOOST_COROSIO_CLANG_WARNING_DISABLE("-Winconsistent-missing-override")
     295                 : 
     296                 : template<class Traits, class AccImplBase, class Endpoint>
     297                 : class reactor_acceptor_final final
     298                 :     : public reactor_acceptor<
     299                 :           reactor_acceptor_final<Traits, AccImplBase, Endpoint>,
     300                 :           reactor_acceptor_service_final<
     301                 :               Traits,
     302                 :               std::conditional_t<std::is_same_v<Endpoint, endpoint>,
     303                 :                   tcp_acceptor_service, local_stream_acceptor_service>,
     304                 :               reactor_acceptor_final<Traits, AccImplBase, Endpoint>,
     305                 :               stream_service_for<Traits, Endpoint>,
     306                 :               Endpoint>,
     307                 :           stream_base_op<Traits, Endpoint>,
     308                 :           stream_accept_op<Traits, Endpoint>,
     309                 :           typename Traits::desc_state_type,
     310                 :           AccImplBase,
     311                 :           Endpoint>
     312                 : {
     313                 :     using acc_service_type = reactor_acceptor_service_final<
     314                 :         Traits,
     315                 :         std::conditional_t<std::is_same_v<Endpoint, endpoint>,
     316                 :             tcp_acceptor_service, local_stream_acceptor_service>,
     317                 :         reactor_acceptor_final,
     318                 :         stream_service_for<Traits, Endpoint>,
     319                 :         Endpoint>;
     320                 :     friend acc_service_type;
     321                 : 
     322                 : public:
     323 HIT         163 :     explicit reactor_acceptor_final(acc_service_type& svc) noexcept
     324             163 :         : reactor_acceptor_final::reactor_acceptor(svc)
     325                 :     {
     326             163 :     }
     327                 : 
     328             163 :     ~reactor_acceptor_final() override = default;
     329                 : 
     330                 :     using impl_base_type = AccImplBase;
     331                 : 
     332                 :     // NOLINTNEXTLINE(modernize-use-override)
     333 MIS           0 :     native_handle_type release_socket() noexcept
     334                 :     {
     335               0 :         return this->do_release_socket();
     336                 :     }
     337                 : 
     338                 :     std::coroutine_handle<> accept(
     339                 :         std::coroutine_handle<>,
     340                 :         capy::executor_ref,
     341                 :         std::stop_token,
     342                 :         std::error_code*,
     343                 :         io_object::implementation**) override;
     344                 : };
     345                 : 
     346                 : BOOST_COROSIO_CLANG_WARNING_POP
     347                 : 
     348                 : } // namespace boost::corosio::detail
     349                 : 
     350                 : #endif // BOOST_COROSIO_NATIVE_DETAIL_REACTOR_REACTOR_SOCKET_FINALS_HPP
        

Generated by: LCOV version 2.3