fix for crashes when stopping or restarting DHT
This commit is contained in:
parent
fcc9c49608
commit
7888b72e12
|
@ -363,7 +363,7 @@ namespace libtorrent
|
|||
boost::posix_time::ptime m_last_tick;
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
boost::scoped_ptr<dht::dht_tracker> m_dht;
|
||||
boost::shared_ptr<dht::dht_tracker> m_dht;
|
||||
dht_settings m_dht_settings;
|
||||
#endif
|
||||
// the timer used to fire the second_tick
|
||||
|
|
|
@ -45,6 +45,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <boost/optional.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
#include <boost/detail/atomic_count.hpp>
|
||||
|
||||
#include "libtorrent/kademlia/node.hpp"
|
||||
#include "libtorrent/kademlia/node_id.hpp"
|
||||
|
@ -60,10 +62,18 @@ namespace libtorrent { namespace dht
|
|||
TORRENT_DECLARE_LOG(dht_tracker);
|
||||
#endif
|
||||
|
||||
struct dht_tracker;
|
||||
|
||||
TORRENT_EXPORT void intrusive_ptr_add_ref(dht_tracker const*);
|
||||
TORRENT_EXPORT void intrusive_ptr_release(dht_tracker const*);
|
||||
|
||||
struct dht_tracker
|
||||
{
|
||||
friend void intrusive_ptr_add_ref(dht_tracker const*);
|
||||
friend void intrusive_ptr_release(dht_tracker const*);
|
||||
dht_tracker(asio::io_service& ios, dht_settings const& settings
|
||||
, asio::ip::address listen_interface, entry const& bootstrap);
|
||||
void stop();
|
||||
|
||||
void add_node(udp::endpoint node);
|
||||
void add_node(std::pair<std::string, int> const& node);
|
||||
|
@ -80,6 +90,9 @@ namespace libtorrent { namespace dht
|
|||
void dht_status(session_status& s);
|
||||
|
||||
private:
|
||||
|
||||
boost::intrusive_ptr<dht_tracker> self()
|
||||
{ return boost::intrusive_ptr<dht_tracker>(this); }
|
||||
|
||||
void on_name_lookup(asio::error_code const& e
|
||||
, udp::resolver::iterator host);
|
||||
|
@ -116,6 +129,9 @@ namespace libtorrent { namespace dht
|
|||
|
||||
// used to resolve hostnames for nodes
|
||||
udp::resolver m_host_resolver;
|
||||
|
||||
// reference counter for intrusive_ptr
|
||||
mutable boost::detail::atomic_count m_refs;
|
||||
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
int m_replies_sent[5];
|
||||
|
|
|
@ -126,6 +126,22 @@ namespace
|
|||
|
||||
namespace libtorrent { namespace dht
|
||||
{
|
||||
|
||||
void intrusive_ptr_add_ref(dht_tracker const* c)
|
||||
{
|
||||
assert(c->m_refs >= 0);
|
||||
assert(c != 0);
|
||||
++c->m_refs;
|
||||
}
|
||||
|
||||
void intrusive_ptr_release(dht_tracker const* c)
|
||||
{
|
||||
assert(c->m_refs > 0);
|
||||
assert(c != 0);
|
||||
if (--c->m_refs == 0)
|
||||
delete c;
|
||||
}
|
||||
|
||||
#ifdef TORRENT_DHT_VERBOSE_LOGGING
|
||||
TORRENT_DEFINE_LOG(dht_tracker)
|
||||
#endif
|
||||
|
@ -146,6 +162,7 @@ namespace libtorrent { namespace dht
|
|||
, m_settings(settings)
|
||||
, m_refresh_bucket(160)
|
||||
, m_host_resolver(ios)
|
||||
, m_refs(0)
|
||||
{
|
||||
using boost::bind;
|
||||
|
||||
|
@ -187,20 +204,28 @@ namespace libtorrent { namespace dht
|
|||
} catch (std::exception&) {}
|
||||
}
|
||||
|
||||
m_dht.bootstrap(initial_nodes, bind(&dht_tracker::on_bootstrap, this));
|
||||
m_dht.bootstrap(initial_nodes, bind(&dht_tracker::on_bootstrap, self()));
|
||||
|
||||
m_socket.async_receive_from(asio::buffer(&m_in_buf[m_buffer][0]
|
||||
, m_in_buf[m_buffer].size()), m_remote_endpoint[m_buffer]
|
||||
, m_strand.wrap(bind(&dht_tracker::on_receive, this, _1, _2)));
|
||||
, m_strand.wrap(bind(&dht_tracker::on_receive, self(), _1, _2)));
|
||||
m_timer.expires_from_now(seconds(1));
|
||||
m_timer.async_wait(m_strand.wrap(bind(&dht_tracker::tick, this, _1)));
|
||||
m_timer.async_wait(m_strand.wrap(bind(&dht_tracker::tick, self(), _1)));
|
||||
|
||||
m_connection_timer.expires_from_now(seconds(10));
|
||||
m_connection_timer.async_wait(m_strand.wrap(
|
||||
bind(&dht_tracker::connection_timeout, this, _1)));
|
||||
bind(&dht_tracker::connection_timeout, self(), _1)));
|
||||
|
||||
m_refresh_timer.expires_from_now(minutes(15));
|
||||
m_refresh_timer.async_wait(m_strand.wrap(bind(&dht_tracker::refresh_timeout, this, _1)));
|
||||
m_refresh_timer.async_wait(m_strand.wrap(bind(&dht_tracker::refresh_timeout, self(), _1)));
|
||||
}
|
||||
|
||||
void dht_tracker::stop()
|
||||
{
|
||||
m_timer.cancel();
|
||||
m_connection_timer.cancel();
|
||||
m_refresh_timer.cancel();
|
||||
m_socket.close();
|
||||
}
|
||||
|
||||
void dht_tracker::dht_status(session_status& s)
|
||||
|
@ -215,7 +240,7 @@ namespace libtorrent { namespace dht
|
|||
if (e) return;
|
||||
time_duration d = m_dht.connection_timeout();
|
||||
m_connection_timer.expires_from_now(d);
|
||||
m_connection_timer.async_wait(m_strand.wrap(bind(&dht_tracker::connection_timeout, this, _1)));
|
||||
m_connection_timer.async_wait(m_strand.wrap(bind(&dht_tracker::connection_timeout, self(), _1)));
|
||||
}
|
||||
catch (std::exception& exc)
|
||||
{
|
||||
|
@ -233,7 +258,7 @@ namespace libtorrent { namespace dht
|
|||
time_duration d = m_dht.refresh_timeout();
|
||||
m_refresh_timer.expires_from_now(d);
|
||||
m_refresh_timer.async_wait(m_strand.wrap(
|
||||
bind(&dht_tracker::refresh_timeout, this, _1)));
|
||||
bind(&dht_tracker::refresh_timeout, self(), _1)));
|
||||
}
|
||||
catch (std::exception&)
|
||||
{
|
||||
|
@ -361,7 +386,7 @@ namespace libtorrent { namespace dht
|
|||
m_buffer = (m_buffer + 1) & 1;
|
||||
m_socket.async_receive_from(asio::buffer(&m_in_buf[m_buffer][0]
|
||||
, m_in_buf[m_buffer].size()), m_remote_endpoint[m_buffer]
|
||||
, m_strand.wrap(bind(&dht_tracker::on_receive, this, _1, _2)));
|
||||
, m_strand.wrap(bind(&dht_tracker::on_receive, self(), _1, _2)));
|
||||
|
||||
if (error) return;
|
||||
|
||||
|
@ -655,7 +680,7 @@ namespace libtorrent { namespace dht
|
|||
{
|
||||
udp::resolver::query q(node.first, lexical_cast<std::string>(node.second));
|
||||
m_host_resolver.async_resolve(q, m_strand.wrap(
|
||||
bind(&dht_tracker::on_name_lookup, this, _1, _2)));
|
||||
bind(&dht_tracker::on_name_lookup, self(), _1, _2)));
|
||||
}
|
||||
|
||||
void dht_tracker::on_name_lookup(asio::error_code const& e
|
||||
|
@ -673,7 +698,7 @@ namespace libtorrent { namespace dht
|
|||
{
|
||||
udp::resolver::query q(node.first, lexical_cast<std::string>(node.second));
|
||||
m_host_resolver.async_resolve(q, m_strand.wrap(
|
||||
bind(&dht_tracker::on_router_name_lookup, this, _1, _2)));
|
||||
bind(&dht_tracker::on_router_name_lookup, self(), _1, _2)));
|
||||
}
|
||||
|
||||
void dht_tracker::on_router_name_lookup(asio::error_code const& e
|
||||
|
|
|
@ -1507,7 +1507,11 @@ namespace libtorrent { namespace detail
|
|||
void session_impl::start_dht(entry const& startup_state)
|
||||
{
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
m_dht.reset();
|
||||
if (m_dht)
|
||||
{
|
||||
m_dht->stop();
|
||||
m_dht.reset();
|
||||
}
|
||||
m_dht.reset(new dht::dht_tracker(m_io_service
|
||||
, m_dht_settings, m_listen_interface.address()
|
||||
, startup_state));
|
||||
|
@ -1516,6 +1520,7 @@ namespace libtorrent { namespace detail
|
|||
void session_impl::stop_dht()
|
||||
{
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
m_dht->stop();
|
||||
m_dht.reset();
|
||||
}
|
||||
|
||||
|
|
|
@ -420,9 +420,11 @@ namespace libtorrent
|
|||
if (m_pimpl->info.num_files() == 1)
|
||||
{
|
||||
path single_file = m_pimpl->info.begin_files()->path;
|
||||
assert(!is_complete(single_file));
|
||||
if (single_file.has_branch_path())
|
||||
{
|
||||
std::string const& trunk = *single_file.begin();
|
||||
assert(single_file.begin() != single_file.end());
|
||||
std::string trunk = *single_file.begin();
|
||||
old_path = m_pimpl->save_path / trunk;
|
||||
new_path = save_path / trunk;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue