1  
//
1  
//
2  
// Copyright (c) 2026 Steve Gerbino
2  
// Copyright (c) 2026 Steve Gerbino
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
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)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/cppalliance/corosio
7  
// Official repository: https://github.com/cppalliance/corosio
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_COROSIO_NATIVE_DETAIL_SELECT_SELECT_SOCKET_HPP
10  
#ifndef BOOST_COROSIO_NATIVE_DETAIL_SELECT_SELECT_SOCKET_HPP
11  
#define BOOST_COROSIO_NATIVE_DETAIL_SELECT_SELECT_SOCKET_HPP
11  
#define BOOST_COROSIO_NATIVE_DETAIL_SELECT_SELECT_SOCKET_HPP
12  

12  

13  
#include <boost/corosio/detail/platform.hpp>
13  
#include <boost/corosio/detail/platform.hpp>
14  

14  

15  
#if BOOST_COROSIO_HAS_SELECT
15  
#if BOOST_COROSIO_HAS_SELECT
16  

16  

17  
#include <boost/corosio/tcp_socket.hpp>
17  
#include <boost/corosio/tcp_socket.hpp>
18  
#include <boost/capy/ex/executor_ref.hpp>
18  
#include <boost/capy/ex/executor_ref.hpp>
19  
#include <boost/corosio/detail/intrusive.hpp>
19  
#include <boost/corosio/detail/intrusive.hpp>
20  

20  

21  
#include <boost/corosio/native/detail/select/select_op.hpp>
21  
#include <boost/corosio/native/detail/select/select_op.hpp>
22  

22  

23  
#include <memory>
23  
#include <memory>
24  

24  

25  
namespace boost::corosio::detail {
25  
namespace boost::corosio::detail {
26  

26  

27  
class select_socket_service;
27  
class select_socket_service;
28  

28  

29  
/// Socket implementation for select backend.
29  
/// Socket implementation for select backend.
30  
class select_socket final
30  
class select_socket final
31  
    : public tcp_socket::implementation
31  
    : public tcp_socket::implementation
32  
    , public std::enable_shared_from_this<select_socket>
32  
    , public std::enable_shared_from_this<select_socket>
33  
    , public intrusive_list<select_socket>::node
33  
    , public intrusive_list<select_socket>::node
34  
{
34  
{
35  
    friend class select_socket_service;
35  
    friend class select_socket_service;
36  

36  

37  
public:
37  
public:
38  
    explicit select_socket(select_socket_service& svc) noexcept;
38  
    explicit select_socket(select_socket_service& svc) noexcept;
39  

39  

40  
    std::coroutine_handle<> connect(
40  
    std::coroutine_handle<> connect(
41  
        std::coroutine_handle<>,
41  
        std::coroutine_handle<>,
42  
        capy::executor_ref,
42  
        capy::executor_ref,
43  
        endpoint,
43  
        endpoint,
44  
        std::stop_token,
44  
        std::stop_token,
45  
        std::error_code*) override;
45  
        std::error_code*) override;
46  

46  

47  
    std::coroutine_handle<> read_some(
47  
    std::coroutine_handle<> read_some(
48  
        std::coroutine_handle<>,
48  
        std::coroutine_handle<>,
49  
        capy::executor_ref,
49  
        capy::executor_ref,
50  
        io_buffer_param,
50  
        io_buffer_param,
51  
        std::stop_token,
51  
        std::stop_token,
52  
        std::error_code*,
52  
        std::error_code*,
53  
        std::size_t*) override;
53  
        std::size_t*) override;
54  

54  

55  
    std::coroutine_handle<> write_some(
55  
    std::coroutine_handle<> write_some(
56  
        std::coroutine_handle<>,
56  
        std::coroutine_handle<>,
57  
        capy::executor_ref,
57  
        capy::executor_ref,
58  
        io_buffer_param,
58  
        io_buffer_param,
59  
        std::stop_token,
59  
        std::stop_token,
60  
        std::error_code*,
60  
        std::error_code*,
61  
        std::size_t*) override;
61  
        std::size_t*) override;
62  

62  

63  
    std::error_code shutdown(tcp_socket::shutdown_type what) noexcept override;
63  
    std::error_code shutdown(tcp_socket::shutdown_type what) noexcept override;
64  

64  

65  
    native_handle_type native_handle() const noexcept override
65  
    native_handle_type native_handle() const noexcept override
66  
    {
66  
    {
67  
        return fd_;
67  
        return fd_;
68  
    }
68  
    }
69  

69  

70  
    // Socket options
70  
    // Socket options
71  
    std::error_code set_no_delay(bool value) noexcept override;
71  
    std::error_code set_no_delay(bool value) noexcept override;
72  
    bool no_delay(std::error_code& ec) const noexcept override;
72  
    bool no_delay(std::error_code& ec) const noexcept override;
73  

73  

74  
    std::error_code set_keep_alive(bool value) noexcept override;
74  
    std::error_code set_keep_alive(bool value) noexcept override;
75  
    bool keep_alive(std::error_code& ec) const noexcept override;
75  
    bool keep_alive(std::error_code& ec) const noexcept override;
76  

76  

77  
    std::error_code set_receive_buffer_size(int size) noexcept override;
77  
    std::error_code set_receive_buffer_size(int size) noexcept override;
78  
    int receive_buffer_size(std::error_code& ec) const noexcept override;
78  
    int receive_buffer_size(std::error_code& ec) const noexcept override;
79  

79  

80  
    std::error_code set_send_buffer_size(int size) noexcept override;
80  
    std::error_code set_send_buffer_size(int size) noexcept override;
81  
    int send_buffer_size(std::error_code& ec) const noexcept override;
81  
    int send_buffer_size(std::error_code& ec) const noexcept override;
82  

82  

83  
    std::error_code set_linger(bool enabled, int timeout) noexcept override;
83  
    std::error_code set_linger(bool enabled, int timeout) noexcept override;
84  
    tcp_socket::linger_options
84  
    tcp_socket::linger_options
85  
    linger(std::error_code& ec) const noexcept override;
85  
    linger(std::error_code& ec) const noexcept override;
86  

86  

87  
    endpoint local_endpoint() const noexcept override
87  
    endpoint local_endpoint() const noexcept override
88  
    {
88  
    {
89  
        return local_endpoint_;
89  
        return local_endpoint_;
90  
    }
90  
    }
91  
    endpoint remote_endpoint() const noexcept override
91  
    endpoint remote_endpoint() const noexcept override
92  
    {
92  
    {
93  
        return remote_endpoint_;
93  
        return remote_endpoint_;
94  
    }
94  
    }
95  
    bool is_open() const noexcept
95  
    bool is_open() const noexcept
96  
    {
96  
    {
97  
        return fd_ >= 0;
97  
        return fd_ >= 0;
98  
    }
98  
    }
99  
    void cancel() noexcept override;
99  
    void cancel() noexcept override;
100  
    void cancel_single_op(select_op& op) noexcept;
100  
    void cancel_single_op(select_op& op) noexcept;
101  
    void close_socket() noexcept;
101  
    void close_socket() noexcept;
102  
    void set_socket(int fd) noexcept
102  
    void set_socket(int fd) noexcept
103  
    {
103  
    {
104  
        fd_ = fd;
104  
        fd_ = fd;
105  
    }
105  
    }
106  
    void set_endpoints(endpoint local, endpoint remote) noexcept
106  
    void set_endpoints(endpoint local, endpoint remote) noexcept
107  
    {
107  
    {
108  
        local_endpoint_  = local;
108  
        local_endpoint_  = local;
109  
        remote_endpoint_ = remote;
109  
        remote_endpoint_ = remote;
110  
    }
110  
    }
111  

111  

112  
    select_connect_op conn_;
112  
    select_connect_op conn_;
113  
    select_read_op rd_;
113  
    select_read_op rd_;
114  
    select_write_op wr_;
114  
    select_write_op wr_;
115  

115  

116  
private:
116  
private:
117  
    select_socket_service& svc_;
117  
    select_socket_service& svc_;
118  
    int fd_ = -1;
118  
    int fd_ = -1;
119  
    endpoint local_endpoint_;
119  
    endpoint local_endpoint_;
120  
    endpoint remote_endpoint_;
120  
    endpoint remote_endpoint_;
121  
};
121  
};
122  

122  

123  
} // namespace boost::corosio::detail
123  
} // namespace boost::corosio::detail
124  

124  

125  
#endif // BOOST_COROSIO_HAS_SELECT
125  
#endif // BOOST_COROSIO_HAS_SELECT
126  

126  

127  
#endif // BOOST_COROSIO_NATIVE_DETAIL_SELECT_SELECT_SOCKET_HPP
127  
#endif // BOOST_COROSIO_NATIVE_DETAIL_SELECT_SELECT_SOCKET_HPP