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_NATIVE_DETAIL_EPOLL_EPOLL_SOCKET_HPP
 
11 +
#define BOOST_COROSIO_NATIVE_DETAIL_EPOLL_EPOLL_SOCKET_HPP
 
12 +

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

 
15 +
#if BOOST_COROSIO_HAS_EPOLL
 
16 +

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

 
21 +
#include <boost/corosio/native/detail/epoll/epoll_op.hpp>
 
22 +

 
23 +
#include <memory>
 
24 +

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

 
27 +
class epoll_socket_service;
 
28 +

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

 
37 +
public:
 
38 +
    explicit epoll_socket(epoll_socket_service& svc) noexcept;
 
39 +
    ~epoll_socket() override;
 
40 +

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

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

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

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

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

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

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

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

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

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

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

 
113 +
    epoll_connect_op conn_;
 
114 +
    epoll_read_op rd_;
 
115 +
    epoll_write_op wr_;
 
116 +

 
117 +
    /// Per-descriptor state for persistent epoll registration
 
118 +
    descriptor_state desc_state_;
 
119 +

 
120 +
private:
 
121 +
    epoll_socket_service& svc_;
 
122 +
    int fd_ = -1;
 
123 +
    endpoint local_endpoint_;
 
124 +
    endpoint remote_endpoint_;
 
125 +

 
126 +
    void register_op(
 
127 +
        epoll_op& op,
 
128 +
        epoll_op*& desc_slot,
 
129 +
        bool& ready_flag,
 
130 +
        bool& cancel_flag) noexcept;
 
131 +

 
132 +
    friend struct epoll_op;
 
133 +
    friend struct epoll_connect_op;
 
134 +
};
 
135 +

 
136 +
} // namespace boost::corosio::detail
 
137 +

 
138 +
#endif // BOOST_COROSIO_HAS_EPOLL
 
139 +

 
140 +
#endif // BOOST_COROSIO_NATIVE_DETAIL_EPOLL_EPOLL_SOCKET_HPP