include/boost/corosio/detail/object_pool.hpp

94.2% Lines (65 / 69) 97.5% Functions (157 / 161)
object_pool.hpp
f(x) Functions (161)
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 159x 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 411x 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 2142x 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 17509x 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 502x 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 6900x 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 1464x 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 152x 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 382x 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 1960x 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 13020x 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 38818x 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 61x 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 177x 85.7% 79.0% boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_acceptor>::adopt(boost::corosio::detail::epoll_tcp_acceptor*) :102 908x 85.7% 79.0% boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_socket>::adopt(boost::corosio::detail::epoll_tcp_socket*) :102 2562x 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 251x 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 3414x 85.7% 79.0% boost::corosio::detail::object_pool<boost::corosio::detail::posix_stream_file>::adopt(boost::corosio::detail::posix_stream_file*) :102 700x 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 58x 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 167x 85.7% 79.0% boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_acceptor>::adopt(boost::corosio::detail::select_tcp_acceptor*) :102 817x 85.7% 79.0% boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_socket>::adopt(boost::corosio::detail::select_tcp_socket*) :102 2231x 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 19414x 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 18343x 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 55x 100.0% 68.0% boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_stream_socket>::~object_pool() :151 118x 100.0% 68.0% boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_acceptor>::~object_pool() :151 536x 100.0% 68.0% boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_socket>::~object_pool() :151 748x 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 196x 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 589x 100.0% 68.0% boost::corosio::detail::object_pool<boost::corosio::detail::posix_stream_file>::~object_pool() :151 644x 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 52x 100.0% 68.0% boost::corosio::detail::object_pool<boost::corosio::detail::select_local_stream_socket>::~object_pool() :151 111x 100.0% 68.0% boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_acceptor>::~object_pool() :151 446x 100.0% 68.0% boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_socket>::~object_pool() :151 513x 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 925x 100.0% 74.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 55x 100.0% 100.0% boost::corosio::detail::object_pool<boost::corosio::detail::epoll_local_stream_socket>::object_pool() :164 118x 100.0% 100.0% boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_acceptor>::object_pool() :164 536x 100.0% 100.0% boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_socket>::object_pool() :164 748x 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 196x 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 589x 100.0% 100.0% boost::corosio::detail::object_pool<boost::corosio::detail::posix_stream_file>::object_pool() :164 644x 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 52x 100.0% 100.0% boost::corosio::detail::object_pool<boost::corosio::detail::select_local_stream_socket>::object_pool() :164 111x 100.0% 100.0% boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_acceptor>::object_pool() :164 446x 100.0% 100.0% boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_socket>::object_pool() :164 513x 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 925x 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 98x 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 234x 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 1234x 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 14947x 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 251x 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 3486x 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 764x 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 94x 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 215x 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 1143x 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 10789x 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 4811x 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 98x 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 234x 86.7% 71.0% boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_acceptor>::recycle(boost::corosio::detail::epoll_tcp_acceptor*) :245 1234x 86.7% 71.0% boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_socket>::recycle(boost::corosio::detail::epoll_tcp_socket*) :245 14947x 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 251x 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 3486x 86.7% 71.0% boost::corosio::detail::object_pool<boost::corosio::detail::posix_stream_file>::recycle(boost::corosio::detail::posix_stream_file*) :245 764x 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 94x 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 215x 86.7% 71.0% boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_acceptor>::recycle(boost::corosio::detail::select_tcp_acceptor*) :245 1143x 86.7% 71.0% boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_socket>::recycle(boost::corosio::detail::select_tcp_socket*) :245 10789x 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 1061x 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 55x 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 118x 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 536x 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 748x 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 196x 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 589x 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 644x 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 52x 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 111x 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 446x 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 513x 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 920x 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 100.0% 0.0% 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}&&)::{lambda(boost::corosio::detail::timer::implementation*)#1}::operator()(boost::corosio::detail::timer::implementation*) const :300 3251x 100.0% 100.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 37.5% 0.0% 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}&&)::{lambda(boost::corosio::detail::timer::implementation*)#2}::operator()(boost::corosio::detail::timer::implementation*) const :303 3251x 100.0% 100.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 85425x static bool is_pooled(Impl const* impl) noexcept
79 {
80 85425x return impl->refs_.load(std::memory_order_relaxed) ==
81 85425x 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 31626x void adopt(Impl* impl)
103 {
104 31626x std::lock_guard lock(mutex_);
105 31626x if (is_pooled(impl))
106 {
107 ✗ BOOST_COROSIO_ASSERT(false);
108 return;
109 }
110 31626x BOOST_COROSIO_ASSERT(!shutting_down_);
111 31626x live_.push_back(impl);
112 31626x }
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 18346x bool remove(Impl* impl) noexcept
130 {
131 18346x std::lock_guard lock(mutex_);
132 18346x if (is_pooled(impl))
133 {
134 ✗ BOOST_COROSIO_ASSERT(false);
135 return false;
136 }
137 18346x return live_.remove(impl);
138 18346x }
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 5561x ~object_pool()
152 {
153 5561x BOOST_COROSIO_ASSERT(shutting_down_ || live_.empty());
154 16683x for (auto* list : {&free_, &live_})
155 {
156 18444x while (auto* impl = list->pop_front())
157 {
158 7322x impl->refs_.store(pooled_sentinel, std::memory_order_relaxed);
159 7322x delete impl;
160 }
161 }
162 5561x }
163
164 5551x 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 39207x Impl* acquire(Args&&... args)
191 {
192 Impl* impl;
193 {
194 39207x std::lock_guard lock(mutex_);
195 39207x BOOST_COROSIO_ASSERT(!shutting_down_);
196 39207x impl = free_.pop_front();
197 39207x if (impl)
198 {
199 22186x impl->refs_.store(1, std::memory_order_relaxed);
200 22186x live_.push_back(impl);
201 }
202 39207x }
203 // reuse() runs unlocked: acquire()'s precondition excludes a
204 // concurrent shutdown() visiting the impl mid-reset.
205 39207x if (impl)
206 {
207 22186x impl->reuse();
208 22186x return impl;
209 }
210 17021x impl = new Impl(std::forward<Args>(args)...);
211 17021x adopt(impl);
212 17021x 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 35453x void recycle(Impl* impl)
246 {
247 35453x bool do_delete = false;
248 {
249 35453x std::lock_guard lock(mutex_);
250 35453x if (is_pooled(impl))
251 {
252 ✗ BOOST_COROSIO_ASSERT(false);
253 return;
254 }
255
256 35453x bool const was_live = live_.remove(impl);
257 35453x if (shutting_down_)
258 {
259 5959x do_delete = was_live;
260 }
261 29494x else if (was_live)
262 {
263 29494x 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 29494x free_.push_front(impl);
268 }
269 else
270 {
271 ✗ BOOST_COROSIO_ASSERT(false);
272 do_delete = true;
273 }
274 35453x }
275 35453x if (do_delete)
276 5959x 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 5551x void shutdown(F&& f)
293 {
294 5551x std::vector<Impl*> pinned;
295 {
296 5551x std::lock_guard lock(mutex_);
297 5551x shutting_down_ = true;
298 // Sized before any pin, so a failure here leaves none held.
299 5551x std::size_t n = 0;
300 5551x live_.for_each([&](Impl*) { ++n; });
301 5551x pinned.reserve(n);
302 5551x live_.for_each(
303 6508x [&](Impl* impl)
304 {
305 3254x if (try_acquire(impl))
306 {
307 3254x pinned.push_back(impl);
308 3254x f(impl);
309 }
310 });
311 5551x }
312 14762x for (auto* impl : pinned)
313 9211x release(impl);
314 5551x }
315 };
316
317 } // namespace boost::corosio::detail
318
319 #endif
320