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 118 : tcp_acceptor::
25 118 : ~tcp_acceptor()
26 : {
27 118 : close();
28 118 : }
29 :
30 116 : tcp_acceptor::
31 : tcp_acceptor(
32 116 : capy::execution_context& ctx)
33 116 : : io_object(ctx)
34 : {
35 116 : }
36 :
37 : std::error_code
38 113 : tcp_acceptor::
39 : listen(endpoint ep, int backlog)
40 : {
41 113 : if (impl_)
42 1 : close();
43 :
44 113 : std::error_code ec;
45 :
46 : #if BOOST_COROSIO_HAS_IOCP
47 : auto& svc = ctx_->use_service<detail::win_sockets>();
48 : auto& wrapper = svc.create_acceptor_impl();
49 : impl_ = &wrapper;
50 : ec = svc.open_acceptor(*wrapper.get_internal(), ep, backlog);
51 : #else
52 : // POSIX backends use abstract acceptor_service for runtime polymorphism.
53 : // The concrete service (epoll_sockets or select_sockets) must be installed
54 : // by the context constructor before any acceptor operations.
55 113 : auto* svc = ctx_->find_service<detail::acceptor_service>();
56 113 : if (!svc)
57 : {
58 : // Should not happen with properly constructed io_context
59 0 : return make_error_code(std::errc::operation_not_supported);
60 : }
61 113 : auto& wrapper = svc->create_acceptor_impl();
62 113 : impl_ = &wrapper;
63 113 : ec = svc->open_acceptor(wrapper, ep, backlog);
64 : #endif
65 : // Both branches above define 'wrapper' as a reference to the impl
66 113 : if (ec)
67 : {
68 9 : wrapper.release();
69 9 : impl_ = nullptr;
70 : }
71 113 : return ec;
72 : }
73 :
74 : void
75 227 : tcp_acceptor::
76 : close()
77 : {
78 227 : if (!impl_)
79 123 : return;
80 :
81 : // acceptor_impl has virtual release() method
82 104 : impl_->release();
83 104 : impl_ = nullptr;
84 : }
85 :
86 : void
87 2 : tcp_acceptor::
88 : cancel()
89 : {
90 2 : if (!impl_)
91 0 : return;
92 : #if BOOST_COROSIO_HAS_IOCP
93 : static_cast<detail::win_acceptor_impl*>(impl_)->get_internal()->cancel();
94 : #else
95 : // acceptor_impl has virtual cancel() method
96 2 : get().cancel();
97 : #endif
98 : }
99 :
100 : endpoint
101 16 : tcp_acceptor::
102 : local_endpoint() const noexcept
103 : {
104 16 : if (!impl_)
105 0 : return endpoint{};
106 16 : return get().local_endpoint();
107 : }
108 :
109 : } // namespace boost::corosio
|