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/session_stats.hpp"
|
||||||
#include "libtorrent/aux_/path.hpp"
|
#include "libtorrent/aux_/path.hpp"
|
||||||
#include "libtorrent/torrent_info.hpp"
|
#include "libtorrent/torrent_info.hpp"
|
||||||
|
#include "libtorrent/time.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
|
#include "setup_transfer.hpp" // for ep()
|
||||||
|
#include "fake_peer.hpp"
|
||||||
|
|
||||||
|
#include "simulator/queue.hpp"
|
||||||
|
#include "utils.hpp"
|
||||||
|
|
||||||
using namespace lt;
|
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)
|
TORRENT_TEST(delete_files)
|
||||||
{
|
{
|
||||||
std::string save_path;
|
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 <functional>
|
||||||
#include "libtorrent/address.hpp"
|
#include "libtorrent/address.hpp"
|
||||||
#include "libtorrent/socket.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
|
, std::function<void(lt::session&, lt::alert const*)> on_alert
|
||||||
= [](lt::session&, lt::alert const*) {});
|
= [](lt::session&, lt::alert const*) {});
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -4019,10 +4019,27 @@ namespace libtorrent {
|
||||||
{
|
{
|
||||||
m_peer_info->supports_utp = false;
|
m_peer_info->supports_utp = false;
|
||||||
// reconnect immediately using TCP
|
// reconnect immediately using TCP
|
||||||
torrent_peer* pi = peer_info_struct();
|
|
||||||
fast_reconnect(true);
|
fast_reconnect(true);
|
||||||
disconnect(e, op_connect, 0);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue