Merge pull request #296 from arvidn/udp-read-handler

more efficient handler allocation for udp and second_tick
This commit is contained in:
Arvid Norberg 2015-11-28 01:06:10 -05:00
commit 359fc5648b
5 changed files with 89 additions and 6 deletions

View File

@ -1062,6 +1062,15 @@ namespace libtorrent
// the timer used to fire the tick
deadline_timer m_timer;
aux::handler_storage<TORRENT_READ_HANDLER_MAX_SIZE> m_tick_handler_storage;
template <class Handler>
aux::allocating_handler<Handler, TORRENT_READ_HANDLER_MAX_SIZE>
make_tick_handler(Handler const& handler)
{
return aux::allocating_handler<Handler, TORRENT_READ_HANDLER_MAX_SIZE>(
handler, m_tick_handler_storage);
}
// torrents are announced on the local network in a
// round-robin fashion. All torrents are cycled through

View File

@ -985,7 +985,6 @@ namespace libtorrent
// have sent to it
int m_outstanding_bytes;
// TODO: 3 use handler storage for second_tick and udp_packet handler too
aux::handler_storage<TORRENT_READ_HANDLER_MAX_SIZE> m_read_handler_storage;
aux::handler_storage<TORRENT_WRITE_HANDLER_MAX_SIZE> m_write_handler_storage;

View File

@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/thread.hpp"
#include "libtorrent/deadline_timer.hpp"
#include "libtorrent/debug.hpp"
#include "libtorrent/aux_/allocating_handler.hpp"
#include <deque>
@ -179,6 +180,26 @@ namespace libtorrent
std::vector<udp_socket_observer*> m_observers;
std::vector<udp_socket_observer*> m_added_observers;
template <class Handler>
aux::allocating_handler<Handler, TORRENT_READ_HANDLER_MAX_SIZE>
make_read_handler4(Handler const& handler)
{
return aux::allocating_handler<Handler, TORRENT_READ_HANDLER_MAX_SIZE>(
handler, m_v4_read_handler_storage
);
}
#if TORRENT_USE_IPV6
template <class Handler>
aux::allocating_handler<Handler, TORRENT_READ_HANDLER_MAX_SIZE>
make_read_handler6(Handler const& handler)
{
return aux::allocating_handler<Handler, TORRENT_READ_HANDLER_MAX_SIZE>(
handler, m_v6_read_handler_storage
);
}
#endif
// this is true while iterating over the observers
// vector, invoking observer hooks. We may not
// add new observers during this time, since it
@ -219,6 +240,7 @@ namespace libtorrent
void unwrap(error_code const& e, char const* buf, int size);
udp::socket m_ipv4_sock;
aux::handler_storage<TORRENT_READ_HANDLER_MAX_SIZE> m_v4_read_handler_storage;
deadline_timer m_timer;
int m_buf_size;
@ -232,12 +254,15 @@ namespace libtorrent
#if TORRENT_USE_IPV6
udp::socket m_ipv6_sock;
aux::handler_storage<TORRENT_READ_HANDLER_MAX_SIZE> m_v6_read_handler_storage;
#endif
boost::uint16_t m_bind_port;
boost::uint8_t m_v4_outstanding;
boost::uint8_t m_restart_v4;
#if TORRENT_USE_IPV6
boost::uint8_t m_v6_outstanding;
boost::uint8_t m_restart_v6;
#endif
tcp::socket m_socks5_sock;

View File

@ -1730,9 +1730,10 @@ namespace aux {
{
TORRENT_ASSERT_VAL(ec, ec);
#ifndef TORRENT_DISABLE_LOGGING
error_code ignore;
session_log("failed to bind to interface [%s %d] \"%s\" : %s (%d) : %s "
"(retries: %d)"
, device.c_str(), port, bind_ip.to_string(ec).c_str()
, device.c_str(), port, bind_ip.to_string(ignore).c_str()
, ec.category().name(), ec.value(), ec.message().c_str(), retries);
#endif
ec.clear();
@ -1755,6 +1756,8 @@ namespace aux {
}
if (ec)
{
TORRENT_ASSERT_VAL(ec.value() != 0, ec);
// not even that worked, give up
if (m_alerts.should_post<listen_failed_alert>())
m_alerts.emplace_alert<listen_failed_alert>(device, last_op, ec, sock_type);
@ -2958,7 +2961,7 @@ retry:
#endif
error_code ec;
m_timer.expires_at(now + milliseconds(m_settings.get_int(settings_pack::tick_interval)), ec);
m_timer.async_wait(boost::bind(&session_impl::on_tick, this, _1));
m_timer.async_wait(make_tick_handler(boost::bind(&session_impl::on_tick, this, _1)));
m_download_rate.update_quotas(now - m_last_tick);
m_upload_rate.update_quotas(now - m_last_tick);

View File

@ -67,8 +67,10 @@ udp_socket::udp_socket(io_service& ios)
#endif
, m_bind_port(0)
, m_v4_outstanding(0)
, m_restart_v4(0)
#if TORRENT_USE_IPV6
, m_v6_outstanding(0)
, m_restart_v6(false)
#endif
, m_socks5_sock(ios)
, m_resolver(ios)
@ -284,7 +286,26 @@ void udp_socket::on_read(error_code const& ec, udp::socket* s)
--m_v4_outstanding;
}
if (ec == boost::asio::error::operation_aborted) return;
if (ec == boost::asio::error::operation_aborted)
{
#if TORRENT_USE_IPV6
if (s == &m_ipv6_sock)
{
if (m_restart_v6) {
--m_restart_v6;
setup_read(s);
}
}
else
#endif
{
if (m_restart_v4) {
--m_restart_v4;
setup_read(s);
}
}
return;
}
if (m_abort) return;
CHECK_MAGIC;
@ -498,10 +519,26 @@ void udp_socket::setup_read(udp::socket* s)
#if TORRENT_USE_IPV6
if (s == &m_ipv6_sock)
{
if (m_v6_outstanding)
{
++m_restart_v6;
m_ipv6_sock.cancel();
return;
}
++m_v6_outstanding;
}
else
#endif
{
if (m_v4_outstanding)
{
++m_restart_v4;
m_ipv4_sock.cancel();
return;
}
++m_v4_outstanding;
}
#if defined TORRENT_ASIO_DEBUGGING
add_outstanding_async("udp_socket::on_read");
@ -510,8 +547,18 @@ void udp_socket::setup_read(udp::socket* s)
udp::endpoint ep;
TORRENT_TRY
{
s->async_receive_from(null_buffers()
, ep, boost::bind(&udp_socket::on_read, this, _1, s));
#if TORRENT_USE_IPV6
if (s == &m_ipv6_sock)
{
s->async_receive_from(null_buffers()
, ep, make_read_handler6(boost::bind(&udp_socket::on_read, this, _1, s)));
}
else
#endif
{
s->async_receive_from(null_buffers()
, ep, make_read_handler4(boost::bind(&udp_socket::on_read, this, _1, s)));
}
}
TORRENT_CATCH(boost::system::system_error& e)
{