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_acceptor.hpp>
11 : #include <boost/corosio/detail/platform.hpp>
12 :
13 : #if BOOST_COROSIO_HAS_IOCP
14 : #include "src/detail/iocp/sockets.hpp"
15 : #else
16 : // POSIX backends use the abstract acceptor_service interface
17 : #include "src/detail/socket_service.hpp"
18 : #endif
19 :
20 : #include <boost/corosio/detail/except.hpp>
21 :
22 : namespace boost::corosio {
23 :
24 119 : tcp_acceptor::
25 119 : ~tcp_acceptor()
26 : {
27 119 : close();
28 119 : }
29 :
30 117 : tcp_acceptor::
31 : tcp_acceptor(
32 117 : capy::execution_context& ctx)
33 117 : : io_object(ctx)
34 : {
35 117 : }
36 :
37 : void
38 113 : tcp_acceptor::
39 : listen(endpoint ep, int backlog)
40 : {
41 113 : if (impl_)
42 0 : close();
43 :
44 : #if BOOST_COROSIO_HAS_IOCP
45 : auto& svc = ctx_->use_service<detail::win_sockets>();
46 : auto& wrapper = svc.create_acceptor_impl();
47 : impl_ = &wrapper;
48 : std::error_code ec = svc.open_acceptor(
49 : *wrapper.get_internal(), ep, backlog);
50 : #else
51 : // POSIX backends use abstract acceptor_service for runtime polymorphism.
52 : // The concrete service (epoll_sockets or select_sockets) must be installed
53 : // by the context constructor before any acceptor operations.
54 113 : auto* svc = ctx_->find_service<detail::acceptor_service>();
55 113 : if (!svc)
56 0 : detail::throw_logic_error("tcp_acceptor::listen: no acceptor service installed");
57 113 : auto& wrapper = svc->create_acceptor_impl();
58 113 : impl_ = &wrapper;
59 113 : std::error_code ec = svc->open_acceptor(wrapper, ep, backlog);
60 : #endif
61 113 : if (ec)
62 : {
63 14 : wrapper.release();
64 14 : impl_ = nullptr;
65 14 : detail::throw_system_error(ec, "tcp_acceptor::listen");
66 : }
67 99 : }
68 :
69 : void
70 241 : tcp_acceptor::
71 : close()
72 : {
73 241 : if (!impl_)
74 142 : return;
75 :
76 : // acceptor_impl has virtual release() method
77 99 : impl_->release();
78 99 : impl_ = nullptr;
79 : }
80 :
81 : void
82 2 : tcp_acceptor::
83 : cancel()
84 : {
85 2 : if (!impl_)
86 0 : return;
87 : #if BOOST_COROSIO_HAS_IOCP
88 : static_cast<detail::win_acceptor_impl*>(impl_)->get_internal()->cancel();
89 : #else
90 : // acceptor_impl has virtual cancel() method
91 2 : get().cancel();
92 : #endif
93 : }
94 :
95 : endpoint
96 14 : tcp_acceptor::
97 : local_endpoint() const noexcept
98 : {
99 14 : if (!impl_)
100 0 : return endpoint{};
101 14 : return get().local_endpoint();
102 : }
103 :
104 : } // namespace boost::corosio
|