include/boost/corosio/detail/object_pool.hpp

94.2% Lines (65 / 69) 97.5% Functions (155 / 159)
object_pool.hpp
f(x) 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