simplify and improve the uTP deferred ACK logic to respond earlier

This commit is contained in:
arvidn 2018-12-31 15:28:43 +01:00 committed by Arvid Norberg
parent 6f1f466832
commit 8ffd524b5f
3 changed files with 20 additions and 15 deletions

View File

@ -1,3 +1,5 @@
* uTP performance fixes
1.1.11 release 1.1.11 release
* fix move_storage with save_path with a trailing slash * fix move_storage with save_path with a trailing slash

View File

@ -121,11 +121,10 @@ namespace libtorrent
typedef std::multimap<boost::uint16_t, utp_socket_impl*> socket_map_t; typedef std::multimap<boost::uint16_t, utp_socket_impl*> socket_map_t;
socket_map_t m_utp_sockets; socket_map_t m_utp_sockets;
// this is a list of sockets that needs to send an ack. // if this is set, it means this socket still needs to send an ACK. Once
// once the UDP socket is drained, all of these will // we exit the loop processing packets, or switch to processing packets
// have a chance to do that. This is to avoid sending // for a different socket, issue the ACK packet and clear this.
// an ack for every single packet utp_socket_impl* m_deferred_ack;
std::vector<utp_socket_impl*> m_deferred_acks;
// sockets that have received or sent packets this // sockets that have received or sent packets this
// round, may subscribe to the event of draining the // round, may subscribe to the event of draining the

View File

@ -53,6 +53,7 @@ namespace libtorrent
, incoming_utp_callback_t cb) , incoming_utp_callback_t cb)
: m_sock(s) : m_sock(s)
, m_cb(cb) , m_cb(cb)
, m_deferred_ack(0)
, m_last_socket(0) , m_last_socket(0)
, m_new_connection(-1) , m_new_connection(-1)
, m_sett(sett) , m_sett(sett)
@ -268,6 +269,12 @@ namespace libtorrent
return utp_incoming_packet(m_last_socket, p, size, ep, receive_time); return utp_incoming_packet(m_last_socket, p, size, ep, receive_time);
} }
if (m_deferred_ack)
{
utp_send_ack(m_deferred_ack);
m_deferred_ack = NULL;
}
std::pair<socket_map_t::iterator, socket_map_t::iterator> r = std::pair<socket_map_t::iterator, socket_map_t::iterator> r =
m_utp_sockets.equal_range(id); m_utp_sockets.equal_range(id);
@ -319,6 +326,7 @@ namespace libtorrent
utp_init_mtu(str->get_impl(), link_mtu, utp_mtu); utp_init_mtu(str->get_impl(), link_mtu, utp_mtu);
bool ret = utp_incoming_packet(str->get_impl(), p, size, ep, receive_time); bool ret = utp_incoming_packet(str->get_impl(), p, size, ep, receive_time);
if (!ret) return false; if (!ret) return false;
m_last_socket = str->get_impl();
m_cb(c); m_cb(c);
// the connection most likely changed its connection ID here // the connection most likely changed its connection ID here
// we need to move it to the correct ID // we need to move it to the correct ID
@ -353,14 +361,10 @@ namespace libtorrent
void utp_socket_manager::socket_drained() void utp_socket_manager::socket_drained()
{ {
// flush all deferred acks if (m_deferred_ack)
std::vector<utp_socket_impl*> deferred_acks;
m_deferred_acks.swap(deferred_acks);
for (std::vector<utp_socket_impl*>::iterator i = deferred_acks.begin()
, end(deferred_acks.end()); i != end; ++i)
{ {
utp_socket_impl* s = *i; utp_socket_impl* s = m_deferred_ack;
m_deferred_ack = NULL;
utp_send_ack(s); utp_send_ack(s);
} }
@ -376,9 +380,8 @@ namespace libtorrent
void utp_socket_manager::defer_ack(utp_socket_impl* s) void utp_socket_manager::defer_ack(utp_socket_impl* s)
{ {
TORRENT_ASSERT(std::find(m_deferred_acks.begin(), m_deferred_acks.end(), s) TORRENT_ASSERT(m_deferred_ack == NULL || m_deferred_ack == s);
== m_deferred_acks.end()); m_deferred_ack = s;
m_deferred_acks.push_back(s);
} }
void utp_socket_manager::subscribe_drained(utp_socket_impl* s) void utp_socket_manager::subscribe_drained(utp_socket_impl* s)
@ -394,6 +397,7 @@ namespace libtorrent
if (i == m_utp_sockets.end()) return; if (i == m_utp_sockets.end()) return;
delete_utp_impl(i->second); delete_utp_impl(i->second);
if (m_last_socket == i->second) m_last_socket = 0; if (m_last_socket == i->second) m_last_socket = 0;
if (m_deferred_ack == i->second) m_deferred_ack = 0;
m_utp_sockets.erase(i); m_utp_sockets.erase(i);
} }