LCOV - code coverage report
Current view: top level - src - tcp_socket.cpp (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 76.0 % 121 92
Test Date: 2026-02-06 05:04:16 Functions: 90.0 % 20 18

            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/tcp_socket.hpp>
      11              : #include <boost/corosio/detail/except.hpp>
      12              : #include <boost/corosio/detail/platform.hpp>
      13              : 
      14              : #if BOOST_COROSIO_HAS_IOCP
      15              : #include "src/detail/iocp/sockets.hpp"
      16              : #else
      17              : // POSIX backends use the abstract socket_service interface
      18              : #include "src/detail/socket_service.hpp"
      19              : #endif
      20              : 
      21              : namespace boost::corosio {
      22              : 
      23        17957 : tcp_socket::
      24        17957 : ~tcp_socket()
      25              : {
      26        17957 :     close();
      27        17957 : }
      28              : 
      29        17777 : tcp_socket::
      30              : tcp_socket(
      31        17777 :     capy::execution_context& ctx)
      32        17777 :     : io_stream(ctx)
      33              : {
      34        17777 : }
      35              : 
      36              : void
      37         8875 : tcp_socket::
      38              : open()
      39              : {
      40         8875 :     if (impl_)
      41            0 :         return;
      42              : 
      43              : #if BOOST_COROSIO_HAS_IOCP
      44              :     auto& svc = ctx_->use_service<detail::win_sockets>();
      45              :     auto& wrapper = svc.create_impl();
      46              :     impl_ = &wrapper;
      47              :     std::error_code ec = svc.open_socket(*wrapper.get_internal());
      48              : #else
      49              :     // POSIX backends use abstract socket_service for runtime polymorphism.
      50              :     // The concrete service (epoll_sockets or select_sockets) must be installed
      51              :     // by the context constructor before any socket operations.
      52         8875 :     auto* svc = ctx_->find_service<detail::socket_service>();
      53         8875 :     if (!svc)
      54            0 :         detail::throw_logic_error("tcp_socket::open: no socket service installed");
      55         8875 :     auto& wrapper = svc->create_impl();
      56         8875 :     impl_ = &wrapper;
      57         8875 :     std::error_code ec = svc->open_socket(wrapper);
      58              : #endif
      59         8875 :     if (ec)
      60              :     {
      61            0 :         wrapper.release();
      62            0 :         impl_ = nullptr;
      63            0 :         detail::throw_system_error(ec, "tcp_socket::open");
      64              :     }
      65              : }
      66              : 
      67              : void
      68        44556 : tcp_socket::
      69              : close()
      70              : {
      71        44556 :     if (!impl_)
      72        26830 :         return;
      73              : 
      74              :     // socket_impl has virtual release() method
      75        17726 :     impl_->release();
      76        17726 :     impl_ = nullptr;
      77              : }
      78              : 
      79              : void
      80          194 : tcp_socket::
      81              : cancel()
      82              : {
      83          194 :     if (!impl_)
      84            0 :         return;
      85              : #if BOOST_COROSIO_HAS_IOCP
      86              :     static_cast<detail::win_socket_impl*>(impl_)->get_internal()->cancel();
      87              : #else
      88              :     // socket_impl has virtual cancel() method
      89          194 :     get().cancel();
      90              : #endif
      91              : }
      92              : 
      93              : void
      94           12 : tcp_socket::
      95              : shutdown(shutdown_type what)
      96              : {
      97           12 :     if (impl_)
      98            6 :         get().shutdown(what);
      99           12 : }
     100              : 
     101              : native_handle_type
     102            0 : tcp_socket::
     103              : native_handle() const noexcept
     104              : {
     105            0 :     if (!impl_)
     106              :     {
     107              : #if BOOST_COROSIO_HAS_IOCP
     108              :         return static_cast<native_handle_type>(~0ull);  // INVALID_SOCKET
     109              : #else
     110            0 :         return -1;
     111              : #endif
     112              :     }
     113            0 :     return get().native_handle();
     114              : }
     115              : 
     116              : //------------------------------------------------------------------------------
     117              : // Socket Options
     118              : //------------------------------------------------------------------------------
     119              : 
     120              : void
     121           10 : tcp_socket::
     122              : set_no_delay(bool value)
     123              : {
     124           10 :     if (!impl_)
     125            0 :         detail::throw_logic_error("set_no_delay: socket not open");
     126           10 :     std::error_code ec = get().set_no_delay(value);
     127           10 :     if (ec)
     128            0 :         detail::throw_system_error(ec, "tcp_socket::set_no_delay");
     129           10 : }
     130              : 
     131              : bool
     132           10 : tcp_socket::
     133              : no_delay() const
     134              : {
     135           10 :     if (!impl_)
     136            0 :         detail::throw_logic_error("no_delay: socket not open");
     137           10 :     std::error_code ec;
     138           10 :     bool result = get().no_delay(ec);
     139           10 :     if (ec)
     140            0 :         detail::throw_system_error(ec, "tcp_socket::no_delay");
     141           10 :     return result;
     142              : }
     143              : 
     144              : void
     145            8 : tcp_socket::
     146              : set_keep_alive(bool value)
     147              : {
     148            8 :     if (!impl_)
     149            0 :         detail::throw_logic_error("set_keep_alive: socket not open");
     150            8 :     std::error_code ec = get().set_keep_alive(value);
     151            8 :     if (ec)
     152            0 :         detail::throw_system_error(ec, "tcp_socket::set_keep_alive");
     153            8 : }
     154              : 
     155              : bool
     156            8 : tcp_socket::
     157              : keep_alive() const
     158              : {
     159            8 :     if (!impl_)
     160            0 :         detail::throw_logic_error("keep_alive: socket not open");
     161            8 :     std::error_code ec;
     162            8 :     bool result = get().keep_alive(ec);
     163            8 :     if (ec)
     164            0 :         detail::throw_system_error(ec, "tcp_socket::keep_alive");
     165            8 :     return result;
     166              : }
     167              : 
     168              : void
     169            2 : tcp_socket::
     170              : set_receive_buffer_size(int size)
     171              : {
     172            2 :     if (!impl_)
     173            0 :         detail::throw_logic_error("set_receive_buffer_size: socket not open");
     174            2 :     std::error_code ec = get().set_receive_buffer_size(size);
     175            2 :     if (ec)
     176            0 :         detail::throw_system_error(ec, "tcp_socket::set_receive_buffer_size");
     177            2 : }
     178              : 
     179              : int
     180            6 : tcp_socket::
     181              : receive_buffer_size() const
     182              : {
     183            6 :     if (!impl_)
     184            0 :         detail::throw_logic_error("receive_buffer_size: socket not open");
     185            6 :     std::error_code ec;
     186            6 :     int result = get().receive_buffer_size(ec);
     187            6 :     if (ec)
     188            0 :         detail::throw_system_error(ec, "tcp_socket::receive_buffer_size");
     189            6 :     return result;
     190              : }
     191              : 
     192              : void
     193            2 : tcp_socket::
     194              : set_send_buffer_size(int size)
     195              : {
     196            2 :     if (!impl_)
     197            0 :         detail::throw_logic_error("set_send_buffer_size: socket not open");
     198            2 :     std::error_code ec = get().set_send_buffer_size(size);
     199            2 :     if (ec)
     200            0 :         detail::throw_system_error(ec, "tcp_socket::set_send_buffer_size");
     201            2 : }
     202              : 
     203              : int
     204            6 : tcp_socket::
     205              : send_buffer_size() const
     206              : {
     207            6 :     if (!impl_)
     208            0 :         detail::throw_logic_error("send_buffer_size: socket not open");
     209            6 :     std::error_code ec;
     210            6 :     int result = get().send_buffer_size(ec);
     211            6 :     if (ec)
     212            0 :         detail::throw_system_error(ec, "tcp_socket::send_buffer_size");
     213            6 :     return result;
     214              : }
     215              : 
     216              : void
     217            8 : tcp_socket::
     218              : set_linger(bool enabled, int timeout)
     219              : {
     220            8 :     if (!impl_)
     221            0 :         detail::throw_logic_error("set_linger: socket not open");
     222            8 :     std::error_code ec = get().set_linger(enabled, timeout);
     223            8 :     if (ec)
     224            2 :         detail::throw_system_error(ec, "tcp_socket::set_linger");
     225            6 : }
     226              : 
     227              : tcp_socket::linger_options
     228            6 : tcp_socket::
     229              : linger() const
     230              : {
     231            6 :     if (!impl_)
     232            0 :         detail::throw_logic_error("linger: socket not open");
     233            6 :     std::error_code ec;
     234            6 :     linger_options result = get().linger(ec);
     235            6 :     if (ec)
     236            0 :         detail::throw_system_error(ec, "tcp_socket::linger");
     237            6 :     return result;
     238              : }
     239              : 
     240              : endpoint
     241           42 : tcp_socket::
     242              : local_endpoint() const noexcept
     243              : {
     244           42 :     if (!impl_)
     245           10 :         return endpoint{};
     246           32 :     return get().local_endpoint();
     247              : }
     248              : 
     249              : endpoint
     250           42 : tcp_socket::
     251              : remote_endpoint() const noexcept
     252              : {
     253           42 :     if (!impl_)
     254           10 :         return endpoint{};
     255           32 :     return get().remote_endpoint();
     256              : }
     257              : 
     258              : } // namespace boost::corosio
        

Generated by: LCOV version 2.3