libs/corosio/src/corosio/src/tcp_acceptor.cpp

91.4% Lines (32/35) 100.0% Functions (6/6) 81.2% Branches (13/16)
libs/corosio/src/corosio/src/tcp_acceptor.cpp
Line Branch Hits 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
2/2
✓ Branch 0 taken 1 time.
✓ Branch 1 taken 112 times.
113 if (impl_)
42
1/1
✓ Branch 1 taken 1 time.
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
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 113 times.
113 if (!svc)
57 {
58 // Should not happen with properly constructed io_context
59 return make_error_code(std::errc::operation_not_supported);
60 }
61
1/1
✓ Branch 1 taken 113 times.
113 auto& wrapper = svc->create_acceptor_impl();
62 113 impl_ = &wrapper;
63
1/1
✓ Branch 1 taken 113 times.
113 ec = svc->open_acceptor(wrapper, ep, backlog);
64 #endif
65 // Both branches above define 'wrapper' as a reference to the impl
66
2/2
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 104 times.
113 if (ec)
67 {
68
1/1
✓ Branch 1 taken 9 times.
9 wrapper.release();
69 9 impl_ = nullptr;
70 }
71 113 return ec;
72 }
73
74 void
75 227 tcp_acceptor::
76 close()
77 {
78
2/2
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 104 times.
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
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!impl_)
91 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
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (!impl_)
105 return endpoint{};
106 16 return get().local_endpoint();
107 }
108
109 } // namespace boost::corosio
110