forked from premiere/premiere-libtorrent
defer reconnecting peers to after the second_tick loop (to avoid mutating m_connections while iterating over it)
This commit is contained in:
parent
3215deb2c5
commit
3f09d16e3c
|
@ -39,7 +39,13 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/session_stats.hpp"
|
||||
#include "libtorrent/aux_/path.hpp"
|
||||
#include "libtorrent/torrent_info.hpp"
|
||||
#include "libtorrent/time.hpp"
|
||||
#include "settings.hpp"
|
||||
#include "setup_transfer.hpp" // for ep()
|
||||
#include "fake_peer.hpp"
|
||||
|
||||
#include "simulator/queue.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
using namespace lt;
|
||||
|
||||
|
@ -370,6 +376,70 @@ TORRENT_TEST(shutdown)
|
|||
});
|
||||
}
|
||||
|
||||
// make the delays on the connections unreasonable long, so libtorrent times-out
|
||||
// the connection attempts
|
||||
struct timeout_config : sim::default_config
|
||||
{
|
||||
virtual sim::route incoming_route(lt::address ip) override
|
||||
{
|
||||
auto it = m_incoming.find(ip);
|
||||
if (it != m_incoming.end()) return sim::route().append(it->second);
|
||||
it = m_incoming.insert(it, std::make_pair(ip, std::make_shared<queue>(
|
||||
std::ref(m_sim->get_io_service())
|
||||
, 1000
|
||||
, lt::duration_cast<lt::time_duration>(seconds(10))
|
||||
, 1000, "packet-loss modem in")));
|
||||
return sim::route().append(it->second);
|
||||
}
|
||||
|
||||
virtual sim::route outgoing_route(lt::address ip) override
|
||||
{
|
||||
auto it = m_outgoing.find(ip);
|
||||
if (it != m_outgoing.end()) return sim::route().append(it->second);
|
||||
it = m_outgoing.insert(it, std::make_pair(ip, std::make_shared<queue>(
|
||||
std::ref(m_sim->get_io_service()), 1000
|
||||
, lt::duration_cast<lt::time_duration>(seconds(5)), 200 * 1000, "packet-loss out")));
|
||||
return sim::route().append(it->second);
|
||||
}
|
||||
};
|
||||
|
||||
// make sure peers that are no longer alive are handled correctly.
|
||||
TORRENT_TEST(dead_peers)
|
||||
{
|
||||
int num_connect_timeout = 0;
|
||||
|
||||
timeout_config network_cfg;
|
||||
sim::simulation sim{network_cfg};
|
||||
setup_swarm(1, swarm_test::download, sim
|
||||
// add session
|
||||
, [](lt::settings_pack& p) {
|
||||
p.set_int(settings_pack::peer_connect_timeout, 1);
|
||||
}
|
||||
// add torrent
|
||||
, [](lt::add_torrent_params& params) {
|
||||
params.peers.assign({
|
||||
ep("66.66.66.60", 9999)
|
||||
, ep("66.66.66.61", 9999)
|
||||
, ep("66.66.66.62", 9999)
|
||||
});
|
||||
}
|
||||
// on alert
|
||||
, [&](lt::alert const* a, lt::session&) {
|
||||
auto* e = alert_cast<peer_disconnected_alert>(a);
|
||||
if (e
|
||||
&& e->operation == op_connect
|
||||
&& e->error == error_code(errors::timed_out))
|
||||
{
|
||||
++num_connect_timeout;
|
||||
}
|
||||
}
|
||||
// terminate
|
||||
, [](int t, lt::session&) -> bool
|
||||
{ return t > 100; });
|
||||
|
||||
TEST_EQUAL(num_connect_timeout, 3);
|
||||
}
|
||||
|
||||
TORRENT_TEST(delete_files)
|
||||
{
|
||||
std::string save_path;
|
||||
|
|
|
@ -30,6 +30,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
*/
|
||||
|
||||
#ifndef TORRENT_UTILS_HPP_INCLUDED
|
||||
#define TORRENT_UTILS_HPP_INCLUDED
|
||||
|
||||
#include <functional>
|
||||
#include "libtorrent/address.hpp"
|
||||
#include "libtorrent/socket.hpp"
|
||||
|
@ -61,3 +64,5 @@ void print_alerts(lt::session& ses
|
|||
, std::function<void(lt::session&, lt::alert const*)> on_alert
|
||||
= [](lt::session&, lt::alert const*) {});
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -4019,10 +4019,27 @@ namespace libtorrent {
|
|||
{
|
||||
m_peer_info->supports_utp = false;
|
||||
// reconnect immediately using TCP
|
||||
torrent_peer* pi = peer_info_struct();
|
||||
fast_reconnect(true);
|
||||
disconnect(e, op_connect, 0);
|
||||
if (t && pi) t->connect_to_peer(pi, true);
|
||||
if (t && m_peer_info)
|
||||
{
|
||||
std::weak_ptr<torrent> weak_t = t;
|
||||
std::weak_ptr<peer_connection> weak_self = shared_from_this();
|
||||
|
||||
// we can't touch m_connections here, since we're likely looping
|
||||
// over it. So defer the actual reconnection to after we've handled
|
||||
// the existing message queue
|
||||
m_ses.get_io_service().post([weak_t, weak_self]()
|
||||
{
|
||||
std::shared_ptr<torrent> tor = weak_t.lock();
|
||||
std::shared_ptr<peer_connection> p = weak_self.lock();
|
||||
if (tor && p)
|
||||
{
|
||||
torrent_peer* pi = p->peer_info_struct();
|
||||
tor->connect_to_peer(pi, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue