From cd10e9bbaa6c0d59664da89ce64fd3dd20ad96b3 Mon Sep 17 00:00:00 2001 From: Marcos Pinto Date: Wed, 19 Sep 2007 20:39:29 +0000 Subject: [PATCH] many fixes in libtorrent sync 1586 --- .../include/libtorrent/bandwidth_manager.hpp | 22 +- libtorrent/include/libtorrent/storage.hpp | 4 +- .../include/libtorrent/torrent_handle.hpp | 2 + libtorrent/src/peer_connection.cpp | 4 +- libtorrent/src/policy.cpp | 45 ++-- libtorrent/src/storage.cpp | 17 +- libtorrent/src/torrent.cpp | 17 +- libtorrent/src/torrent_handle.cpp | 240 +++++++++++++----- 8 files changed, 251 insertions(+), 100 deletions(-) diff --git a/libtorrent/include/libtorrent/bandwidth_manager.hpp b/libtorrent/include/libtorrent/bandwidth_manager.hpp index 1e1b29699..d84f68bfe 100644 --- a/libtorrent/include/libtorrent/bandwidth_manager.hpp +++ b/libtorrent/include/libtorrent/bandwidth_manager.hpp @@ -180,12 +180,8 @@ struct bandwidth_manager , m_limit(bandwidth_limit::inf) , m_current_quota(0) , m_channel(channel) - { - -#ifndef NDEBUG - m_in_hand_out_bandwidth = false; -#endif - } + , m_in_hand_out_bandwidth(false) + {} void throttle(int limit) throw() { @@ -333,10 +329,11 @@ private: void hand_out_bandwidth() throw() { -#ifndef NDEBUG - assert(m_in_hand_out_bandwidth == false); - + // if we're already handing out bandwidth, just return back + // to the loop further down on the callstack + if (m_in_hand_out_bandwidth) return; m_in_hand_out_bandwidth = true; +#ifndef NDEBUG try { #endif INVARIANT_CHECK; @@ -451,9 +448,8 @@ private: } catch (std::exception& e) { assert(false); }; - - m_in_hand_out_bandwidth = false; #endif + m_in_hand_out_bandwidth = false; } @@ -487,9 +483,9 @@ private: // that bandwidth is assigned to (upload or download) int m_channel; -#ifndef NDEBUG + // this is true while we're in the hand_out_bandwidth loop + // to prevent recursive invocations to interfere bool m_in_hand_out_bandwidth; -#endif }; diff --git a/libtorrent/include/libtorrent/storage.hpp b/libtorrent/include/libtorrent/storage.hpp index 505be8b6c..b9a25d491 100755 --- a/libtorrent/include/libtorrent/storage.hpp +++ b/libtorrent/include/libtorrent/storage.hpp @@ -344,7 +344,8 @@ namespace libtorrent std::multimap m_hash_to_piece; // this map contains partial hashes for downloading - // pieces. + // pieces. This is only accessed from within the + // disk-io thread. std::map m_piece_hasher; disk_io_thread& m_io_thread; @@ -362,3 +363,4 @@ namespace libtorrent #endif // TORRENT_STORAGE_HPP_INCLUDED + diff --git a/libtorrent/include/libtorrent/torrent_handle.hpp b/libtorrent/include/libtorrent/torrent_handle.hpp index 31a39c38e..4b1ac4b0b 100755 --- a/libtorrent/include/libtorrent/torrent_handle.hpp +++ b/libtorrent/include/libtorrent/torrent_handle.hpp @@ -399,6 +399,7 @@ namespace libtorrent , m_info_hash(h) { assert(m_ses != 0); + assert(m_chk != 0); } #ifndef NDEBUG @@ -416,3 +417,4 @@ namespace libtorrent #endif // TORRENT_TORRENT_HANDLE_HPP_INCLUDED + diff --git a/libtorrent/src/peer_connection.cpp b/libtorrent/src/peer_connection.cpp index 59031cc18..ab5476e85 100755 --- a/libtorrent/src/peer_connection.cpp +++ b/libtorrent/src/peer_connection.cpp @@ -1952,7 +1952,6 @@ namespace libtorrent } t->remove_peer(this); - m_torrent.reset(); } @@ -2856,6 +2855,8 @@ namespace libtorrent return; } + assert(t->connection_for(remote()) != 0 || m_in_constructor); + if (!m_in_constructor && t->connection_for(remote()) != this && !m_ses.settings().allow_multiple_connections_per_ip) { @@ -3021,3 +3022,4 @@ namespace libtorrent } } + diff --git a/libtorrent/src/policy.cpp b/libtorrent/src/policy.cpp index 6e81da0d5..ca82a3868 100755 --- a/libtorrent/src/policy.cpp +++ b/libtorrent/src/policy.cpp @@ -138,28 +138,28 @@ namespace return free_upload; } - struct match_peer_ip + struct match_peer_address { - match_peer_ip(address const& ip) - : m_ip(ip) + match_peer_address(address const& addr) + : m_addr(addr) {} bool operator()(policy::peer const& p) const - { return p.ip.address() == m_ip; } + { return p.ip.address() == m_addr; } - address const& m_ip; + address const& m_addr; }; - struct match_peer_id + struct match_peer_endpoint { - match_peer_id(peer_id const& id_) - : m_id(id_) + match_peer_endpoint(tcp::endpoint const& ep) + : m_ep(ep) {} bool operator()(policy::peer const& p) const - { return p.connection && p.connection->pid() == m_id; } + { return p.ip == m_ep; } - peer_id const& m_id; + tcp::endpoint const& m_ep; }; struct match_peer_connection @@ -939,7 +939,7 @@ namespace libtorrent i = std::find_if( m_peers.begin() , m_peers.end() - , match_peer_ip(c.remote().address())); + , match_peer_address(c.remote().address())); } if (i != m_peers.end()) @@ -1029,14 +1029,14 @@ namespace libtorrent i = std::find_if( m_peers.begin() , m_peers.end() - , match_peer_id(pid)); + , match_peer_endpoint(remote)); } else { i = std::find_if( m_peers.begin() , m_peers.end() - , match_peer_ip(remote.address())); + , match_peer_address(remote.address())); } if (i == m_peers.end()) @@ -1291,9 +1291,15 @@ namespace libtorrent try { + INVARIANT_CHECK; p->connected = time_now(); p->connection = m_torrent->connect_to_peer(&*p); - if (p->connection == 0) return false; + assert(p->connection == m_torrent->connection_for(p->ip)); + if (p->connection == 0) + { + ++p->failcount; + return false; + } p->connection->add_stat(p->prev_amount_download, p->prev_amount_upload); p->prev_amount_download = 0; p->prev_amount_upload = 0; @@ -1305,6 +1311,7 @@ namespace libtorrent (*m_torrent->session().m_logger) << "*** CONNECTION FAILED '" << e.what() << "'\n"; #endif + std::cerr << e.what() << std::endl; ++p->failcount; return false; } @@ -1402,15 +1409,22 @@ namespace libtorrent int nonempty_connections = 0; std::set
unique_test; + std::set unique_test2; for (const_iterator i = m_peers.begin(); i != m_peers.end(); ++i) { peer const& p = *i; if (!m_torrent->settings().allow_multiple_connections_per_ip) assert(unique_test.find(p.ip.address()) == unique_test.end()); + assert(unique_test2.find(p.ip) == unique_test2.end()); unique_test.insert(p.ip.address()); + unique_test2.insert(p.ip); ++total_connections; - if (!p.connection) continue; + if (!p.connection) + { +// assert(m_torrent->connection_for(p.ip) == 0); + continue; + } if (!m_torrent->settings().allow_multiple_connections_per_ip) { std::vector conns; @@ -1537,3 +1551,4 @@ namespace libtorrent } } + diff --git a/libtorrent/src/storage.cpp b/libtorrent/src/storage.cpp index 7124fab96..96159391c 100755 --- a/libtorrent/src/storage.cpp +++ b/libtorrent/src/storage.cpp @@ -400,16 +400,20 @@ namespace libtorrent partial.update(&m_scratch_buffer[0], ph.offset); whole.update(&m_scratch_buffer[0], slot_size1); hasher partial_copy = ph.h; + std::cerr << partial_copy.final() << " " << partial.final() << std::endl; assert(ph.offset == 0 || partial_copy.final() == partial.final()); #endif int slot_size = piece_size - ph.offset; - if (slot_size == 0) return ph.h.final(); + if (slot_size == 0) + { + assert(ph.h.final() == whole.final()); + return ph.h.final(); + } m_scratch_buffer.resize(slot_size); read_impl(&m_scratch_buffer[0], slot, ph.offset, slot_size, true); ph.h.update(&m_scratch_buffer[0], slot_size); - sha1_hash ret = ph.h.final(); - assert(whole.final() == ret); - return ret; + assert(whole.final() == ph.h.final()); + return ph.h.final(); } void storage::initialize(bool allocate_files) @@ -996,9 +1000,6 @@ namespace libtorrent int err = statfs(query_path.native_directory_string().c_str(), &buf); if (err == 0) { -#ifndef NDEBUG - std::cerr << "buf.f_type " << std::hex << buf.f_type << std::endl; -#endif switch (buf.f_type) { case 0x5346544e: // NTFS @@ -1297,6 +1298,7 @@ namespace libtorrent if (i != m_piece_hasher.end()) { assert(i->second.offset > 0); + assert(offset >= i->second.offset); if (offset == i->second.offset) { i->second.offset += size; @@ -2211,3 +2213,4 @@ namespace libtorrent #endif } // namespace libtorrent + diff --git a/libtorrent/src/torrent.cpp b/libtorrent/src/torrent.cpp index ddf8a9164..221697284 100755 --- a/libtorrent/src/torrent.cpp +++ b/libtorrent/src/torrent.cpp @@ -1653,6 +1653,7 @@ namespace libtorrent assert(m_connections.find(a) == m_connections.end()); // add the newly connected peer to this torrent's peer list + assert(m_connections.find(a) == m_connections.end()); m_connections.insert( std::make_pair(a, boost::get_pointer(c))); m_ses.m_connections.insert(std::make_pair(s, c)); @@ -1669,8 +1670,8 @@ namespace libtorrent #endif // TODO: post an error alert! - std::map::iterator i = m_connections.find(a); - if (i != m_connections.end()) m_connections.erase(i); +// std::map::iterator i = m_connections.find(a); +// if (i != m_connections.end()) m_connections.erase(i); m_ses.connection_failed(s, a, e.what()); c->disconnect(); } @@ -1857,6 +1858,8 @@ namespace libtorrent try { + assert(m_connections.find(a) == m_connections.end()); + // add the newly connected peer to this torrent's peer list m_connections.insert( std::make_pair(a, boost::get_pointer(c))); @@ -1869,6 +1872,7 @@ namespace libtorrent } catch (std::exception& e) { + assert(false); // TODO: post an error alert! std::map::iterator i = m_connections.find(a); if (i != m_connections.end()) m_connections.erase(i); @@ -1925,6 +1929,7 @@ namespace libtorrent = m_connections.find(p->remote()); if (c != m_connections.end()) { + assert(p != c->second); // we already have a peer_connection to this ip. // It may currently be waiting for completing a // connection attempt that might fail. So, @@ -1948,6 +1953,7 @@ namespace libtorrent throw protocol_error("session is closing"); } + assert(m_connections.find(p->remote()) == m_connections.end()); peer_iterator ci = m_connections.insert( std::make_pair(p->remote(), p)).first; try @@ -2408,6 +2414,12 @@ namespace libtorrent assert(m_abort || m_have_pieces.empty()); } +/* for (policy::const_iterator i = m_policy->begin_peer() + , end(m_policy->end_peer()); i != end; ++i) + { + assert(i->connection == const_cast(this)->connection_for(i->ip)); + } +*/ size_type total_done = quantized_bytes_done(); if (m_torrent_file->is_valid()) { @@ -2925,3 +2937,4 @@ namespace libtorrent } + diff --git a/libtorrent/src/torrent_handle.cpp b/libtorrent/src/torrent_handle.cpp index 3cf1f2bac..1ca3a27ef 100755 --- a/libtorrent/src/torrent_handle.cpp +++ b/libtorrent/src/torrent_handle.cpp @@ -94,18 +94,11 @@ namespace libtorrent , aux::checker_impl* chk , sha1_hash const& hash) { - if (ses == 0) throw_invalid_handle(); + aux::piece_checker_data* d = chk->find_torrent(hash); + if (d != 0) return d->torrent_ptr; - if (chk) - { - aux::piece_checker_data* d = chk->find_torrent(hash); - if (d != 0) return d->torrent_ptr; - } - - { - boost::shared_ptr t = ses->find_torrent(hash).lock(); - if (t) return t; - } + boost::shared_ptr t = ses->find_torrent(hash).lock(); + if (t) return t; // throwing directly instead of calling // the throw_invalid_handle() function @@ -118,7 +111,7 @@ namespace libtorrent void torrent_handle::check_invariant() const { - assert((m_ses == 0 && m_chk == 0) || (m_ses != 0)); + assert((m_ses == 0 && m_chk == 0) || (m_ses != 0 && m_chk != 0)); } #endif @@ -127,6 +120,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + assert(max_uploads >= 2 || max_uploads == -1); session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); @@ -138,6 +134,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); find_torrent(m_ses, m_chk, m_info_hash)->use_interface(net_interface); @@ -147,6 +146,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + assert(max_connections >= 2 || max_connections == -1); session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); @@ -159,6 +161,9 @@ namespace libtorrent INVARIANT_CHECK; assert(limit >= -1); + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); find_torrent(m_ses, m_chk, m_info_hash)->set_peer_upload_limit(ip, limit); @@ -169,6 +174,9 @@ namespace libtorrent INVARIANT_CHECK; assert(limit >= -1); + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); find_torrent(m_ses, m_chk, m_info_hash)->set_peer_download_limit(ip, limit); @@ -178,6 +186,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + assert(limit >= -1); session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); @@ -188,6 +199,10 @@ namespace libtorrent int torrent_handle::upload_limit() const { INVARIANT_CHECK; + + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); return find_torrent(m_ses, m_chk, m_info_hash)->upload_limit(); @@ -197,6 +212,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + assert(limit >= -1); session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); @@ -208,6 +226,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); return find_torrent(m_ses, m_chk, m_info_hash)->download_limit(); @@ -218,6 +239,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); find_torrent(m_ses, m_chk, m_info_hash)->move_storage(save_path); @@ -227,6 +251,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); return find_torrent(m_ses, m_chk, m_info_hash)->valid_metadata(); @@ -236,6 +263,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); return find_torrent(m_ses, m_chk, m_info_hash)->is_seed(); @@ -245,6 +275,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); return find_torrent(m_ses, m_chk, m_info_hash)->is_paused(); @@ -254,6 +287,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); find_torrent(m_ses, m_chk, m_info_hash)->pause(); @@ -263,6 +299,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); find_torrent(m_ses, m_chk, m_info_hash)->resume(); @@ -273,6 +312,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); find_torrent(m_ses, m_chk, m_info_hash)->set_tracker_login(name, password); @@ -283,31 +325,27 @@ namespace libtorrent INVARIANT_CHECK; if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + + session_impl::mutex_t::scoped_lock l(m_ses->m_mutex); + mutex::scoped_lock l2(m_chk->m_mutex); - if (m_chk) + aux::piece_checker_data* d = m_chk->find_torrent(m_info_hash); + if (d != 0) { - mutex::scoped_lock l(m_chk->m_mutex); - - aux::piece_checker_data* d = m_chk->find_torrent(m_info_hash); - if (d != 0) + if (!d->processing) { - if (!d->processing) - { - torrent_info const& info = d->torrent_ptr->torrent_file(); - progress.clear(); - progress.resize(info.num_files(), 0.f); - return; - } - d->torrent_ptr->file_progress(progress); + torrent_info const& info = d->torrent_ptr->torrent_file(); + progress.clear(); + progress.resize(info.num_files(), 0.f); return; } + d->torrent_ptr->file_progress(progress); + return; } - { - 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->file_progress(progress); - } + boost::shared_ptr t = m_ses->find_torrent(m_info_hash).lock(); + if (t) return t->file_progress(progress); throw_invalid_handle(); } @@ -317,36 +355,32 @@ namespace libtorrent INVARIANT_CHECK; if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + + session_impl::mutex_t::scoped_lock l(m_ses->m_mutex); + mutex::scoped_lock l2(m_chk->m_mutex); - if (m_chk) + aux::piece_checker_data* d = m_chk->find_torrent(m_info_hash); + if (d != 0) { - mutex::scoped_lock l(m_chk->m_mutex); + torrent_status st; - aux::piece_checker_data* d = m_chk->find_torrent(m_info_hash); - if (d != 0) + if (d->processing) { - torrent_status st; - - if (d->processing) - { - if (d->torrent_ptr->is_allocating()) - st.state = torrent_status::allocating; - else - st.state = torrent_status::checking_files; - } + if (d->torrent_ptr->is_allocating()) + st.state = torrent_status::allocating; else - st.state = torrent_status::queued_for_checking; - st.progress = d->progress; - st.paused = d->torrent_ptr->is_paused(); - return st; + st.state = torrent_status::checking_files; } + else + st.state = torrent_status::queued_for_checking; + st.progress = d->progress; + st.paused = d->torrent_ptr->is_paused(); + return st; } - { - 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(); - } + boost::shared_ptr t = m_ses->find_torrent(m_info_hash).lock(); + if (t) return t->status(); throw_invalid_handle(); return torrent_status(); @@ -355,6 +389,10 @@ namespace libtorrent void torrent_handle::set_sequenced_download_threshold(int threshold) const { INVARIANT_CHECK; + + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); find_torrent(m_ses, m_chk, m_info_hash)->set_sequenced_download_threshold(threshold); @@ -364,6 +402,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); return find_torrent(m_ses, m_chk, m_info_hash)->name(); @@ -374,6 +415,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); find_torrent(m_ses, m_chk, m_info_hash)->piece_availability(avail); @@ -383,6 +427,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); find_torrent(m_ses, m_chk, m_info_hash)->set_piece_priority(index, priority); @@ -392,6 +439,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); return find_torrent(m_ses, m_chk, m_info_hash)->piece_priority(index); @@ -401,6 +451,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); find_torrent(m_ses, m_chk, m_info_hash)->prioritize_pieces(pieces); @@ -409,6 +462,10 @@ namespace libtorrent std::vector torrent_handle::piece_priorities() const { INVARIANT_CHECK; + + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + std::vector ret; session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); @@ -420,6 +477,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); find_torrent(m_ses, m_chk, m_info_hash)->prioritize_files(files); @@ -430,6 +490,10 @@ namespace libtorrent void torrent_handle::filter_piece(int index, bool filter) const { INVARIANT_CHECK; + + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); find_torrent(m_ses, m_chk, m_info_hash)->filter_piece(index, filter); @@ -438,6 +502,10 @@ namespace libtorrent void torrent_handle::filter_pieces(std::vector const& pieces) const { INVARIANT_CHECK; + + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); find_torrent(m_ses, m_chk, m_info_hash)->filter_pieces(pieces); @@ -446,6 +514,10 @@ namespace libtorrent bool torrent_handle::is_piece_filtered(int index) const { INVARIANT_CHECK; + + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); return find_torrent(m_ses, m_chk, m_info_hash)->is_piece_filtered(index); @@ -454,6 +526,10 @@ namespace libtorrent std::vector torrent_handle::filtered_pieces() const { INVARIANT_CHECK; + + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + std::vector ret; session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); @@ -464,6 +540,10 @@ namespace libtorrent void torrent_handle::filter_files(std::vector const& files) const { INVARIANT_CHECK; + + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); find_torrent(m_ses, m_chk, m_info_hash)->filter_files(files); @@ -476,6 +556,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); return find_torrent(m_ses, m_chk, m_info_hash)->trackers(); @@ -485,6 +568,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); find_torrent(m_ses, m_chk, m_info_hash)->add_url_seed(url); @@ -494,6 +580,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); find_torrent(m_ses, m_chk, m_info_hash)->remove_url_seed(url); @@ -503,6 +592,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); return find_torrent(m_ses, m_chk, m_info_hash)->url_seeds(); @@ -513,6 +605,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); find_torrent(m_ses, m_chk, m_info_hash)->replace_trackers(urls); @@ -521,6 +616,10 @@ namespace libtorrent torrent_info const& torrent_handle::get_torrent_info() const { INVARIANT_CHECK; + + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); boost::shared_ptr t = find_torrent(m_ses, m_chk, m_info_hash); @@ -533,16 +632,14 @@ namespace libtorrent INVARIANT_CHECK; if (m_ses == 0) return false; + assert(m_chk); - if (m_chk) - { - mutex::scoped_lock l(m_chk->m_mutex); - aux::piece_checker_data* d = m_chk->find_torrent(m_info_hash); - if (d != 0) return true; - } + session_impl::mutex_t::scoped_lock l(m_ses->m_mutex); + mutex::scoped_lock l2(m_chk->m_mutex); + aux::piece_checker_data* d = m_chk->find_torrent(m_info_hash); + if (d != 0) return true; { - session_impl::mutex_t::scoped_lock l(m_ses->m_mutex); boost::weak_ptr t = m_ses->find_torrent(m_info_hash); if (!t.expired()) return true; } @@ -556,6 +653,7 @@ namespace libtorrent std::vector piece_index; if (m_ses == 0) return entry(); + assert(m_chk); session_impl::mutex_t::scoped_lock l(m_ses->m_mutex); boost::shared_ptr t = m_ses->find_torrent(m_info_hash).lock(); @@ -674,6 +772,9 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); return find_torrent(m_ses, m_chk, m_info_hash)->save_path(); @@ -684,6 +785,7 @@ namespace libtorrent INVARIANT_CHECK; if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); session_impl::mutex_t::scoped_lock l(m_ses->m_mutex); boost::shared_ptr t = m_ses->find_torrent(m_info_hash).lock(); @@ -712,6 +814,7 @@ namespace libtorrent INVARIANT_CHECK; if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); session_impl::mutex_t::scoped_lock l(m_ses->m_mutex); boost::shared_ptr t = m_ses->find_torrent(m_info_hash).lock(); @@ -726,6 +829,7 @@ namespace libtorrent INVARIANT_CHECK; if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); session_impl::mutex_t::scoped_lock l(m_ses->m_mutex); boost::shared_ptr t = m_ses->find_torrent(m_info_hash).lock(); @@ -738,8 +842,10 @@ namespace libtorrent { INVARIANT_CHECK; + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + assert(ratio >= 0.f); - if (ratio < 1.f && ratio > 0.f) ratio = 1.f; @@ -752,6 +858,10 @@ namespace libtorrent void torrent_handle::resolve_countries(bool r) { INVARIANT_CHECK; + + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); find_torrent(m_ses, m_chk, m_info_hash)->resolve_countries(r); @@ -760,6 +870,10 @@ namespace libtorrent bool torrent_handle::resolve_countries() const { INVARIANT_CHECK; + + if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex); mutex::scoped_lock l2(m_chk->m_mutex); return find_torrent(m_ses, m_chk, m_info_hash)->resolving_countries(); @@ -770,8 +884,10 @@ namespace libtorrent { INVARIANT_CHECK; - v.clear(); if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); + + v.clear(); session_impl::mutex_t::scoped_lock l(m_ses->m_mutex); @@ -803,6 +919,7 @@ namespace libtorrent INVARIANT_CHECK; if (m_ses == 0) throw_invalid_handle(); + assert(m_chk); session_impl::mutex_t::scoped_lock l(m_ses->m_mutex); boost::shared_ptr t = m_ses->find_torrent(m_info_hash).lock(); @@ -884,3 +1001,4 @@ namespace libtorrent } +