diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 3242e8dac..812a81d41 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -407,7 +407,7 @@ namespace libtorrent { return m_num_uploads < m_max_uploads; } bool choke_peer(peer_connection& c); - bool unchoke_peer(peer_connection& c); + bool unchoke_peer(peer_connection& c, bool optimistic = false); // used by peer_connection to attach itself to a torrent // since incoming connections don't know what torrent diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 3636d8344..753b9641a 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -2807,11 +2807,19 @@ namespace aux { if (!pi->optimistically_unchoked) { torrent* t = pi->connection->associated_torrent().lock().get(); - bool ret = t->unchoke_peer(*pi->connection); + bool ret = t->unchoke_peer(*pi->connection, true); TORRENT_ASSERT(ret); - pi->optimistically_unchoked = true; - ++m_num_unchoked; - pi->last_optimistically_unchoked = session_time(); + if (ret) + { + pi->optimistically_unchoked = true; + ++m_num_unchoked; + pi->last_optimistically_unchoked = session_time(); + } + else + { + // we failed to unchoke it, increment the count again + ++num_opt_unchoke; + } } } else diff --git a/src/torrent.cpp b/src/torrent.cpp index 52c80e2e8..167cdb5f4 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -3220,13 +3220,16 @@ namespace libtorrent return true; } - bool torrent::unchoke_peer(peer_connection& c) + bool torrent::unchoke_peer(peer_connection& c, bool optimistic) { INVARIANT_CHECK; TORRENT_ASSERT(c.is_choked()); TORRENT_ASSERT(!c.ignore_unchoke_slots()); - if (m_num_uploads >= m_max_uploads) return false; + // when we're unchoking the optimistic slots, we might + // exceed the limit temporarily while we're iterating + // over the peers + if (m_num_uploads >= m_max_uploads && !optimistic) return false; if (!c.send_unchoke()) return false; ++m_num_uploads; return true;