hold settings_pack by shared_ptr when passing it across thread boundaries. don't allocate it on the heap redundantly

This commit is contained in:
Arvid Norberg 2015-05-29 05:27:53 +00:00
parent e44c8e9002
commit 9b0313bd8e
10 changed files with 70 additions and 64 deletions

View File

@ -276,7 +276,8 @@ namespace libtorrent
libtorrent::session_settings deprecated_settings() const; libtorrent::session_settings deprecated_settings() const;
#endif #endif
void apply_settings_pack(settings_pack* pack); void apply_settings_pack(boost::shared_ptr<settings_pack> pack);
void apply_settings_pack_impl(settings_pack const& pack);
session_settings const& settings() const { return m_settings; } session_settings const& settings() const { return m_settings; }
#ifndef TORRENT_DISABLE_DHT #ifndef TORRENT_DISABLE_DHT

View File

@ -253,7 +253,7 @@ namespace libtorrent { namespace aux
virtual void trigger_auto_manage() = 0; virtual void trigger_auto_manage() = 0;
virtual void apply_settings_pack(settings_pack* pack) = 0; virtual void apply_settings_pack(boost::shared_ptr<settings_pack> pack) = 0;
virtual session_settings const& settings() const = 0; virtual session_settings const& settings() const = 0;
virtual void queue_tracker_request(tracker_request& req virtual void queue_tracker_request(tracker_request& req

View File

@ -290,7 +290,7 @@ namespace libtorrent
, int block_size = 16 * 1024); , int block_size = 16 * 1024);
~disk_io_thread(); ~disk_io_thread();
void set_settings(settings_pack* sett, alert_manager& alerts); void set_settings(settings_pack const* sett, alert_manager& alerts);
void set_num_threads(int i, bool wait = true); void set_num_threads(int i, bool wait = true);
void async_read(piece_manager* storage, peer_request const& r void async_read(piece_manager* storage, peer_request const& r
@ -586,7 +586,7 @@ namespace libtorrent
// dedicated to do hashing // dedicated to do hashing
condition_variable m_hash_job_cond; condition_variable m_hash_job_cond;
tailqueue m_queued_hash_jobs; tailqueue m_queued_hash_jobs;
// used to rate limit disk performance warnings // used to rate limit disk performance warnings
time_point m_last_disk_aio_performance_warning; time_point m_last_disk_aio_performance_warning;

View File

@ -39,9 +39,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/aux_/disable_warnings_push.hpp" #include "libtorrent/aux_/disable_warnings_push.hpp"
#include <boost/limits.hpp> #include <boost/limits.hpp>
#ifdef _MSC_VER
# include <eh.h>
#endif
#include "libtorrent/aux_/disable_warnings_pop.hpp" #include "libtorrent/aux_/disable_warnings_pop.hpp"
@ -50,7 +47,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/entry.hpp" #include "libtorrent/entry.hpp"
#include "libtorrent/version.hpp" #include "libtorrent/version.hpp"
#include "libtorrent/fingerprint.hpp" #include "libtorrent/fingerprint.hpp"
#include "libtorrent/disk_io_thread.hpp" #include "libtorrent/disk_io_thread.hpp" // for cached_piece_info
#include "libtorrent/peer_id.hpp" #include "libtorrent/peer_id.hpp"
#include "libtorrent/alert.hpp" // alert::error_notification #include "libtorrent/alert.hpp" // alert::error_notification
#include "libtorrent/add_torrent_params.hpp" #include "libtorrent/add_torrent_params.hpp"
@ -389,7 +386,7 @@ namespace libtorrent
#endif #endif
torrent_handle add_torrent(add_torrent_params const& params, error_code& ec); torrent_handle add_torrent(add_torrent_params const& params, error_code& ec);
void async_add_torrent(add_torrent_params const& params); void async_add_torrent(add_torrent_params const& params);
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
// deprecated in 0.14 // deprecated in 0.14

View File

@ -36,6 +36,10 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/entry.hpp" #include "libtorrent/entry.hpp"
#include <vector> #include <vector>
#ifndef TORRENT_NO_DEPRECATE
#include <boost/smart_ptr.hpp>
#endif
// OVERVIEW // OVERVIEW
// //
// You have some control over session configuration through the session::apply_settings() // You have some control over session configuration through the session::apply_settings()
@ -53,7 +57,7 @@ namespace libtorrent
struct settings_pack; struct settings_pack;
struct bdecode_node; struct bdecode_node;
TORRENT_EXTRA_EXPORT settings_pack* load_pack_from_dict(bdecode_node const& settings); TORRENT_EXTRA_EXPORT boost::shared_ptr<settings_pack> load_pack_from_dict(bdecode_node const& settings);
TORRENT_EXTRA_EXPORT void save_settings_to_dict(aux::session_settings const& s, entry::dictionary_type& sett); TORRENT_EXTRA_EXPORT void save_settings_to_dict(aux::session_settings const& s, entry::dictionary_type& sett);
TORRENT_EXTRA_EXPORT void apply_pack(settings_pack const* pack, aux::session_settings& sett, aux::session_impl* ses = 0); TORRENT_EXTRA_EXPORT void apply_pack(settings_pack const* pack, aux::session_settings& sett, aux::session_impl* ses = 0);
@ -62,7 +66,7 @@ namespace libtorrent
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
struct session_settings; struct session_settings;
settings_pack* load_pack_from_struct(aux::session_settings const& current, session_settings const& s); boost::shared_ptr<settings_pack> load_pack_from_struct(aux::session_settings const& current, session_settings const& s);
void load_struct_from_settings(aux::session_settings const& current, session_settings& ret); void load_struct_from_settings(aux::session_settings const& current, session_settings& ret);
#endif #endif
@ -183,7 +187,7 @@ namespace libtorrent
// when using a poxy, this is the hostname where the proxy is running // when using a poxy, this is the hostname where the proxy is running
// see proxy_type. // see proxy_type.
proxy_hostname, proxy_hostname,
// when using a proxy, these are the credentials (if any) to use whne // when using a proxy, these are the credentials (if any) to use whne
// connecting to it. see proxy_type // connecting to it. see proxy_type
proxy_username, proxy_username,

View File

@ -262,7 +262,7 @@ namespace libtorrent
m_blocks_to_reclaim.clear(); m_blocks_to_reclaim.clear();
} }
void disk_io_thread::set_settings(settings_pack* pack, alert_manager& alerts) void disk_io_thread::set_settings(settings_pack const* pack, alert_manager& alerts)
{ {
TORRENT_ASSERT(m_magic == 0x1337); TORRENT_ASSERT(m_magic == 0x1337);
mutex::scoped_lock l(m_cache_mutex); mutex::scoped_lock l(m_cache_mutex);

View File

@ -968,7 +968,7 @@ namespace libtorrent
void session::apply_settings(settings_pack const& s) void session::apply_settings(settings_pack const& s)
{ {
settings_pack* copy = new settings_pack(s); boost::shared_ptr<settings_pack> copy = boost::make_shared<settings_pack>(s);
TORRENT_ASYNC_CALL1(apply_settings_pack, copy); TORRENT_ASYNC_CALL1(apply_settings_pack, copy);
} }
@ -1209,14 +1209,14 @@ namespace libtorrent
p.set_bool(settings_pack::enable_lsd, true); p.set_bool(settings_pack::enable_lsd, true);
apply_settings(p); apply_settings(p);
} }
void session::start_natpmp() void session::start_natpmp()
{ {
settings_pack p; settings_pack p;
p.set_bool(settings_pack::enable_natpmp, true); p.set_bool(settings_pack::enable_natpmp, true);
apply_settings(p); apply_settings(p);
} }
void session::start_upnp() void session::start_upnp()
{ {
settings_pack p; settings_pack p;
@ -1230,22 +1230,22 @@ namespace libtorrent
p.set_bool(settings_pack::enable_lsd, false); p.set_bool(settings_pack::enable_lsd, false);
apply_settings(p); apply_settings(p);
} }
void session::stop_natpmp() void session::stop_natpmp()
{ {
settings_pack p; settings_pack p;
p.set_bool(settings_pack::enable_natpmp, false); p.set_bool(settings_pack::enable_natpmp, false);
apply_settings(p); apply_settings(p);
} }
void session::stop_upnp() void session::stop_upnp()
{ {
settings_pack p; settings_pack p;
p.set_bool(settings_pack::enable_upnp, false); p.set_bool(settings_pack::enable_upnp, false);
apply_settings(p); apply_settings(p);
} }
#endif #endif // TORRENT_NO_DEPRECATED
int session::add_port_mapping(protocol_type t, int external_port, int local_port) int session::add_port_mapping(protocol_type t, int external_port, int local_port)
{ {
return TORRENT_SYNC_CALL_RET3(int, add_port_mapping, int(t), external_port, local_port); return TORRENT_SYNC_CALL_RET3(int, add_port_mapping, int(t), external_port, local_port);
@ -1255,7 +1255,7 @@ namespace libtorrent
{ {
TORRENT_ASYNC_CALL1(delete_port_mapping, handle); TORRENT_ASYNC_CALL1(delete_port_mapping, handle);
} }
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
session_settings::session_settings(std::string const& user_agent_) session_settings::session_settings(std::string const& user_agent_)
{ {

View File

@ -425,9 +425,6 @@ namespace aux {
, m_need_auto_manage(false) , m_need_auto_manage(false)
, m_abort(false) , m_abort(false)
, m_paused(false) , m_paused(false)
#if TORRENT_USE_ASSERTS && defined BOOST_HAS_PTHREADS
, m_network_thread(0)
#endif
{ {
#if TORRENT_USE_ASSERTS #if TORRENT_USE_ASSERTS
m_posting_torrent_updates = false; m_posting_torrent_updates = false;
@ -448,6 +445,10 @@ namespace aux {
TORRENT_ASSERT_VAL(!ec, ec); TORRENT_ASSERT_VAL(!ec, ec);
} }
// This function is called by the creating thread, not in the message loop's
// / io_service thread.
// TODO: 2 is there a reason not to move all of this into init()? and just
// post it to the io_service?
void session_impl::start_session(settings_pack const& pack) void session_impl::start_session(settings_pack const& pack)
{ {
m_alerts.set_alert_mask(pack.get_int(settings_pack::alert_mask)); m_alerts.set_alert_mask(pack.get_int(settings_pack::alert_mask));
@ -546,7 +547,7 @@ namespace aux {
session_log(" generated peer ID: %s", m_peer_id.to_string().c_str()); session_log(" generated peer ID: %s", m_peer_id.to_string().c_str());
#endif #endif
settings_pack* copy = new settings_pack(pack); boost::shared_ptr<settings_pack> copy = boost::make_shared<settings_pack>(pack);
m_io_service.post(boost::bind(&session_impl::apply_settings_pack, this, copy)); m_io_service.post(boost::bind(&session_impl::apply_settings_pack, this, copy));
// call update_* after settings set initialized // call update_* after settings set initialized
m_io_service.post(boost::bind(&session_impl::init_settings, this)); m_io_service.post(boost::bind(&session_impl::init_settings, this));
@ -806,7 +807,7 @@ namespace aux {
settings = e->dict_find_dict("settings"); settings = e->dict_find_dict("settings");
if (settings) if (settings)
{ {
settings_pack* pack = load_pack_from_dict(settings); boost::shared_ptr<settings_pack> pack = load_pack_from_dict(settings);
apply_settings_pack(pack); apply_settings_pack(pack);
} }
@ -1520,22 +1521,24 @@ namespace aux {
return ret; return ret;
} }
// session_impl is responsible for deleting 'pack', but it // session_impl is responsible for deleting 'pack'
// will pass it on to the disk io thread, which will take void session_impl::apply_settings_pack(boost::shared_ptr<settings_pack> pack)
// over ownership of it {
void session_impl::apply_settings_pack(settings_pack* pack) apply_settings_pack_impl(*pack);
}
void session_impl::apply_settings_pack_impl(settings_pack const& pack)
{ {
bool reopen_listen_port = bool reopen_listen_port =
(pack->has_val(settings_pack::ssl_listen) (pack.has_val(settings_pack::ssl_listen)
&& pack->get_int(settings_pack::ssl_listen) && pack.get_int(settings_pack::ssl_listen)
!= m_settings.get_int(settings_pack::ssl_listen)) != m_settings.get_int(settings_pack::ssl_listen))
|| (pack->has_val(settings_pack::listen_interfaces) || (pack.has_val(settings_pack::listen_interfaces)
&& pack->get_str(settings_pack::listen_interfaces) && pack.get_str(settings_pack::listen_interfaces)
!= m_settings.get_str(settings_pack::listen_interfaces)); != m_settings.get_str(settings_pack::listen_interfaces));
apply_pack(pack, m_settings, this); apply_pack(&pack, m_settings, this);
m_disk_thread.set_settings(pack, m_alerts); m_disk_thread.set_settings(&pack, m_alerts);
delete pack;
if (reopen_listen_port) if (reopen_listen_port)
{ {
@ -1549,7 +1552,7 @@ namespace aux {
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_ASSERT(is_single_thread()); TORRENT_ASSERT(is_single_thread());
settings_pack* p = load_pack_from_struct(m_settings, s); boost::shared_ptr<settings_pack> p = load_pack_from_struct(m_settings, s);
apply_settings_pack(p); apply_settings_pack(p);
} }
@ -5696,44 +5699,44 @@ retry:
void session_impl::set_local_download_rate_limit(int bytes_per_second) void session_impl::set_local_download_rate_limit(int bytes_per_second)
{ {
settings_pack* p = new settings_pack; settings_pack p;
p->set_int(settings_pack::local_download_rate_limit, bytes_per_second); p.set_int(settings_pack::local_download_rate_limit, bytes_per_second);
apply_settings_pack(p); apply_settings_pack_impl(p);
} }
void session_impl::set_local_upload_rate_limit(int bytes_per_second) void session_impl::set_local_upload_rate_limit(int bytes_per_second)
{ {
settings_pack* p = new settings_pack; settings_pack p;
p->set_int(settings_pack::local_upload_rate_limit, bytes_per_second); p.set_int(settings_pack::local_upload_rate_limit, bytes_per_second);
apply_settings_pack(p); apply_settings_pack_impl(p);
} }
void session_impl::set_download_rate_limit(int bytes_per_second) void session_impl::set_download_rate_limit(int bytes_per_second)
{ {
settings_pack* p = new settings_pack; settings_pack p;
p->set_int(settings_pack::download_rate_limit, bytes_per_second); p.set_int(settings_pack::download_rate_limit, bytes_per_second);
apply_settings_pack(p); apply_settings_pack_impl(p);
} }
void session_impl::set_upload_rate_limit(int bytes_per_second) void session_impl::set_upload_rate_limit(int bytes_per_second)
{ {
settings_pack* p = new settings_pack; settings_pack p;
p->set_int(settings_pack::upload_rate_limit, bytes_per_second); p.set_int(settings_pack::upload_rate_limit, bytes_per_second);
apply_settings_pack(p); apply_settings_pack_impl(p);
} }
void session_impl::set_max_connections(int limit) void session_impl::set_max_connections(int limit)
{ {
settings_pack* p = new settings_pack; settings_pack p;
p->set_int(settings_pack::connections_limit, limit); p.set_int(settings_pack::connections_limit, limit);
apply_settings_pack(p); apply_settings_pack_impl(p);
} }
void session_impl::set_max_uploads(int limit) void session_impl::set_max_uploads(int limit)
{ {
settings_pack* p = new settings_pack; settings_pack p;
p->set_int(settings_pack::unchoke_slots_limit, limit); p.set_int(settings_pack::unchoke_slots_limit, limit);
apply_settings_pack(p); apply_settings_pack_impl(p);
} }
int session_impl::local_upload_rate_limit() const int session_impl::local_upload_rate_limit() const

View File

@ -390,9 +390,9 @@ namespace libtorrent
return ""; return "";
} }
settings_pack* load_pack_from_dict(bdecode_node const& settings) boost::shared_ptr<settings_pack> load_pack_from_dict(bdecode_node const& settings)
{ {
settings_pack* pack = new settings_pack; boost::shared_ptr<settings_pack> pack = boost::make_shared<settings_pack>();
for (int i = 0; i < settings.dict_size(); ++i) for (int i = 0; i < settings.dict_size(); ++i)
{ {
@ -462,9 +462,10 @@ namespace libtorrent
} }
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
settings_pack* load_pack_from_struct(aux::session_settings const& current, session_settings const& s) boost::shared_ptr<settings_pack> load_pack_from_struct(
aux::session_settings const& current, session_settings const& s)
{ {
settings_pack* p = new settings_pack; boost::shared_ptr<settings_pack> p = boost::make_shared<settings_pack>();
for (int i = 0; i < settings_pack::num_string_settings; ++i) for (int i = 0; i < settings_pack::num_string_settings; ++i)
{ {
@ -474,7 +475,7 @@ namespace libtorrent
if (val == current.get_str(setting_name)) continue; if (val == current.get_str(setting_name)) continue;
p->set_str(setting_name, val); p->set_str(setting_name, val);
} }
for (int i = 0; i < settings_pack::num_int_settings; ++i) for (int i = 0; i < settings_pack::num_int_settings; ++i)
{ {
if (int_settings[i].offset == 0) continue; if (int_settings[i].offset == 0) continue;
@ -521,7 +522,7 @@ namespace libtorrent
std::string& val = *(std::string*)(((char*)&ret) + str_settings[i].offset); std::string& val = *(std::string*)(((char*)&ret) + str_settings[i].offset);
val = current.get_str(settings_pack::string_type_base + i); val = current.get_str(settings_pack::string_type_base + i);
} }
for (int i = 0; i < settings_pack::num_int_settings; ++i) for (int i = 0; i < settings_pack::num_int_settings; ++i)
{ {
if (int_settings[i].offset == 0) continue; if (int_settings[i].offset == 0) continue;

View File

@ -2771,7 +2771,7 @@ namespace libtorrent
#ifndef TORRENT_NO_DEPRECATE #ifndef TORRENT_NO_DEPRECATE
void torrent::use_interface(std::string net_interfaces) void torrent::use_interface(std::string net_interfaces)
{ {
settings_pack* p = new settings_pack; boost::shared_ptr<settings_pack> p = boost::make_shared<settings_pack>();
p->set_str(settings_pack::outgoing_interfaces, net_interfaces); p->set_str(settings_pack::outgoing_interfaces, net_interfaces);
m_ses.apply_settings_pack(p); m_ses.apply_settings_pack(p);
} }
@ -2792,7 +2792,7 @@ namespace libtorrent
void torrent::on_tracker_announce() void torrent::on_tracker_announce()
{ {
TORRENT_ASSERT(is_single_thread()); TORRENT_ASSERT(is_single_thread());
m_waiting_tracker = false; m_waiting_tracker = false;
if (m_abort) return; if (m_abort) return;
announce_with_tracker(); announce_with_tracker();
} }