include/boost/corosio/detail/object_pool.hpp
94.2% Lines (65 / 69)
97.5% Functions (155 / 159)
Functions (159)
Function
Calls
Lines
Blocks
boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::pool_impl>::is_pooled(boost::corosio::detail::(anonymous namespace)::pool_impl const*)
:78
24x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::self_ref_derived>::is_pooled(boost::corosio::detail::(anonymous namespace)::self_ref_derived const*)
:78
1x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::self_ref_impl>::is_pooled(boost::corosio::detail::(anonymous namespace)::self_ref_impl const*)
:78
1x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_descriptor>::is_pooled(boost::corosio::detail::epoll_descriptor const*)
:78
174x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_datagram_socket>::is_pooled(boost::corosio::detail::epoll_local_datagram_socket const*)
:78
312x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_stream_acceptor>::is_pooled(boost::corosio::detail::epoll_local_stream_acceptor const*)
:78
151x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_stream_socket>::is_pooled(boost::corosio::detail::epoll_local_stream_socket const*)
:78
407x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_acceptor>::is_pooled(boost::corosio::detail::epoll_tcp_acceptor const*)
:78
2072x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_socket>::is_pooled(boost::corosio::detail::epoll_tcp_socket const*)
:78
17316x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_udp_socket>::is_pooled(boost::corosio::detail::epoll_udp_socket const*)
:78
369x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_random_access_file>::is_pooled(boost::corosio::detail::posix_random_access_file const*)
:78
488x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_resolver>::is_pooled(boost::corosio::detail::posix_resolver const*)
:78
220x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_signal>::is_pooled(boost::corosio::detail::posix_signal const*)
:78
6880x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_stream_file>::is_pooled(boost::corosio::detail::posix_stream_file const*)
:78
1454x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_descriptor>::is_pooled(boost::corosio::detail::select_descriptor const*)
:78
171x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_local_datagram_socket>::is_pooled(boost::corosio::detail::select_local_datagram_socket const*)
:78
292x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_local_stream_acceptor>::is_pooled(boost::corosio::detail::select_local_stream_acceptor const*)
:78
144x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_local_stream_socket>::is_pooled(boost::corosio::detail::select_local_stream_socket const*)
:78
378x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_acceptor>::is_pooled(boost::corosio::detail::select_tcp_acceptor const*)
:78
1906x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_socket>::is_pooled(boost::corosio::detail::select_tcp_socket const*)
:78
12987x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_udp_socket>::is_pooled(boost::corosio::detail::select_udp_socket const*)
:78
442x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::timer::implementation>::is_pooled(boost::corosio::detail::timer::implementation const*)
:78
40795x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::pool_impl>::adopt(boost::corosio::detail::(anonymous namespace)::pool_impl*)
:102
10x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::self_ref_derived>::adopt(boost::corosio::detail::(anonymous namespace)::self_ref_derived*)
:102
1x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::self_ref_impl>::adopt(boost::corosio::detail::(anonymous namespace)::self_ref_impl*)
:102
1x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_descriptor>::adopt(boost::corosio::detail::epoll_descriptor*)
:102
71x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_datagram_socket>::adopt(boost::corosio::detail::epoll_local_datagram_socket*)
:102
137x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_stream_acceptor>::adopt(boost::corosio::detail::epoll_local_stream_acceptor*)
:102
57x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_stream_socket>::adopt(boost::corosio::detail::epoll_local_stream_socket*)
:102
175x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_acceptor>::adopt(boost::corosio::detail::epoll_tcp_acceptor*)
:102
874x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_socket>::adopt(boost::corosio::detail::epoll_tcp_socket*)
:102
2481x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_udp_socket>::adopt(boost::corosio::detail::epoll_udp_socket*)
:102
167x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_random_access_file>::adopt(boost::corosio::detail::posix_random_access_file*)
:102
244x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_resolver>::adopt(boost::corosio::detail::posix_resolver*)
:102
78x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_signal>::adopt(boost::corosio::detail::posix_signal*)
:102
3404x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_stream_file>::adopt(boost::corosio::detail::posix_stream_file*)
:102
695x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_descriptor>::adopt(boost::corosio::detail::select_descriptor*)
:102
69x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_local_datagram_socket>::adopt(boost::corosio::detail::select_local_datagram_socket*)
:102
128x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_local_stream_acceptor>::adopt(boost::corosio::detail::select_local_stream_acceptor*)
:102
54x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_local_stream_socket>::adopt(boost::corosio::detail::select_local_stream_socket*)
:102
165x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_acceptor>::adopt(boost::corosio::detail::select_tcp_acceptor*)
:102
791x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_socket>::adopt(boost::corosio::detail::select_tcp_socket*)
:102
2199x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_udp_socket>::adopt(boost::corosio::detail::select_udp_socket*)
:102
204x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::timer::implementation>::adopt(boost::corosio::detail::timer::implementation*)
:102
20399x
85.7%
79.0%
boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::pool_impl>::remove(boost::corosio::detail::(anonymous namespace)::pool_impl*)
:129
3x
83.3%
88.0%
boost::corosio::detail::object_pool<boost::corosio::detail::timer::implementation>::remove(boost::corosio::detail::timer::implementation*)
:129
18490x
83.3%
88.0%
boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::pool_impl>::~object_pool()
:151
8x
100.0%
74.0%
boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::self_ref_derived>::~object_pool()
:151
1x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::self_ref_impl>::~object_pool()
:151
1x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_descriptor>::~object_pool()
:151
59x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_datagram_socket>::~object_pool()
:151
82x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_stream_acceptor>::~object_pool()
:151
52x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_stream_socket>::~object_pool()
:151
115x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_acceptor>::~object_pool()
:151
506x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_socket>::~object_pool()
:151
720x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_udp_socket>::~object_pool()
:151
113x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_random_access_file>::~object_pool()
:151
189x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_resolver>::~object_pool()
:151
77x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_signal>::~object_pool()
:151
583x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_stream_file>::~object_pool()
:151
639x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_descriptor>::~object_pool()
:151
58x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_local_datagram_socket>::~object_pool()
:151
77x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_local_stream_acceptor>::~object_pool()
:151
49x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_local_stream_socket>::~object_pool()
:151
108x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_acceptor>::~object_pool()
:151
424x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_socket>::~object_pool()
:151
491x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_udp_socket>::~object_pool()
:151
152x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::timer::implementation>::~object_pool()
:151
4413x
100.0%
68.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_descriptor>::object_pool()
:164
59x
100.0%
100.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_datagram_socket>::object_pool()
:164
82x
100.0%
100.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_stream_acceptor>::object_pool()
:164
52x
100.0%
100.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_stream_socket>::object_pool()
:164
115x
100.0%
100.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_acceptor>::object_pool()
:164
506x
100.0%
100.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_socket>::object_pool()
:164
720x
100.0%
100.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_udp_socket>::object_pool()
:164
113x
100.0%
100.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_random_access_file>::object_pool()
:164
189x
100.0%
100.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_resolver>::object_pool()
:164
77x
100.0%
100.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_signal>::object_pool()
:164
583x
100.0%
100.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_stream_file>::object_pool()
:164
639x
100.0%
100.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_descriptor>::object_pool()
:164
58x
100.0%
100.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_local_datagram_socket>::object_pool()
:164
77x
100.0%
100.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_local_stream_acceptor>::object_pool()
:164
49x
100.0%
100.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_local_stream_socket>::object_pool()
:164
108x
100.0%
100.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_acceptor>::object_pool()
:164
424x
100.0%
100.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_socket>::object_pool()
:164
491x
100.0%
100.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_udp_socket>::object_pool()
:164
152x
100.0%
100.0%
boost::corosio::detail::object_pool<boost::corosio::detail::timer::implementation>::object_pool()
:164
4413x
100.0%
100.0%
boost::corosio::detail::(anonymous namespace)::pool_impl* boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::pool_impl>::acquire<>()
:190
13x
100.0%
74.0%
boost::corosio::detail::(anonymous namespace)::self_ref_derived* boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::self_ref_derived>::acquire<>()
:190
1x
71.4%
31.0%
boost::corosio::detail::(anonymous namespace)::self_ref_impl* boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::self_ref_impl>::acquire<>()
:190
1x
71.4%
31.0%
boost::corosio::detail::epoll_descriptor* boost::corosio::detail::object_pool<boost::corosio::detail::epoll_descriptor>::acquire<boost::corosio::detail::epoll_descriptor_service&>(boost::corosio::detail::epoll_descriptor_service&)
:190
103x
100.0%
75.0%
boost::corosio::detail::epoll_local_datagram_socket* boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_datagram_socket>::acquire<boost::corosio::detail::epoll_local_datagram_service&>(boost::corosio::detail::epoll_local_datagram_service&)
:190
175x
100.0%
75.0%
boost::corosio::detail::epoll_local_stream_acceptor* boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_stream_acceptor>::acquire<boost::corosio::detail::epoll_local_stream_acceptor_service&>(boost::corosio::detail::epoll_local_stream_acceptor_service&)
:190
94x
100.0%
75.0%
boost::corosio::detail::epoll_local_stream_socket* boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_stream_socket>::acquire<boost::corosio::detail::epoll_local_stream_service&>(boost::corosio::detail::epoll_local_stream_service&)
:190
232x
100.0%
75.0%
boost::corosio::detail::epoll_tcp_acceptor* boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_acceptor>::acquire<boost::corosio::detail::epoll_tcp_acceptor_service&>(boost::corosio::detail::epoll_tcp_acceptor_service&)
:190
1198x
100.0%
75.0%
boost::corosio::detail::epoll_tcp_socket* boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_socket>::acquire<boost::corosio::detail::epoll_tcp_service&>(boost::corosio::detail::epoll_tcp_service&)
:190
14835x
100.0%
75.0%
boost::corosio::detail::epoll_udp_socket* boost::corosio::detail::object_pool<boost::corosio::detail::epoll_udp_socket>::acquire<boost::corosio::detail::epoll_udp_service&>(boost::corosio::detail::epoll_udp_service&)
:190
202x
100.0%
75.0%
boost::corosio::detail::posix_random_access_file* boost::corosio::detail::object_pool<boost::corosio::detail::posix_random_access_file>::acquire<boost::corosio::detail::posix_random_access_file_service&>(boost::corosio::detail::posix_random_access_file_service&)
:190
244x
71.4%
32.0%
boost::corosio::detail::posix_resolver* boost::corosio::detail::object_pool<boost::corosio::detail::posix_resolver>::acquire<boost::corosio::detail::posix_resolver_service&>(boost::corosio::detail::posix_resolver_service&)
:190
142x
100.0%
75.0%
boost::corosio::detail::posix_signal* boost::corosio::detail::object_pool<boost::corosio::detail::posix_signal>::acquire<boost::corosio::detail::posix_signal_service&>(boost::corosio::detail::posix_signal_service&)
:190
3476x
100.0%
75.0%
boost::corosio::detail::posix_stream_file* boost::corosio::detail::object_pool<boost::corosio::detail::posix_stream_file>::acquire<boost::corosio::detail::posix_stream_file_service&>(boost::corosio::detail::posix_stream_file_service&)
:190
759x
100.0%
75.0%
boost::corosio::detail::select_descriptor* boost::corosio::detail::object_pool<boost::corosio::detail::select_descriptor>::acquire<boost::corosio::detail::select_descriptor_service&>(boost::corosio::detail::select_descriptor_service&)
:190
102x
100.0%
75.0%
boost::corosio::detail::select_local_datagram_socket* boost::corosio::detail::object_pool<boost::corosio::detail::select_local_datagram_socket>::acquire<boost::corosio::detail::select_local_datagram_service&>(boost::corosio::detail::select_local_datagram_service&)
:190
164x
100.0%
75.0%
boost::corosio::detail::select_local_stream_acceptor* boost::corosio::detail::object_pool<boost::corosio::detail::select_local_stream_acceptor>::acquire<boost::corosio::detail::select_local_stream_acceptor_service&>(boost::corosio::detail::select_local_stream_acceptor_service&)
:190
90x
100.0%
75.0%
boost::corosio::detail::select_local_stream_socket* boost::corosio::detail::object_pool<boost::corosio::detail::select_local_stream_socket>::acquire<boost::corosio::detail::select_local_stream_service&>(boost::corosio::detail::select_local_stream_service&)
:190
213x
100.0%
75.0%
boost::corosio::detail::select_tcp_acceptor* boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_acceptor>::acquire<boost::corosio::detail::select_tcp_acceptor_service&>(boost::corosio::detail::select_tcp_acceptor_service&)
:190
1115x
100.0%
75.0%
boost::corosio::detail::select_tcp_socket* boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_socket>::acquire<boost::corosio::detail::select_tcp_service&>(boost::corosio::detail::select_tcp_service&)
:190
10788x
100.0%
75.0%
boost::corosio::detail::select_udp_socket* boost::corosio::detail::object_pool<boost::corosio::detail::select_udp_socket>::acquire<boost::corosio::detail::select_udp_service&>(boost::corosio::detail::select_udp_service&)
:190
238x
100.0%
75.0%
boost::corosio::detail::timer::implementation* boost::corosio::detail::object_pool<boost::corosio::detail::timer::implementation>::acquire<boost::corosio::detail::timer_service&>(boost::corosio::detail::timer_service&)
:190
5657x
100.0%
75.0%
boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::pool_impl>::recycle(boost::corosio::detail::(anonymous namespace)::pool_impl*)
:245
11x
86.7%
71.0%
boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::self_ref_derived>::recycle(boost::corosio::detail::(anonymous namespace)::self_ref_derived*)
:245
0
0.0%
0.0%
boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::self_ref_impl>::recycle(boost::corosio::detail::(anonymous namespace)::self_ref_impl*)
:245
0
0.0%
0.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_descriptor>::recycle(boost::corosio::detail::epoll_descriptor*)
:245
103x
86.7%
71.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_datagram_socket>::recycle(boost::corosio::detail::epoll_local_datagram_socket*)
:245
175x
86.7%
71.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_stream_acceptor>::recycle(boost::corosio::detail::epoll_local_stream_acceptor*)
:245
94x
86.7%
71.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_stream_socket>::recycle(boost::corosio::detail::epoll_local_stream_socket*)
:245
232x
86.7%
71.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_acceptor>::recycle(boost::corosio::detail::epoll_tcp_acceptor*)
:245
1198x
86.7%
71.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_socket>::recycle(boost::corosio::detail::epoll_tcp_socket*)
:245
14835x
86.7%
71.0%
boost::corosio::detail::object_pool<boost::corosio::detail::epoll_udp_socket>::recycle(boost::corosio::detail::epoll_udp_socket*)
:245
202x
86.7%
71.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_random_access_file>::recycle(boost::corosio::detail::posix_random_access_file*)
:245
244x
86.7%
71.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_resolver>::recycle(boost::corosio::detail::posix_resolver*)
:245
142x
86.7%
71.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_signal>::recycle(boost::corosio::detail::posix_signal*)
:245
3476x
86.7%
71.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_stream_file>::recycle(boost::corosio::detail::posix_stream_file*)
:245
759x
86.7%
71.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_descriptor>::recycle(boost::corosio::detail::select_descriptor*)
:245
102x
86.7%
71.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_local_datagram_socket>::recycle(boost::corosio::detail::select_local_datagram_socket*)
:245
164x
86.7%
71.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_local_stream_acceptor>::recycle(boost::corosio::detail::select_local_stream_acceptor*)
:245
90x
86.7%
71.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_local_stream_socket>::recycle(boost::corosio::detail::select_local_stream_socket*)
:245
213x
86.7%
71.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_acceptor>::recycle(boost::corosio::detail::select_tcp_acceptor*)
:245
1115x
86.7%
71.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_socket>::recycle(boost::corosio::detail::select_tcp_socket*)
:245
10788x
86.7%
71.0%
boost::corosio::detail::object_pool<boost::corosio::detail::select_udp_socket>::recycle(boost::corosio::detail::select_udp_socket*)
:245
238x
86.7%
71.0%
boost::corosio::detail::object_pool<boost::corosio::detail::timer::implementation>::recycle(boost::corosio::detail::timer::implementation*)
:245
1906x
73.3%
64.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::pool_impl>::shutdown<boost::corosio::detail::object_pool_test::run()::{lambda(boost::corosio::detail::(anonymous namespace)::pool_impl*)#1}>(boost::corosio::detail::object_pool_test::run()::{lambda(boost::corosio::detail::(anonymous namespace)::pool_impl*)#1}&&)
:292
1x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::pool_impl>::shutdown<boost::corosio::detail::object_pool_test::run()::{lambda(boost::corosio::detail::(anonymous namespace)::pool_impl*)#2}>(boost::corosio::detail::object_pool_test::run()::{lambda(boost::corosio::detail::(anonymous namespace)::pool_impl*)#2}&&)
:292
1x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::pool_impl>::shutdown<boost::corosio::detail::object_pool_test::run()::{lambda(boost::corosio::detail::(anonymous namespace)::pool_impl*)#3}>(boost::corosio::detail::object_pool_test::run()::{lambda(boost::corosio::detail::(anonymous namespace)::pool_impl*)#3}&&)
:292
1x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::self_ref_derived>::shutdown<boost::corosio::detail::object_pool_test::run()::{lambda(boost::corosio::detail::(anonymous namespace)::self_ref_derived*)#1}>(boost::corosio::detail::object_pool_test::run()::{lambda(boost::corosio::detail::(anonymous namespace)::self_ref_derived*)#1}&&)
:292
1x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::(anonymous namespace)::self_ref_impl>::shutdown<boost::corosio::detail::object_pool_test::run()::{lambda(boost::corosio::detail::(anonymous namespace)::self_ref_impl*)#1}>(boost::corosio::detail::object_pool_test::run()::{lambda(boost::corosio::detail::(anonymous namespace)::self_ref_impl*)#1}&&)
:292
1x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::epoll_descriptor>::shutdown<boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::epoll_descriptor_service, boost::corosio::detail::epoll_traits, boost::corosio::detail::epoll_descriptor>::shutdown()::{lambda(boost::corosio::detail::epoll_descriptor*)#1}>(boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::epoll_descriptor_service, boost::corosio::detail::epoll_traits, boost::corosio::detail::epoll_descriptor>::shutdown()::{lambda(boost::corosio::detail::epoll_descriptor*)#1}&&)
:292
59x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_datagram_socket>::shutdown<boost::corosio::detail::reactor_socket_service<boost::corosio::detail::epoll_local_datagram_service, boost::corosio::detail::local_datagram_service, boost::corosio::detail::epoll_scheduler, boost::corosio::detail::epoll_local_datagram_socket>::shutdown()::{lambda(boost::corosio::detail::epoll_local_datagram_socket*)#1}>(boost::corosio::detail::reactor_socket_service<boost::corosio::detail::epoll_local_datagram_service, boost::corosio::detail::local_datagram_service, boost::corosio::detail::epoll_scheduler, boost::corosio::detail::epoll_local_datagram_socket>::shutdown()::{lambda(boost::corosio::detail::epoll_local_datagram_socket*)#1}&&)
:292
82x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_stream_acceptor>::shutdown<boost::corosio::detail::reactor_acceptor_service<boost::corosio::detail::epoll_local_stream_acceptor_service, boost::corosio::detail::local_stream_acceptor_service, boost::corosio::detail::epoll_scheduler, boost::corosio::detail::epoll_local_stream_acceptor, boost::corosio::detail::epoll_local_stream_service>::shutdown()::{lambda(boost::corosio::detail::epoll_local_stream_acceptor*)#1}>(boost::corosio::detail::reactor_acceptor_service<boost::corosio::detail::epoll_local_stream_acceptor_service, boost::corosio::detail::local_stream_acceptor_service, boost::corosio::detail::epoll_scheduler, boost::corosio::detail::epoll_local_stream_acceptor, boost::corosio::detail::epoll_local_stream_service>::shutdown()::{lambda(boost::corosio::detail::epoll_local_stream_acceptor*)#1}&&)
:292
52x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_stream_socket>::shutdown<boost::corosio::detail::reactor_socket_service<boost::corosio::detail::epoll_local_stream_service, boost::corosio::detail::local_stream_service, boost::corosio::detail::epoll_scheduler, boost::corosio::detail::epoll_local_stream_socket>::shutdown()::{lambda(boost::corosio::detail::epoll_local_stream_socket*)#1}>(boost::corosio::detail::reactor_socket_service<boost::corosio::detail::epoll_local_stream_service, boost::corosio::detail::local_stream_service, boost::corosio::detail::epoll_scheduler, boost::corosio::detail::epoll_local_stream_socket>::shutdown()::{lambda(boost::corosio::detail::epoll_local_stream_socket*)#1}&&)
:292
115x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_acceptor>::shutdown<boost::corosio::detail::reactor_acceptor_service<boost::corosio::detail::epoll_tcp_acceptor_service, boost::corosio::detail::tcp_acceptor_service, boost::corosio::detail::epoll_scheduler, boost::corosio::detail::epoll_tcp_acceptor, boost::corosio::detail::epoll_tcp_service>::shutdown()::{lambda(boost::corosio::detail::epoll_tcp_acceptor*)#1}>(boost::corosio::detail::reactor_acceptor_service<boost::corosio::detail::epoll_tcp_acceptor_service, boost::corosio::detail::tcp_acceptor_service, boost::corosio::detail::epoll_scheduler, boost::corosio::detail::epoll_tcp_acceptor, boost::corosio::detail::epoll_tcp_service>::shutdown()::{lambda(boost::corosio::detail::epoll_tcp_acceptor*)#1}&&)
:292
506x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_socket>::shutdown<boost::corosio::detail::reactor_socket_service<boost::corosio::detail::epoll_tcp_service, boost::corosio::detail::tcp_service, boost::corosio::detail::epoll_scheduler, boost::corosio::detail::epoll_tcp_socket>::shutdown()::{lambda(boost::corosio::detail::epoll_tcp_socket*)#1}>(boost::corosio::detail::reactor_socket_service<boost::corosio::detail::epoll_tcp_service, boost::corosio::detail::tcp_service, boost::corosio::detail::epoll_scheduler, boost::corosio::detail::epoll_tcp_socket>::shutdown()::{lambda(boost::corosio::detail::epoll_tcp_socket*)#1}&&)
:292
720x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::epoll_udp_socket>::shutdown<boost::corosio::detail::reactor_socket_service<boost::corosio::detail::epoll_udp_service, boost::corosio::detail::udp_service, boost::corosio::detail::epoll_scheduler, boost::corosio::detail::epoll_udp_socket>::shutdown()::{lambda(boost::corosio::detail::epoll_udp_socket*)#1}>(boost::corosio::detail::reactor_socket_service<boost::corosio::detail::epoll_udp_service, boost::corosio::detail::udp_service, boost::corosio::detail::epoll_scheduler, boost::corosio::detail::epoll_udp_socket>::shutdown()::{lambda(boost::corosio::detail::epoll_udp_socket*)#1}&&)
:292
113x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::posix_random_access_file>::shutdown<boost::corosio::detail::posix_random_access_file_service::shutdown()::{lambda(boost::corosio::detail::posix_random_access_file*)#1}>(boost::corosio::detail::posix_random_access_file_service::shutdown()::{lambda(boost::corosio::detail::posix_random_access_file*)#1}&&)
:292
189x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::posix_resolver>::shutdown<boost::corosio::detail::posix_resolver_service::shutdown()::{lambda(boost::corosio::detail::posix_resolver*)#1}>(boost::corosio::detail::posix_resolver_service::shutdown()::{lambda(boost::corosio::detail::posix_resolver*)#1}&&)
:292
77x
91.7%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::posix_signal>::shutdown<boost::corosio::detail::posix_signal_service::shutdown()::{lambda(boost::corosio::detail::posix_signal*)#1}>(boost::corosio::detail::posix_signal_service::shutdown()::{lambda(boost::corosio::detail::posix_signal*)#1}&&)
:292
583x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::posix_stream_file>::shutdown<boost::corosio::detail::posix_stream_file_service::shutdown()::{lambda(boost::corosio::detail::posix_stream_file*)#1}>(boost::corosio::detail::posix_stream_file_service::shutdown()::{lambda(boost::corosio::detail::posix_stream_file*)#1}&&)
:292
639x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::select_descriptor>::shutdown<boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::select_descriptor_service, boost::corosio::detail::select_traits, boost::corosio::detail::select_descriptor>::shutdown()::{lambda(boost::corosio::detail::select_descriptor*)#1}>(boost::corosio::detail::reactor_descriptor_service<boost::corosio::detail::select_descriptor_service, boost::corosio::detail::select_traits, boost::corosio::detail::select_descriptor>::shutdown()::{lambda(boost::corosio::detail::select_descriptor*)#1}&&)
:292
58x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::select_local_datagram_socket>::shutdown<boost::corosio::detail::reactor_socket_service<boost::corosio::detail::select_local_datagram_service, boost::corosio::detail::local_datagram_service, boost::corosio::detail::select_scheduler, boost::corosio::detail::select_local_datagram_socket>::shutdown()::{lambda(boost::corosio::detail::select_local_datagram_socket*)#1}>(boost::corosio::detail::reactor_socket_service<boost::corosio::detail::select_local_datagram_service, boost::corosio::detail::local_datagram_service, boost::corosio::detail::select_scheduler, boost::corosio::detail::select_local_datagram_socket>::shutdown()::{lambda(boost::corosio::detail::select_local_datagram_socket*)#1}&&)
:292
77x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::select_local_stream_acceptor>::shutdown<boost::corosio::detail::reactor_acceptor_service<boost::corosio::detail::select_local_stream_acceptor_service, boost::corosio::detail::local_stream_acceptor_service, boost::corosio::detail::select_scheduler, boost::corosio::detail::select_local_stream_acceptor, boost::corosio::detail::select_local_stream_service>::shutdown()::{lambda(boost::corosio::detail::select_local_stream_acceptor*)#1}>(boost::corosio::detail::reactor_acceptor_service<boost::corosio::detail::select_local_stream_acceptor_service, boost::corosio::detail::local_stream_acceptor_service, boost::corosio::detail::select_scheduler, boost::corosio::detail::select_local_stream_acceptor, boost::corosio::detail::select_local_stream_service>::shutdown()::{lambda(boost::corosio::detail::select_local_stream_acceptor*)#1}&&)
:292
49x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::select_local_stream_socket>::shutdown<boost::corosio::detail::reactor_socket_service<boost::corosio::detail::select_local_stream_service, boost::corosio::detail::local_stream_service, boost::corosio::detail::select_scheduler, boost::corosio::detail::select_local_stream_socket>::shutdown()::{lambda(boost::corosio::detail::select_local_stream_socket*)#1}>(boost::corosio::detail::reactor_socket_service<boost::corosio::detail::select_local_stream_service, boost::corosio::detail::local_stream_service, boost::corosio::detail::select_scheduler, boost::corosio::detail::select_local_stream_socket>::shutdown()::{lambda(boost::corosio::detail::select_local_stream_socket*)#1}&&)
:292
108x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_acceptor>::shutdown<boost::corosio::detail::reactor_acceptor_service<boost::corosio::detail::select_tcp_acceptor_service, boost::corosio::detail::tcp_acceptor_service, boost::corosio::detail::select_scheduler, boost::corosio::detail::select_tcp_acceptor, boost::corosio::detail::select_tcp_service>::shutdown()::{lambda(boost::corosio::detail::select_tcp_acceptor*)#1}>(boost::corosio::detail::reactor_acceptor_service<boost::corosio::detail::select_tcp_acceptor_service, boost::corosio::detail::tcp_acceptor_service, boost::corosio::detail::select_scheduler, boost::corosio::detail::select_tcp_acceptor, boost::corosio::detail::select_tcp_service>::shutdown()::{lambda(boost::corosio::detail::select_tcp_acceptor*)#1}&&)
:292
424x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_socket>::shutdown<boost::corosio::detail::reactor_socket_service<boost::corosio::detail::select_tcp_service, boost::corosio::detail::tcp_service, boost::corosio::detail::select_scheduler, boost::corosio::detail::select_tcp_socket>::shutdown()::{lambda(boost::corosio::detail::select_tcp_socket*)#1}>(boost::corosio::detail::reactor_socket_service<boost::corosio::detail::select_tcp_service, boost::corosio::detail::tcp_service, boost::corosio::detail::select_scheduler, boost::corosio::detail::select_tcp_socket>::shutdown()::{lambda(boost::corosio::detail::select_tcp_socket*)#1}&&)
:292
491x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::select_udp_socket>::shutdown<boost::corosio::detail::reactor_socket_service<boost::corosio::detail::select_udp_service, boost::corosio::detail::udp_service, boost::corosio::detail::select_scheduler, boost::corosio::detail::select_udp_socket>::shutdown()::{lambda(boost::corosio::detail::select_udp_socket*)#1}>(boost::corosio::detail::reactor_socket_service<boost::corosio::detail::select_udp_service, boost::corosio::detail::udp_service, boost::corosio::detail::select_scheduler, boost::corosio::detail::select_udp_socket>::shutdown()::{lambda(boost::corosio::detail::select_udp_socket*)#1}&&)
:292
152x
100.0%
75.0%
void boost::corosio::detail::object_pool<boost::corosio::detail::timer::implementation>::shutdown<boost::corosio::detail::timer_service::shutdown()::{lambda(boost::corosio::detail::timer::implementation*)#1}>(boost::corosio::detail::timer_service::shutdown()::{lambda(boost::corosio::detail::timer::implementation*)#1}&&)
:292
8826x
100.0%
75.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_resolver>::shutdown<boost::corosio::detail::posix_resolver_service::shutdown()::{lambda(boost::corosio::detail::posix_resolver*)#1}>(boost::corosio::detail::posix_resolver_service::shutdown()::{lambda(boost::corosio::detail::posix_resolver*)#1}&&)::{lambda(boost::corosio::detail::posix_resolver*)#1}::operator()(boost::corosio::detail::posix_resolver*) const
:300
3x
100.0%
100.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_signal>::shutdown<boost::corosio::detail::posix_signal_service::shutdown()::{lambda(boost::corosio::detail::posix_signal*)#1}>(boost::corosio::detail::posix_signal_service::shutdown()::{lambda(boost::corosio::detail::posix_signal*)#1}&&)::{lambda(boost::corosio::detail::posix_signal*)#1}::operator()(boost::corosio::detail::posix_signal*) const
:300
0
0.0%
0.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_resolver>::shutdown<boost::corosio::detail::posix_resolver_service::shutdown()::{lambda(boost::corosio::detail::posix_resolver*)#1}>(boost::corosio::detail::posix_resolver_service::shutdown()::{lambda(boost::corosio::detail::posix_resolver*)#1}&&)::{lambda(boost::corosio::detail::posix_resolver*)#2}::operator()(boost::corosio::detail::posix_resolver*) const
:303
3x
100.0%
100.0%
boost::corosio::detail::object_pool<boost::corosio::detail::posix_signal>::shutdown<boost::corosio::detail::posix_signal_service::shutdown()::{lambda(boost::corosio::detail::posix_signal*)#1}>(boost::corosio::detail::posix_signal_service::shutdown()::{lambda(boost::corosio::detail::posix_signal*)#1}&&)::{lambda(boost::corosio::detail::posix_signal*)#2}::operator()(boost::corosio::detail::posix_signal*) const
:303
0
0.0%
0.0%
| Line | TLA | Hits | Source Code |
|---|---|---|---|
| 1 | // | ||
| 2 | // Copyright (c) 2025 Steve Gerbino (steve@gerbino.co) | ||
| 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_DETAIL_OBJECT_POOL_HPP | ||
| 11 | #define BOOST_COROSIO_DETAIL_OBJECT_POOL_HPP | ||
| 12 | |||
| 13 | #include <boost/corosio/detail/config.hpp> | ||
| 14 | #include <boost/corosio/detail/intrusive.hpp> | ||
| 15 | #include <boost/corosio/detail/object_ref.hpp> | ||
| 16 | #include <atomic> | ||
| 17 | #include <cstddef> | ||
| 18 | #include <initializer_list> | ||
| 19 | #include <limits> | ||
| 20 | #include <mutex> | ||
| 21 | #include <utility> | ||
| 22 | #include <vector> | ||
| 23 | |||
| 24 | namespace boost::corosio::detail { | ||
| 25 | |||
| 26 | /** Per-service recycling pool for I/O implementations. | ||
| 27 | |||
| 28 | Replaces per-impl `shared_ptr` ownership: a service news an impl | ||
| 29 | once, then `recycle()` (the impl's `retire()` action) parks | ||
| 30 | it on the free list and `acquire()` hands it back out, so steady-state | ||
| 31 | construct/destroy allocates nothing. Unbounded; memory is released | ||
| 32 | only on pool destruction. Debug poisoning, where an impl does it, | ||
| 33 | happens in that impl's `retire()`, not here (the pool cannot know | ||
| 34 | which bytes are resettable). | ||
| 35 | |||
| 36 | A service tears down its impls by calling `shutdown()`, which | ||
| 37 | enters shutting-down mode and visits every live impl in one | ||
| 38 | critical section; subsequent zero-ref crossings delete instead of | ||
| 39 | recycling. | ||
| 40 | |||
| 41 | `adopt()` and `remove()` are protected ownership-transfer | ||
| 42 | primitives for sanctioned extensions — a derived pool exposing | ||
| 43 | them to a caller that tracks some of its live impls through its | ||
| 44 | own structure instead of this pool's `live_` list (the timer | ||
| 45 | service, via its expiry heap) — rather than part of the public | ||
| 46 | surface every ordinary service uses. | ||
| 47 | |||
| 48 | @par Thread Safety | ||
| 49 | Distinct objects: Safe. Shared objects: Safe; all operations lock | ||
| 50 | an internal mutex. | ||
| 51 | */ | ||
| 52 | template<class Impl> | ||
| 53 | class object_pool | ||
| 54 | { | ||
| 55 | std::mutex mutex_; | ||
| 56 | intrusive_list<Impl> live_; | ||
| 57 | intrusive_list<Impl> free_; | ||
| 58 | bool shutting_down_ = false; | ||
| 59 | |||
| 60 | /** Marks `refs_` on an impl currently parked in `free_`. | ||
| 61 | |||
| 62 | `intrusive_list::remove()` cannot distinguish "linked in | ||
| 63 | `free_`" from "linked in `live_`" by inspecting the node | ||
| 64 | alone — both lists share one `next_`/`prev_` pair per impl — | ||
| 65 | so `recycle()` cannot safely call `live_.remove()` on an impl | ||
| 66 | it does not already know is live. Stamping this sentinel into | ||
| 67 | `refs_` the moment an impl joins `free_`, and checking it | ||
| 68 | before touching either list, is what lets `recycle()` and | ||
| 69 | `remove()` tell the two cases apart in every build mode, not | ||
| 70 | just under asserts. `acquire()` always overwrites it with 1 | ||
| 71 | before the impl is usable again. | ||
| 72 | */ | ||
| 73 | static constexpr std::size_t pooled_sentinel = pooled_refs; | ||
| 74 | |||
| 75 | /// Check whether @p impl is parked in `free_` (`refs_` reads the | ||
| 76 | /// sentinel). Callers must check this before any list operation — | ||
| 77 | /// see the class-level comment on `pooled_sentinel`. | ||
| 78 | 86984x | static bool is_pooled(Impl const* impl) noexcept | |
| 79 | { | ||
| 80 | 86984x | return impl->refs_.load(std::memory_order_relaxed) == | |
| 81 | 86984x | pooled_sentinel; | |
| 82 | } | ||
| 83 | |||
| 84 | protected: | ||
| 85 | /** Track a fresh or reset impl as live. | ||
| 86 | |||
| 87 | @pre @p impl is not parked in `free_` (`refs_` must not read | ||
| 88 | `pooled_sentinel`). The same list-corruption hazard | ||
| 89 | `recycle()`'s class-level comment documents applies here: a | ||
| 90 | free-listed impl pushed onto `live_` directly, bypassing | ||
| 91 | `acquire()`, would end up linked in both lists through one shared | ||
| 92 | `next_`/`prev_` pair. | ||
| 93 | |||
| 94 | @pre The caller is not racing `shutdown()`. Every caller adopts | ||
| 95 | while constructing an object (`acquire()`, or a derived pool's | ||
| 96 | cache handing a parked impl back out), and construction is | ||
| 97 | expected to stop before the service's own `shutdown()` runs; | ||
| 98 | this is checked only in debug builds because the failure mode | ||
| 99 | is a silently orphaned impl (no close callback), not memory | ||
| 100 | corruption. | ||
| 101 | */ | ||
| 102 | 32404x | void adopt(Impl* impl) | |
| 103 | { | ||
| 104 | 32404x | std::lock_guard lock(mutex_); | |
| 105 | 32404x | if (is_pooled(impl)) | |
| 106 | { | ||
| 107 | ✗ | BOOST_COROSIO_ASSERT(false); | |
| 108 | return; | ||
| 109 | } | ||
| 110 | 32404x | BOOST_COROSIO_ASSERT(!shutting_down_); | |
| 111 | 32404x | live_.push_back(impl); | |
| 112 | 32404x | } | |
| 113 | |||
| 114 | /** Unlink a live impl without recycling (ownership transfer). | ||
| 115 | |||
| 116 | Used by a caller that is taking an impl out of this pool's | ||
| 117 | bookkeeping entirely (a thread-local cache slot, a direct | ||
| 118 | delete during shutdown) rather than parking it on `free_`. | ||
| 119 | |||
| 120 | @pre @p impl is not parked in `free_` (`refs_` must not read | ||
| 121 | `pooled_sentinel`). The same list-corruption hazard | ||
| 122 | `recycle()`'s class-level comment documents applies here: a | ||
| 123 | free-listed impl would be spliced out using `live_`'s | ||
| 124 | boundary pointers instead of `free_`'s. | ||
| 125 | |||
| 126 | @return True if @p impl was linked in `live_` and has now | ||
| 127 | been removed; false if it was already detached. | ||
| 128 | */ | ||
| 129 | 18493x | bool remove(Impl* impl) noexcept | |
| 130 | { | ||
| 131 | 18493x | std::lock_guard lock(mutex_); | |
| 132 | 18493x | if (is_pooled(impl)) | |
| 133 | { | ||
| 134 | ✗ | BOOST_COROSIO_ASSERT(false); | |
| 135 | return false; | ||
| 136 | } | ||
| 137 | 18493x | return live_.remove(impl); | |
| 138 | 18493x | } | |
| 139 | |||
| 140 | public: | ||
| 141 | /** Destroy the pool, freeing every impl still parked or live. | ||
| 142 | |||
| 143 | A live impl is deleted whatever its count. Keepalives it holds | ||
| 144 | on itself (an embedded op's `object_ref`) are released by its | ||
| 145 | own destructor; the count is pinned first so none of those | ||
| 146 | releases reaches zero and calls `retire()` on an object that | ||
| 147 | is already being destroyed. | ||
| 148 | |||
| 149 | @pre `shutdown()` has already run, or no impls are live. | ||
| 150 | */ | ||
| 151 | 8917x | ~object_pool() | |
| 152 | { | ||
| 153 | 8917x | BOOST_COROSIO_ASSERT(shutting_down_ || live_.empty()); | |
| 154 | 26751x | for (auto* list : {&free_, &live_}) | |
| 155 | { | ||
| 156 | 25800x | while (auto* impl = list->pop_front()) | |
| 157 | { | ||
| 158 | 7966x | impl->refs_.store(pooled_sentinel, std::memory_order_relaxed); | |
| 159 | 7966x | delete impl; | |
| 160 | } | ||
| 161 | } | ||
| 162 | 8917x | } | |
| 163 | |||
| 164 | 8907x | object_pool() = default; | |
| 165 | object_pool(object_pool const&) = delete; | ||
| 166 | object_pool& operator=(object_pool const&) = delete; | ||
| 167 | |||
| 168 | /** Pop-or-create an impl with the acquisition protocol applied. | ||
| 169 | |||
| 170 | Recycled impls are `reuse()`-reset and their reference count | ||
| 171 | restored from the pooled sentinel; fresh impls are constructed | ||
| 172 | in place from `args` on the cold path. Either way the impl is | ||
| 173 | adopted as live. This is the sequence every service's | ||
| 174 | `construct()` used to hand-roll. Making the pool itself the | ||
| 175 | only place that calls `new Impl` gives the whole library one | ||
| 176 | audit point for allocation policy. | ||
| 177 | |||
| 178 | @pre Not called concurrently with, or after, `shutdown()` on | ||
| 179 | this pool. Every caller reaches this through a service's | ||
| 180 | `construct()`, and service shutdown order guarantees no | ||
| 181 | `construct()` outlives that service's own `shutdown()`; the | ||
| 182 | window is only asserted in debug builds (see `adopt()`) | ||
| 183 | because the failure mode is an orphaned impl, not corruption. | ||
| 184 | |||
| 185 | @param args Constructor arguments for `Impl` (cold path only). | ||
| 186 | |||
| 187 | @return The acquired impl, `refs_ == 1`, tracked live. | ||
| 188 | */ | ||
| 189 | template<class... Args> | ||
| 190 | 39842x | Impl* acquire(Args&&... args) | |
| 191 | { | ||
| 192 | Impl* impl; | ||
| 193 | { | ||
| 194 | 39842x | std::lock_guard lock(mutex_); | |
| 195 | 39842x | BOOST_COROSIO_ASSERT(!shutting_down_); | |
| 196 | 39842x | impl = free_.pop_front(); | |
| 197 | 39842x | if (impl) | |
| 198 | { | ||
| 199 | 22182x | impl->refs_.store(1, std::memory_order_relaxed); | |
| 200 | 22182x | live_.push_back(impl); | |
| 201 | } | ||
| 202 | 39842x | } | |
| 203 | // reuse() runs unlocked: acquire()'s precondition excludes a | ||
| 204 | // concurrent shutdown() visiting the impl mid-reset. | ||
| 205 | 39842x | if (impl) | |
| 206 | { | ||
| 207 | 22182x | impl->reuse(); | |
| 208 | 22182x | return impl; | |
| 209 | } | ||
| 210 | 17660x | impl = new Impl(std::forward<Args>(args)...); | |
| 211 | 17660x | adopt(impl); | |
| 212 | 17660x | return impl; | |
| 213 | } | ||
| 214 | |||
| 215 | /** Move a zero-ref impl from live to the free list. | ||
| 216 | |||
| 217 | Called from `retire()`, possibly on a scheduler thread. | ||
| 218 | Deletes instead when shutting down. The impl must not be | ||
| 219 | touched after this returns. | ||
| 220 | |||
| 221 | Two accounting bugs are possible here, neither from this | ||
| 222 | pool's own bookkeeping but from a caller's refcounting (e.g. | ||
| 223 | a duplicate `retire()` for one zero-crossing). Both are | ||
| 224 | made safe in every build mode, not just under asserts, because | ||
| 225 | neither can be told apart from the correct case by a | ||
| 226 | `BOOST_COROSIO_ASSERT` alone that still runs the list | ||
| 227 | operations around it: | ||
| 228 | |||
| 229 | - `impl` is already parked in `free_` — the list-corruption | ||
| 230 | hazard the class-level `pooled_sentinel` comment documents. | ||
| 231 | The `is_pooled()` check runs first and returns before either | ||
| 232 | list is touched. | ||
| 233 | - `impl` is fully detached from `live_` and is not the | ||
| 234 | sentinel (not shutting down): `live_.remove()` correctly | ||
| 235 | returns false, but then the impl is reachable through | ||
| 236 | neither `acquire()` nor `shutdown()`'s visit while still | ||
| 237 | allocated — stranded. Deleted instead of left to leak. | ||
| 238 | |||
| 239 | While shutting down, an impl that is no longer in `live_` is | ||
| 240 | left alone rather than deleted: something else already took | ||
| 241 | it out of the pool's bookkeeping (a derived pool's owner, or a | ||
| 242 | duplicate retirement of an impl already deleted), and deleting | ||
| 243 | it again here could be a double free. | ||
| 244 | */ | ||
| 245 | 36087x | void recycle(Impl* impl) | |
| 246 | { | ||
| 247 | 36087x | bool do_delete = false; | |
| 248 | { | ||
| 249 | 36087x | std::lock_guard lock(mutex_); | |
| 250 | 36087x | if (is_pooled(impl)) | |
| 251 | { | ||
| 252 | ✗ | BOOST_COROSIO_ASSERT(false); | |
| 253 | return; | ||
| 254 | } | ||
| 255 | |||
| 256 | 36087x | bool const was_live = live_.remove(impl); | |
| 257 | 36087x | if (shutting_down_) | |
| 258 | { | ||
| 259 | 5946x | do_delete = was_live; | |
| 260 | } | ||
| 261 | 30141x | else if (was_live) | |
| 262 | { | ||
| 263 | 30141x | impl->refs_.store( | |
| 264 | pooled_sentinel, std::memory_order_relaxed); | ||
| 265 | // LIFO: the most recently retired impl is the | ||
| 266 | // cache-warmest candidate for the next acquire(). | ||
| 267 | 30141x | free_.push_front(impl); | |
| 268 | } | ||
| 269 | else | ||
| 270 | { | ||
| 271 | ✗ | BOOST_COROSIO_ASSERT(false); | |
| 272 | do_delete = true; | ||
| 273 | } | ||
| 274 | 36087x | } | |
| 275 | 36087x | if (do_delete) | |
| 276 | 5946x | delete impl; | |
| 277 | } | ||
| 278 | |||
| 279 | /** Enter shutdown mode and visit every live impl. | ||
| 280 | |||
| 281 | Sets shutting-down (subsequent zero-crossings delete instead | ||
| 282 | of recycling) and runs `f` on each live impl, all under one | ||
| 283 | critical section. Each visited impl is pinned with a reference | ||
| 284 | for the call and released after the critical section ends, so | ||
| 285 | `f` may hold on to it; an impl whose count already reached zero | ||
| 286 | is retiring and is skipped rather than revived. | ||
| 287 | |||
| 288 | @note The callback runs under the pool's non-recursive mutex; | ||
| 289 | it must not call recycle(), adopt(), or remove() on this pool. | ||
| 290 | */ | ||
| 291 | template<class F> | ||
| 292 | 13325x | void shutdown(F&& f) | |
| 293 | { | ||
| 294 | 13325x | std::vector<Impl*> pinned; | |
| 295 | { | ||
| 296 | 13325x | std::lock_guard lock(mutex_); | |
| 297 | 13325x | shutting_down_ = true; | |
| 298 | // Sized before any pin, so a failure here leaves none held. | ||
| 299 | 13325x | std::size_t n = 0; | |
| 300 | 13325x | live_.for_each([&](Impl*) { ++n; }); | |
| 301 | 13325x | pinned.reserve(n); | |
| 302 | 13325x | live_.for_each( | |
| 303 | 6x | [&](Impl* impl) | |
| 304 | { | ||
| 305 | 3x | if (try_acquire(impl)) | |
| 306 | { | ||
| 307 | 3x | pinned.push_back(impl); | |
| 308 | 3x | f(impl); | |
| 309 | } | ||
| 310 | }); | ||
| 311 | 13325x | } | |
| 312 | 22524x | for (auto* impl : pinned) | |
| 313 | 9199x | release(impl); | |
| 314 | 13325x | } | |
| 315 | }; | ||
| 316 | |||
| 317 | } // namespace boost::corosio::detail | ||
| 318 | |||
| 319 | #endif | ||
| 320 |