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 2078x 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 17031x 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 492x 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 6888x 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 1912x 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 12689x 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 39983x 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 876x 85.7% 79.0% boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_socket>::adopt(boost::corosio::detail::epoll_tcp_socket*) :102 2475x 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 246x 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 3408x 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 793x 85.7% 79.0% boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_socket>::adopt(boost::corosio::detail::select_tcp_socket*) :102 2090x 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 19997x 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 18412x 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 507x 100.0% 68.0% boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_socket>::~object_pool() :151 713x 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 191x 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 585x 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 425x 100.0% 68.0% boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_socket>::~object_pool() :151 492x 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 4415x 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 507x 100.0% 100.0% boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_socket>::object_pool() :164 713x 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 191x 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 585x 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 425x 100.0% 100.0% boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_socket>::object_pool() :164 492x 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 4415x 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 1202x 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 14556x 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 246x 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 3480x 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 1119x 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 10599x 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 5323x 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 1202x 86.7% 71.0% boost::corosio::detail::object_pool<boost::corosio::detail::epoll_tcp_socket>::recycle(boost::corosio::detail::epoll_tcp_socket*) :245 14556x 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 246x 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 3480x 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 1119x 86.7% 71.0% boost::corosio::detail::object_pool<boost::corosio::detail::select_tcp_socket>::recycle(boost::corosio::detail::select_tcp_socket*) :245 10599x 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 1574x 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 507x 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 713x 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 191x 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 585x 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 425x 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 492x 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 8830x 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 85613x static bool is_pooled(Impl const* impl) noexcept
79 {
80 85613x return impl->refs_.load(std::memory_order_relaxed) ==
81 85613x 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 31897x void adopt(Impl* impl)
103 {
104 31897x std::lock_guard lock(mutex_);
105 31897x if (is_pooled(impl))
106 {
107 ✗ BOOST_COROSIO_ASSERT(false);
108 return;
109 }
110 31897x BOOST_COROSIO_ASSERT(!shutting_down_);
111 31897x live_.push_back(impl);
112 31897x }
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 18415x bool remove(Impl* impl) noexcept
130 {
131 18415x std::lock_guard lock(mutex_);
132 18415x if (is_pooled(impl))
133 {
134 ✗ BOOST_COROSIO_ASSERT(false);
135 return false;
136 }
137 18415x return live_.remove(impl);
138 18415x }
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 8919x ~object_pool()
152 {
153 8919x BOOST_COROSIO_ASSERT(shutting_down_ || live_.empty());
154 26757x for (auto* list : {&free_, &live_})
155 {
156 25368x while (auto* impl = list->pop_front())
157 {
158 7530x impl->refs_.store(pooled_sentinel, std::memory_order_relaxed);
159 7530x delete impl;
160 }
161 }
162 8919x }
163
164 8909x 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 39054x Impl* acquire(Args&&... args)
191 {
192 Impl* impl;
193 {
194 39054x std::lock_guard lock(mutex_);
195 39054x BOOST_COROSIO_ASSERT(!shutting_down_);
196 39054x impl = free_.pop_front();
197 39054x if (impl)
198 {
199 21833x impl->refs_.store(1, std::memory_order_relaxed);
200 21833x live_.push_back(impl);
201 }
202 39054x }
203 // reuse() runs unlocked: acquire()'s precondition excludes a
204 // concurrent shutdown() visiting the impl mid-reset.
205 39054x if (impl)
206 {
207 21833x impl->reuse();
208 21833x return impl;
209 }
210 17221x impl = new Impl(std::forward<Args>(args)...);
211 17221x adopt(impl);
212 17221x 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 35301x void recycle(Impl* impl)
246 {
247 35301x bool do_delete = false;
248 {
249 35301x std::lock_guard lock(mutex_);
250 35301x if (is_pooled(impl))
251 {
252 ✗ BOOST_COROSIO_ASSERT(false);
253 return;
254 }
255
256 35301x bool const was_live = live_.remove(impl);
257 35301x if (shutting_down_)
258 {
259 5953x do_delete = was_live;
260 }
261 29348x else if (was_live)
262 {
263 29348x 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 29348x free_.push_front(impl);
268 }
269 else
270 {
271 ✗ BOOST_COROSIO_ASSERT(false);
272 do_delete = true;
273 }
274 35301x }
275 35301x if (do_delete)
276 5953x 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 13329x void shutdown(F&& f)
293 {
294 13329x std::vector<Impl*> pinned;
295 {
296 13329x std::lock_guard lock(mutex_);
297 13329x shutting_down_ = true;
298 // Sized before any pin, so a failure here leaves none held.
299 13329x std::size_t n = 0;
300 13329x live_.for_each([&](Impl*) { ++n; });
301 13329x pinned.reserve(n);
302 13329x 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 13329x }
312 22547x for (auto* impl : pinned)
313 9218x release(impl);
314 13329x }
315 };
316
317 } // namespace boost::corosio::detail
318
319 #endif
320