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

View File

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