upnp, natpmp and lsd now have proper lifetime management by using intrusive_ptr

This commit is contained in:
Arvid Norberg 2007-09-29 21:31:51 +00:00
parent c65f33dfcc
commit 0048f343cd
9 changed files with 42 additions and 33 deletions

View File

@ -540,9 +540,9 @@ namespace libtorrent
pe_settings m_pe_settings;
#endif
boost::shared_ptr<natpmp> m_natpmp;
boost::shared_ptr<upnp> m_upnp;
boost::shared_ptr<lsd> m_lsd;
boost::intrusive_ptr<natpmp> m_natpmp;
boost::intrusive_ptr<upnp> m_upnp;
boost::intrusive_ptr<lsd> m_lsd;
// the timer used to fire the second_tick
deadline_timer m_timer;

View File

@ -60,6 +60,12 @@ namespace libtorrent
delete static_cast<T const*>(s);
}
boost::intrusive_ptr<T> self()
{ return boost::intrusive_ptr<T>((T*)this); }
boost::intrusive_ptr<const T> self() const
{ return boost::intrusive_ptr<const T>((T const*)this); }
int refcount() const { return m_refs; }
intrusive_ptr_base(): m_refs(0) {}

View File

@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/socket.hpp"
#include "libtorrent/peer_id.hpp"
#include "libtorrent/broadcast_socket.hpp"
#include "libtorrent/intrusive_ptr_base.hpp"
#include <boost/function.hpp>
#include <boost/noncopyable.hpp>
@ -52,7 +53,7 @@ namespace libtorrent
typedef boost::function<void(tcp::endpoint, sha1_hash)> peer_callback_t;
class lsd : boost::noncopyable
class lsd : public intrusive_ptr_base<lsd>
{
public:
lsd(io_service& ios, address const& listen_interface

View File

@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
#define TORRENT_NATPMP_HPP
#include "libtorrent/socket.hpp"
#include "libtorrent/intrusive_ptr_base.hpp"
#include <boost/function.hpp>
@ -49,7 +50,7 @@ namespace libtorrent
// std::string: error message
typedef boost::function<void(int, int, std::string const&)> portmap_callback_t;
class natpmp
class natpmp : public intrusive_ptr_base<natpmp>
{
public:
natpmp(io_service& ios, address const& listen_interface, portmap_callback_t const& cb);

View File

@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/broadcast_socket.hpp"
#include "libtorrent/http_connection.hpp"
#include "libtorrent/connection_queue.hpp"
#include "libtorrent/intrusive_ptr_base.hpp"
#include <boost/function.hpp>
#include <boost/noncopyable.hpp>
@ -62,7 +63,7 @@ namespace libtorrent
// std::string: error message
typedef boost::function<void(int, int, std::string const&)> portmap_callback_t;
class upnp : boost::noncopyable
class upnp : public intrusive_ptr_base<upnp>
{
public:
upnp(io_service& ios, connection_queue& cc

View File

@ -58,7 +58,7 @@ lsd::lsd(io_service& ios, address const& listen_interface
: m_callback(cb)
, m_retry_count(0)
, m_socket(ios, udp::endpoint(address_v4::from_string("239.192.152.143"), 6771)
, bind(&lsd::on_announce, this, _1, _2, _3))
, bind(&lsd::on_announce, self(), _1, _2, _3))
, m_broadcast_timer(ios)
, m_disabled(false)
{
@ -96,7 +96,7 @@ void lsd::announce(sha1_hash const& ih, int listen_port)
#endif
m_broadcast_timer.expires_from_now(milliseconds(250 * m_retry_count));
m_broadcast_timer.async_wait(bind(&lsd::resend_announce, this, _1, msg));
m_broadcast_timer.async_wait(bind(&lsd::resend_announce, self(), _1, msg));
}
void lsd::resend_announce(asio::error_code const& e, std::string msg) try
@ -111,7 +111,7 @@ void lsd::resend_announce(asio::error_code const& e, std::string msg) try
return;
m_broadcast_timer.expires_from_now(milliseconds(250 * m_retry_count));
m_broadcast_timer.async_wait(bind(&lsd::resend_announce, this, _1, msg));
m_broadcast_timer.async_wait(bind(&lsd::resend_announce, self(), _1, msg));
}
catch (std::exception&)
{}

View File

@ -161,7 +161,7 @@ void natpmp::update_mapping(int i, int port)
m_retry_count = 0;
send_map_request(i);
m_socket.async_receive_from(asio::buffer(&m_response_buffer, 16)
, m_remote, bind(&natpmp::on_reply, this, _1, _2));
, m_remote, bind(&natpmp::on_reply, self(), _1, _2));
}
}
@ -194,7 +194,7 @@ void natpmp::send_map_request(int i) try
// linear back-off instead of exponential
++m_retry_count;
m_send_timer.expires_from_now(milliseconds(250 * m_retry_count));
m_send_timer.async_wait(bind(&natpmp::resend_request, this, i, _1));
m_send_timer.async_wait(bind(&natpmp::resend_request, self(), i, _1));
}
catch (std::exception& e)
{
@ -227,7 +227,7 @@ void natpmp::on_reply(asio::error_code const& e
if (m_remote != m_nat_endpoint)
{
m_socket.async_receive_from(asio::buffer(&m_response_buffer, 16)
, m_remote, bind(&natpmp::on_reply, this, _1, _2));
, m_remote, bind(&natpmp::on_reply, self(), _1, _2));
return;
}
@ -346,7 +346,7 @@ void natpmp::update_expiration_timer()
if (min_index >= 0)
{
m_refresh_timer.expires_from_now(min_expire - now);
m_refresh_timer.async_wait(bind(&natpmp::mapping_expired, this, _1, min_index));
m_refresh_timer.async_wait(bind(&natpmp::mapping_expired, self(), _1, min_index));
}
}
@ -369,7 +369,7 @@ void natpmp::refresh_mapping(int i)
m_retry_count = 0;
send_map_request(i);
m_socket.async_receive_from(asio::buffer(&m_response_buffer, 16)
, m_remote, bind(&natpmp::on_reply, this, _1, _2));
, m_remote, bind(&natpmp::on_reply, self(), _1, _2));
}
}

View File

@ -2200,9 +2200,9 @@ namespace detail
INVARIANT_CHECK;
m_lsd.reset(new lsd(m_io_service
m_lsd = new lsd(m_io_service
, m_listen_interface.address()
, bind(&session_impl::on_lsd_peer, this, _1, _2)));
, bind(&session_impl::on_lsd_peer, this, _1, _2));
}
void session_impl::start_natpmp()
@ -2211,10 +2211,10 @@ namespace detail
INVARIANT_CHECK;
m_natpmp.reset(new natpmp(m_io_service
m_natpmp = new natpmp(m_io_service
, m_listen_interface.address()
, bind(&session_impl::on_port_mapping
, this, _1, _2, _3)));
, this, _1, _2, _3));
m_natpmp->set_mappings(m_listen_interface.port(),
#ifndef TORRENT_DISABLE_DHT
@ -2229,11 +2229,11 @@ namespace detail
INVARIANT_CHECK;
m_upnp.reset(new upnp(m_io_service, m_half_open
m_upnp = new upnp(m_io_service, m_half_open
, m_listen_interface.address()
, m_settings.user_agent
, bind(&session_impl::on_port_mapping
, this, _1, _2, _3)));
, this, _1, _2, _3));
m_upnp->set_mappings(m_listen_interface.port(),
#ifndef TORRENT_DISABLE_DHT
@ -2245,7 +2245,7 @@ namespace detail
void session_impl::stop_lsd()
{
mutex_t::scoped_lock l(m_mutex);
m_lsd.reset();
m_lsd = 0;
}
void session_impl::stop_natpmp()
@ -2253,7 +2253,7 @@ namespace detail
mutex_t::scoped_lock l(m_mutex);
if (m_natpmp.get())
m_natpmp->close();
m_natpmp.reset();
m_natpmp = 0;
}
void session_impl::stop_upnp()
@ -2261,7 +2261,7 @@ namespace detail
mutex_t::scoped_lock l(m_mutex);
if (m_upnp.get())
m_upnp->close();
m_upnp.reset();
m_upnp = 0;
}
void session_impl::free_disk_buffer(char* buf)

View File

@ -70,7 +70,7 @@ upnp::upnp(io_service& ios, connection_queue& cc
, m_io_service(ios)
, m_strand(ios)
, m_socket(ios, udp::endpoint(address_v4::from_string("239.255.255.250"), 1900)
, m_strand.wrap(bind(&upnp::on_reply, this, _1, _2, _3)), false)
, m_strand.wrap(bind(&upnp::on_reply, self(), _1, _2, _3)), false)
, m_broadcast_timer(ios)
, m_refresh_timer(ios)
, m_disabled(false)
@ -119,7 +119,7 @@ void upnp::discover_device() try
++m_retry_count;
m_broadcast_timer.expires_from_now(milliseconds(250 * m_retry_count));
m_broadcast_timer.async_wait(m_strand.wrap(bind(&upnp::resend_request
, this, _1)));
, self(), _1)));
#ifdef TORRENT_UPNP_LOGGING
m_log << time_now_string()
@ -203,7 +203,7 @@ try
try
{
d.upnp_connection.reset(new http_connection(m_io_service
, m_cc, m_strand.wrap(bind(&upnp::on_upnp_xml, this, _1, _2
, m_cc, m_strand.wrap(bind(&upnp::on_upnp_xml, self(), _1, _2
, boost::ref(d)))));
d.upnp_connection->get(d.url);
}
@ -393,7 +393,7 @@ try
try
{
d.upnp_connection.reset(new http_connection(m_io_service
, m_cc, m_strand.wrap(bind(&upnp::on_upnp_xml, this, _1, _2
, m_cc, m_strand.wrap(bind(&upnp::on_upnp_xml, self(), _1, _2
, boost::ref(d)))));
d.upnp_connection->get(d.url);
}
@ -480,9 +480,9 @@ void upnp::map_port(rootdevice& d, int i)
assert(d.service_namespace);
d.upnp_connection.reset(new http_connection(m_io_service
, m_cc, m_strand.wrap(bind(&upnp::on_upnp_map_response, this, _1, _2
, m_cc, m_strand.wrap(bind(&upnp::on_upnp_map_response, self(), _1, _2
, boost::ref(d), i)), true
, bind(&upnp::create_port_mapping, this, _1, boost::ref(d), i)));
, bind(&upnp::create_port_mapping, self(), _1, boost::ref(d), i)));
d.upnp_connection->start(d.hostname, boost::lexical_cast<std::string>(d.port)
, seconds(10));
@ -523,9 +523,9 @@ void upnp::unmap_port(rootdevice& d, int i)
return;
}
d.upnp_connection.reset(new http_connection(m_io_service
, m_cc, m_strand.wrap(bind(&upnp::on_upnp_unmap_response, this, _1, _2
, m_cc, m_strand.wrap(bind(&upnp::on_upnp_unmap_response, self(), _1, _2
, boost::ref(d), i)), true
, bind(&upnp::delete_port_mapping, this, boost::ref(d), i)));
, bind(&upnp::delete_port_mapping, self(), boost::ref(d), i)));
d.upnp_connection->start(d.hostname, boost::lexical_cast<std::string>(d.port)
, seconds(10));
@ -851,7 +851,7 @@ void upnp::on_upnp_map_response(asio::error_code const& e
|| next_expire > d.mapping[mapping].expires)
{
m_refresh_timer.expires_at(d.mapping[mapping].expires);
m_refresh_timer.async_wait(m_strand.wrap(bind(&upnp::on_expire, this, _1)));
m_refresh_timer.async_wait(m_strand.wrap(bind(&upnp::on_expire, self(), _1)));
}
}
else
@ -962,7 +962,7 @@ void upnp::on_expire(asio::error_code const& e) try
if (next_expire != max_time())
{
m_refresh_timer.expires_at(next_expire);
m_refresh_timer.async_wait(m_strand.wrap(bind(&upnp::on_expire, this, _1)));
m_refresh_timer.async_wait(m_strand.wrap(bind(&upnp::on_expire, self(), _1)));
}
}
catch (std::exception&)