LCOV - code coverage report
Current view: top level - src/test - socket_pair.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 71.4 % 35 25
Test Date: 2026-02-04 19:19:32 Functions: 100.0 % 3 3

            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              : #include <boost/corosio/test/socket_pair.hpp>
      11              : #include <boost/corosio/tcp_acceptor.hpp>
      12              : #include <system_error>
      13              : #include <boost/corosio/basic_io_context.hpp>
      14              : #include <boost/corosio/detail/platform.hpp>
      15              : #include <boost/capy/ex/run_async.hpp>
      16              : #include <boost/capy/task.hpp>
      17              : 
      18              : #include <cstdio>
      19              : #include <stdexcept>
      20              : 
      21              : namespace boost::corosio::test {
      22              : 
      23              : std::pair<tcp_socket, tcp_socket>
      24            2 : make_socket_pair(basic_io_context& ctx)
      25              : {
      26            2 :     auto ex = ctx.get_executor();
      27              : 
      28            2 :     std::error_code accept_ec;
      29            2 :     std::error_code connect_ec;
      30            2 :     bool accept_done = false;
      31            2 :     bool connect_done = false;
      32              : 
      33              :     // Use ephemeral port (0) - OS assigns an available port
      34            2 :     tcp_acceptor acc(ctx);
      35            2 :     if (auto ec = acc.listen(endpoint(ipv4_address::loopback(), 0)))
      36            0 :         throw std::runtime_error("socket_pair listen failed: " + ec.message());
      37            2 :     auto port = acc.local_endpoint().port();
      38              : 
      39            2 :     tcp_socket s1(ctx);
      40            2 :     tcp_socket s2(ctx);
      41            2 :     s2.open();
      42              : 
      43            4 :     capy::run_async(ex)(
      44            2 :         [](tcp_acceptor& a, tcp_socket& s,
      45              :            std::error_code& ec_out, bool& done_out) -> capy::task<>
      46              :         {
      47              :             auto [ec] = co_await a.accept(s);
      48              :             ec_out = ec;
      49              :             done_out = true;
      50            8 :         }(acc, s1, accept_ec, accept_done));
      51              : 
      52            4 :     capy::run_async(ex)(
      53            2 :         [](tcp_socket& s, endpoint ep,
      54              :            std::error_code& ec_out, bool& done_out) -> capy::task<>
      55              :         {
      56              :             auto [ec] = co_await s.connect(ep);
      57              :             ec_out = ec;
      58              :             done_out = true;
      59            8 :         }(s2, endpoint(ipv4_address::loopback(), port),
      60              :           connect_ec, connect_done));
      61              : 
      62            2 :     ctx.run();
      63            2 :     ctx.restart();
      64              : 
      65            2 :     if (!accept_done || accept_ec)
      66              :     {
      67            0 :         std::fprintf(stderr, "socket_pair: accept failed (done=%d, ec=%s)\n",
      68            0 :             accept_done, accept_ec.message().c_str());
      69            0 :         acc.close();
      70            0 :         throw std::runtime_error("socket_pair accept failed");
      71              :     }
      72              : 
      73            2 :     if (!connect_done || connect_ec)
      74              :     {
      75            0 :         std::fprintf(stderr, "socket_pair: connect failed (done=%d, ec=%s)\n",
      76            0 :             connect_done, connect_ec.message().c_str());
      77            0 :         acc.close();
      78            0 :         s1.close();
      79            0 :         throw std::runtime_error("socket_pair connect failed");
      80              :     }
      81              : 
      82            2 :     acc.close();
      83              : 
      84            4 :     return {std::move(s1), std::move(s2)};
      85            2 : }
      86              : 
      87              : } // namespace boost::corosio::test
        

Generated by: LCOV version 2.3