From 291ef2a2c9ac3ac889e078ff9321afea9c298d8f Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Wed, 9 Apr 2008 20:09:36 +0000 Subject: [PATCH] optimized torrent_handle to use a weak_ptr directly to the torrent object --- include/libtorrent/torrent.hpp | 2 +- include/libtorrent/torrent_handle.hpp | 24 +++--- src/session_impl.cpp | 20 +++-- src/torrent.cpp | 4 +- src/torrent_handle.cpp | 104 ++++++++++---------------- 5 files changed, 65 insertions(+), 89 deletions(-) diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 439a54378..84bbb53a6 100755 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -513,7 +513,7 @@ namespace libtorrent void replace_trackers(std::vector const& urls); - torrent_handle get_handle() const; + torrent_handle get_handle(); // LOGGING #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING diff --git a/include/libtorrent/torrent_handle.hpp b/include/libtorrent/torrent_handle.hpp index b191679a0..e60b855e1 100755 --- a/include/libtorrent/torrent_handle.hpp +++ b/include/libtorrent/torrent_handle.hpp @@ -282,7 +282,7 @@ namespace libtorrent friend struct aux::session_impl; friend class torrent; - torrent_handle(): m_ses(0), m_info_hash(0) {} + torrent_handle() {} void get_peer_info(std::vector& v) const; torrent_status status() const; @@ -407,34 +407,28 @@ namespace libtorrent // post condition: save_path() == save_path if true is returned void move_storage(fs::path const& save_path) const; - const sha1_hash& info_hash() const - { return m_info_hash; } + sha1_hash info_hash() const; bool operator==(const torrent_handle& h) const - { return m_info_hash == h.m_info_hash; } + { return m_torrent.lock() == h.m_torrent.lock(); } bool operator!=(const torrent_handle& h) const - { return m_info_hash != h.m_info_hash; } + { return m_torrent.lock() != h.m_torrent.lock(); } bool operator<(const torrent_handle& h) const - { return m_info_hash < h.m_info_hash; } + { return m_torrent.lock() < h.m_torrent.lock(); } private: - torrent_handle(aux::session_impl* s - , const sha1_hash& h) - : m_ses(s) - , m_info_hash(h) - { - TORRENT_ASSERT(m_ses != 0); - } + torrent_handle(boost::weak_ptr const& t) + : m_torrent(t) + {} #ifndef NDEBUG void check_invariant() const; #endif - aux::session_impl* m_ses; - sha1_hash m_info_hash; + boost::weak_ptr m_torrent; }; diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 51a8e6314..b1463b6c3 100755 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -1450,14 +1450,14 @@ namespace aux { i != end; ++i) { if (i->second->is_aborted()) continue; - ret.push_back(torrent_handle(this, i->first)); + ret.push_back(torrent_handle(i->second)); } return ret; } torrent_handle session_impl::find_torrent_handle(sha1_hash const& info_hash) { - return torrent_handle(this, info_hash); + return torrent_handle(find_torrent(info_hash)); } torrent_handle session_impl::add_torrent( @@ -1535,7 +1535,7 @@ namespace aux { m_torrents.insert(std::make_pair(ti->info_hash(), torrent_ptr)); - return torrent_handle(this, ti->info_hash()); + return torrent_handle(torrent_ptr); } void session_impl::check_torrent(boost::shared_ptr const& t) @@ -1605,20 +1605,26 @@ namespace aux { m_torrents.insert(std::make_pair(info_hash, torrent_ptr)); - return torrent_handle(this, info_hash); + return torrent_handle(torrent_ptr); } void session_impl::remove_torrent(const torrent_handle& h, int options) { - if (h.m_ses != this) return; - TORRENT_ASSERT(h.m_ses != 0); + boost::shared_ptr tptr = h.m_torrent.lock(); + if (!tptr) +#ifdef BOOST_NO_EXCEPTIONS + return; +#else + throw invalid_handle(); +#endif mutex_t::scoped_lock l(m_mutex); INVARIANT_CHECK; session_impl::torrent_map::iterator i = - m_torrents.find(h.m_info_hash); + m_torrents.find(tptr->torrent_file().info_hash()); + if (i != m_torrents.end()) { torrent& t = *i->second; diff --git a/src/torrent.cpp b/src/torrent.cpp index 361b303e9..07513fcfc 100755 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -2844,9 +2844,9 @@ namespace libtorrent } - torrent_handle torrent::get_handle() const + torrent_handle torrent::get_handle() { - return torrent_handle(&m_ses, m_torrent_file->info_hash()); + return torrent_handle(shared_from_this()); } session_settings const& torrent::settings() const diff --git a/src/torrent_handle.cpp b/src/torrent_handle.cpp index fe4accd0c..1d963060c 100755 --- a/src/torrent_handle.cpp +++ b/src/torrent_handle.cpp @@ -81,47 +81,41 @@ using libtorrent::aux::session_impl; #ifdef BOOST_NO_EXCEPTIONS #define TORRENT_FORWARD(call) \ - if (m_ses == 0) return; \ - session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); \ - boost::shared_ptr t = m_ses->find_torrent(m_info_hash).lock(); \ + boost::shared_ptr t = m_torrent.lock(); \ if (!t) return; \ + session_impl::mutex_t::scoped_lock l(t->session().m_mutex); \ t->call #define TORRENT_FORWARD_RETURN(call, def) \ - if (m_ses == 0) return def; \ - session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); \ - boost::shared_ptr t = m_ses->find_torrent(m_info_hash).lock(); \ + boost::shared_ptr t = m_torrent.lock(); \ if (!t) return def; \ + session_impl::mutex_t::scoped_lock l(t->session().m_mutex); \ return t->call #define TORRENT_FORWARD_RETURN2(call, def) \ - if (m_ses == 0) return def; \ - session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); \ - boost::shared_ptr t = m_ses->find_torrent(m_info_hash).lock(); \ + boost::shared_ptr t = m_torrent.lock(); \ if (!t) return def; \ + session_impl::mutex_t::scoped_lock l(t->session().m_mutex); \ t->call #else #define TORRENT_FORWARD(call) \ - if (m_ses == 0) throw_invalid_handle(); \ - session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); \ - boost::shared_ptr t = m_ses->find_torrent(m_info_hash).lock(); \ + boost::shared_ptr t = m_torrent.lock(); \ if (!t) throw_invalid_handle(); \ + session_impl::mutex_t::scoped_lock l(t->session().m_mutex); \ t->call #define TORRENT_FORWARD_RETURN(call, def) \ - if (m_ses == 0) throw_invalid_handle(); \ - session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); \ - boost::shared_ptr t = m_ses->find_torrent(m_info_hash).lock(); \ - if (!t) return def; \ + boost::shared_ptr t = m_torrent.lock(); \ + if (!t) throw_invalid_handle(); \ + session_impl::mutex_t::scoped_lock l(t->session().m_mutex); \ return t->call #define TORRENT_FORWARD_RETURN2(call, def) \ - if (m_ses == 0) throw_invalid_handle(); \ - session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); \ - boost::shared_ptr t = m_ses->find_torrent(m_info_hash).lock(); \ - if (!t) return def; \ + boost::shared_ptr t = m_torrent.lock(); \ + if (!t) throw_invalid_handle(); \ + session_impl::mutex_t::scoped_lock l(t->session().m_mutex); \ t->call #endif @@ -143,11 +137,17 @@ namespace libtorrent #ifndef NDEBUG void torrent_handle::check_invariant() const - { - } + {} #endif + sha1_hash torrent_handle::info_hash() const + { + INVARIANT_CHECK; + const static sha1_hash empty; + TORRENT_FORWARD_RETURN(torrent_file().info_hash(), empty); + } + void torrent_handle::set_max_uploads(int max_uploads) const { INVARIANT_CHECK; @@ -269,22 +269,7 @@ namespace libtorrent torrent_status torrent_handle::status() const { INVARIANT_CHECK; - - if (m_ses == 0) -#ifdef BOOST_NO_EXCEPTIONS - return torrent_status(); -#else - throw_invalid_handle(); -#endif - - session_impl::mutex_t::scoped_lock l(m_ses->m_mutex); - boost::shared_ptr t = m_ses->find_torrent(m_info_hash).lock(); - if (t) return t->status(); - -#ifndef BOOST_NO_EXCEPTIONS - throw_invalid_handle(); -#endif - return torrent_status(); + TORRENT_FORWARD_RETURN(status(), torrent_status()); } void torrent_handle::set_sequential_download(bool sd) const @@ -412,13 +397,16 @@ namespace libtorrent INVARIANT_CHECK; #ifdef BOOST_NO_EXCEPTIONS const static torrent_info empty; - if (m_ses == 0) return empty; -#else - if (m_ses == 0) throw_invalid_handle(); #endif - session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); - boost::shared_ptr t = m_ses->find_torrent(m_info_hash).lock(); - if (!t || !t->valid_metadata()) + boost::shared_ptr t = m_torrent.lock(); + if (!t) +#ifdef BOOST_NO_EXCEPTIONS + return empty; +#else + throw_invalid_handle(); +#endif + session_impl::mutex_t::scoped_lock l(t->session().m_mutex); + if (!t->valid_metadata()) #ifdef BOOST_NO_EXCEPTIONS return empty; #else @@ -430,25 +418,22 @@ namespace libtorrent bool torrent_handle::is_valid() const { INVARIANT_CHECK; - if (m_ses == 0) return false; - session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); - boost::shared_ptr t = m_ses->find_torrent(m_info_hash).lock(); - return t != 0; + return !m_torrent.expired(); } entry torrent_handle::write_resume_data() const { INVARIANT_CHECK; - if (m_ses == 0) + boost::shared_ptr t = m_torrent.lock(); + if (!t) #ifdef BOOST_NO_EXCEPTIONS return entry(); #else throw_invalid_handle(); #endif - session_impl::mutex_t::scoped_lock l(m_ses->m_mutex); - boost::shared_ptr t = m_ses->find_torrent(m_info_hash).lock(); - if (!t || !t->valid_metadata()) + session_impl::mutex_t::scoped_lock l(t->session().m_mutex); + if (!t->valid_metadata()) #ifdef BOOST_NO_EXCEPTIONS return entry(); #else @@ -580,24 +565,15 @@ namespace libtorrent { INVARIANT_CHECK; - if (m_ses == 0) -#ifdef BOOST_NO_EXCEPTIONS - return; -#else - throw_invalid_handle(); -#endif - session_impl::mutex_t::scoped_lock l(m_ses->m_mutex); - boost::shared_ptr t = m_ses->find_torrent(m_info_hash).lock(); - + boost::shared_ptr t = m_torrent.lock(); if (!t) - { #ifdef BOOST_NO_EXCEPTIONS return; #else throw_invalid_handle(); #endif - } - + session_impl::mutex_t::scoped_lock l(t->session().m_mutex); + peer_id id; std::fill(id.begin(), id.end(), 0); t->get_policy().peer_from_tracker(adr, id, source, 0);