bunch of lt fixes

This commit is contained in:
Marcos Pinto 2007-08-27 19:04:41 +00:00
parent b39f981f6d
commit dd88d29f87
13 changed files with 330 additions and 206 deletions

View File

@ -284,8 +284,8 @@ namespace libtorrent
{ {
torrent* t = c.associated_torrent().lock().get(); torrent* t = c.associated_torrent().lock().get();
assert(t); assert(t);
t->unchoke_peer(c); if (t->unchoke_peer(c))
++m_num_unchoked; ++m_num_unchoked;
} }
session_status status() const; session_status status() const;

View File

@ -49,6 +49,8 @@ using boost::shared_ptr;
using boost::intrusive_ptr; using boost::intrusive_ptr;
using boost::bind; using boost::bind;
//#define TORRENT_VERBOSE_BANDWIDTH_LIMIT
namespace libtorrent { namespace libtorrent {
// the maximum block of bandwidth quota to // the maximum block of bandwidth quota to
@ -237,8 +239,10 @@ struct bandwidth_manager
i = j; i = j;
} }
} }
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT
if (m_queue.size() == 1) hand_out_bandwidth(); std::cerr << " req_bandwidht. m_queue.size() = " << m_queue.size() << std::endl;
#endif
if (!m_queue.empty()) hand_out_bandwidth();
} }
#ifndef NDEBUG #ifndef NDEBUG
@ -337,11 +341,18 @@ private:
// available bandwidth to hand out // available bandwidth to hand out
int amount = limit - m_current_quota; int amount = limit - m_current_quota;
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT
std::cerr << " hand_out_bandwidht. m_queue.size() = " << m_queue.size()
<< " amount = " << amount
<< " limit = " << limit
<< " m_current_quota = " << m_current_quota << std::endl;
#endif
while (!m_queue.empty() && amount > 0) while (!m_queue.empty() && amount > 0)
{ {
assert(amount == limit - m_current_quota); assert(amount == limit - m_current_quota);
bw_queue_entry<PeerConnection> qe = m_queue.front(); bw_queue_entry<PeerConnection> qe = m_queue.front();
assert(qe.max_block_size > 0); assert(qe.max_block_size > 0);
m_queue.pop_front(); m_queue.pop_front();
shared_ptr<Torrent> t = qe.peer->associated_torrent().lock(); shared_ptr<Torrent> t = qe.peer->associated_torrent().lock();
@ -380,7 +391,7 @@ private:
if (block_size < min_bandwidth_block_size) if (block_size < min_bandwidth_block_size)
{ {
block_size = min_bandwidth_block_size; block_size = (std::min)(int(min_bandwidth_block_size), m_limit);
} }
else if (block_size > max_bandwidth_block_size) else if (block_size > max_bandwidth_block_size)
{ {
@ -401,6 +412,9 @@ private:
} }
if (block_size > qe.max_block_size) block_size = qe.max_block_size; if (block_size > qe.max_block_size) block_size = qe.max_block_size;
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT
std::cerr << " block_size = " << block_size << " amount = " << amount << std::endl;
#endif
if (amount < block_size / 2) if (amount < block_size / 2)
{ {
m_queue.push_front(qe); m_queue.push_front(qe);
@ -463,4 +477,3 @@ private:
#endif #endif

View File

@ -71,7 +71,7 @@ namespace libtorrent
size_type offset; // the offset of this file inside the torrent size_type offset; // the offset of this file inside the torrent
size_type size; // the size of this file size_type size; // the size of this file
// if the path was incorrectly encoded, this is // if the path was incorrectly encoded, this is
// the origianal corrupt encoded string. It is // the original corrupt encoded string. It is
// preserved in order to be able to reproduce // preserved in order to be able to reproduce
// the correct info-hash // the correct info-hash
boost::shared_ptr<const fs::path> orig_path; boost::shared_ptr<const fs::path> orig_path;
@ -115,8 +115,12 @@ namespace libtorrent
void add_file(fs::path file, size_type size); void add_file(fs::path file, size_type size);
void add_url_seed(std::string const& url); void add_url_seed(std::string const& url);
std::vector<file_slice> map_block(int piece, size_type offset, int size) const; bool remap_files(std::vector<std::pair<std::string, libtorrent::size_type> > const& map);
peer_request map_file(int file, size_type offset, int size) const;
std::vector<file_slice> map_block(int piece, size_type offset
, int size, bool storage = false) const;
peer_request map_file(int file, size_type offset, int size
, bool storage = false) const;
std::vector<std::string> const& url_seeds() const std::vector<std::string> const& url_seeds() const
{ {
@ -128,15 +132,60 @@ namespace libtorrent
typedef std::vector<file_entry>::const_reverse_iterator reverse_file_iterator; typedef std::vector<file_entry>::const_reverse_iterator reverse_file_iterator;
// list the files in the torrent file // list the files in the torrent file
file_iterator begin_files() const { return m_files.begin(); } file_iterator begin_files(bool storage = false) const
file_iterator end_files() const { return m_files.end(); } {
reverse_file_iterator rbegin_files() const { return m_files.rbegin(); } if (!storage || m_remapped_files.empty())
reverse_file_iterator rend_files() const { return m_files.rend(); } return m_files.begin();
else
return m_remapped_files.begin();
}
int num_files() const file_iterator end_files(bool storage = false) const
{ assert(m_piece_length > 0); return (int)m_files.size(); } {
const file_entry& file_at(int index) const if (!storage || m_remapped_files.empty())
{ assert(index >= 0 && index < (int)m_files.size()); return m_files[index]; } return m_files.end();
else
return m_remapped_files.end();
}
reverse_file_iterator rbegin_files(bool storage = false) const
{
if (!storage || m_remapped_files.empty())
return m_files.rbegin();
else
return m_remapped_files.rbegin();
}
reverse_file_iterator rend_files(bool storage = false) const
{
if (!storage || m_remapped_files.empty())
return m_files.rend();
else
return m_remapped_files.rend();
}
int num_files(bool storage = false) const
{
assert(m_piece_length > 0);
if (!storage || m_remapped_files.empty())
return (int)m_files.size();
else
return (int)m_remapped_files.size();
}
const file_entry& file_at(int index, bool storage = false) const
{
if (!storage || m_remapped_files.empty())
{
assert(index >= 0 && index < (int)m_files.size());
return m_files[index];
}
else
{
assert(index >= 0 && index < (int)m_remapped_files.size());
return m_remapped_files[index];
}
}
const std::vector<announce_entry>& trackers() const { return m_urls; } const std::vector<announce_entry>& trackers() const { return m_urls; }
@ -218,6 +267,13 @@ namespace libtorrent
// the list of files that this torrent consists of // the list of files that this torrent consists of
std::vector<file_entry> m_files; std::vector<file_entry> m_files;
// this vector is typically empty. If it is not
// empty, it means the user has re-mapped the
// files in this torrent to diffefrent names
// on disk. This is only used when reading and
// writing the disk.
std::vector<file_entry> m_remapped_files;
nodes_t m_nodes; nodes_t m_nodes;
// the sum of all filesizes // the sum of all filesizes

View File

@ -184,6 +184,7 @@ namespace
, {"SB", "Swiftbit"} , {"SB", "Swiftbit"}
, {"SN", "ShareNet"} , {"SN", "ShareNet"}
, {"SS", "SwarmScope"} , {"SS", "SwarmScope"}
, {"ST", "SymTorrent"}
, {"SZ", "Shareaza"} , {"SZ", "Shareaza"}
, {"S~", "Shareaza (beta)"} , {"S~", "Shareaza (beta)"}
, {"T", "BitTornado"} , {"T", "BitTornado"}
@ -194,12 +195,57 @@ namespace
, {"U", "UPnP"} , {"U", "UPnP"}
, {"UL", "uLeecher"} , {"UL", "uLeecher"}
, {"UT", "uTorrent"} , {"UT", "uTorrent"}
, {"XL", "Xunlei"}
, {"XT", "XanTorrent"} , {"XT", "XanTorrent"}
, {"XX", "Xtorrent"} , {"XX", "Xtorrent"}
, {"ZT", "ZipTorrent"} , {"ZT", "ZipTorrent"}
, {"lt", "rTorrent"} , {"lt", "rTorrent"}
, {"pX", "pHoeniX"} , {"pX", "pHoeniX"}
, {"qB", "qBittorrent"} , {"qB", "qBittorrent"}
, {"st", "SharkTorrent"}
};
struct generic_map_entry
{
int offset;
char const* id;
char const* name;
};
// non-standard names
generic_map_entry generic_mappings[] =
{
{0, "Deadman Walking-", "Deadman"}
, {5, "Azureus", "Azureus 2.0.3.2"}
, {0, "DansClient", "XanTorrent"}
, {4, "btfans", "SimpleBT"}
, {0, "PRC.P---", "Bittorrent Plus! II"}
, {0, "P87.P---", "Bittorrent Plus!"}
, {0, "S587Plus", "Bittorrent Plus!"}
, {0, "martini", "Martini Man"}
, {0, "Plus---", "Bittorrent Plus"}
, {0, "turbobt", "TurboBT"}
, {0, "a00---0", "Swarmy"}
, {0, "a02---0", "Swarmy"}
, {0, "T00---0", "Teeweety"}
, {0, "BTDWV-", "Deadman Walking"}
, {2, "BS", "BitSpirit"}
, {0, "Pando-", "Pando"}
, {0, "LIME", "LimeWire"}
, {0, "btuga", "BTugaXP"}
, {0, "oernu", "BTugaXP"}
, {0, "Mbrst", "Burst!"}
, {0, "PEERAPP", "PeerApp"}
, {0, "Plus", "Plus!"}
, {0, "-Qt-", "Qt"}
, {0, "exbc", "BitComet"}
, {0, "DNA", "BitTorrent DNA"}
, {0, "-G3", "G3 Torrent"}
, {0, "-FG", "FlashGet"}
, {0, "-ML", "MLdonkey"}
, {0, "XBT", "XBT"}
, {0, "OP", "Opera"}
, {2, "RS", "Rufus"}
, {0, "AZ2500BT", "BitTyrant"}
}; };
bool compare_id(map_entry const& lhs, map_entry const& rhs) bool compare_id(map_entry const& lhs, map_entry const& rhs)
@ -281,30 +327,13 @@ namespace libtorrent
// non standard encodings // non standard encodings
// ---------------------- // ----------------------
if (find_string(PID, "Deadman Walking-")) return "Deadman"; int num_generic_mappings = sizeof(generic_mappings) / sizeof(generic_mappings[0]);
if (find_string(PID + 5, "Azureus")) return "Azureus 2.0.3.2";
if (find_string(PID, "DansClient")) return "XanTorrent"; for (int i = 0; i < num_generic_mappings; ++i)
if (find_string(PID + 4, "btfans")) return "SimpleBT"; {
if (find_string(PID, "PRC.P---")) return "Bittorrent Plus! II"; generic_map_entry const& e = generic_mappings[i];
if (find_string(PID, "P87.P---")) return "Bittorrent Plus!"; if (find_string(PID + e.offset, e.id)) return e.name;
if (find_string(PID, "S587Plus")) return "Bittorrent Plus!"; }
if (find_string(PID, "martini")) return "Martini Man";
if (find_string(PID, "Plus---")) return "Bittorrent Plus";
if (find_string(PID, "turbobt")) return "TurboBT";
if (find_string(PID, "a00---0")) return "Swarmy";
if (find_string(PID, "a02---0")) return "Swarmy";
if (find_string(PID, "T00---0")) return "Teeweety";
if (find_string(PID, "BTDWV-")) return "Deadman Walking";
if (find_string(PID + 2, "BS")) return "BitSpirit";
if (find_string(PID, "btuga")) return "BTugaXP";
if (find_string(PID, "oernu")) return "BTugaXP";
if (find_string(PID, "Mbrst")) return "Burst!";
if (find_string(PID, "Plus")) return "Plus!";
if (find_string(PID, "-Qt-")) return "Qt";
if (find_string(PID, "exbc")) return "BitComet";
if (find_string(PID, "-G3")) return "G3 Torrent";
if (find_string(PID, "XBT")) return "XBT";
if (find_string(PID, "OP")) return "Opera";
if (find_string(PID, "-BOW") && PID[7] == '-') if (find_string(PID, "-BOW") && PID[7] == '-')
return "Bits on Wheels " + std::string(PID + 4, PID + 7); return "Bits on Wheels " + std::string(PID + 4, PID + 7);

View File

@ -978,4 +978,3 @@ namespace libtorrent { namespace dht
}} }}

View File

@ -189,7 +189,7 @@ namespace libtorrent
, m_download_limit(bandwidth_limit::inf) , m_download_limit(bandwidth_limit::inf)
, m_peer_info(peerinfo) , m_peer_info(peerinfo)
, m_speed(slow) , m_speed(slow)
, m_connection_ticket(-1) , m_connection_ticket(-1)
, m_remote_bytes_dled(0) , m_remote_bytes_dled(0)
, m_remote_dl_rate(0) , m_remote_dl_rate(0)
, m_remote_dl_update(time_now()) , m_remote_dl_update(time_now())

View File

@ -1699,3 +1699,4 @@ namespace libtorrent
} }
} }

View File

@ -1530,4 +1530,3 @@ namespace libtorrent
} }
} }

View File

@ -976,6 +976,8 @@ namespace detail
// if we should not make any more connections // if we should not make any more connections
// attempts this tick, abort // attempts this tick, abort
if (max_connections == 0) break; if (max_connections == 0) break;
// maintain the global limit on number of connections
if (num_connections() >= m_max_connections) break;
} }
} }

View File

@ -247,8 +247,8 @@ namespace libtorrent
{ {
p = complete(p); p = complete(p);
std::vector<std::pair<size_type, std::time_t> > sizes; std::vector<std::pair<size_type, std::time_t> > sizes;
for (torrent_info::file_iterator i = t.begin_files(); for (torrent_info::file_iterator i = t.begin_files(true);
i != t.end_files(); ++i) i != t.end_files(true); ++i)
{ {
size_type size = 0; size_type size = 0;
std::time_t time = 0; std::time_t time = 0;
@ -287,7 +287,7 @@ namespace libtorrent
, bool compact_mode , bool compact_mode
, std::string* error) , std::string* error)
{ {
if ((int)sizes.size() != t.num_files()) if ((int)sizes.size() != t.num_files(true))
{ {
if (error) *error = "mismatching number of files"; if (error) *error = "mismatching number of files";
return false; return false;
@ -296,8 +296,8 @@ namespace libtorrent
std::vector<std::pair<size_type, std::time_t> >::const_iterator s std::vector<std::pair<size_type, std::time_t> >::const_iterator s
= sizes.begin(); = sizes.begin();
for (torrent_info::file_iterator i = t.begin_files(); for (torrent_info::file_iterator i = t.begin_files(true);
i != t.end_files(); ++i, ++s) i != t.end_files(true); ++i, ++s)
{ {
size_type size = 0; size_type size = 0;
std::time_t time = 0; std::time_t time = 0;
@ -342,50 +342,14 @@ namespace libtorrent
return true; return true;
} }
struct thread_safe_storage class storage : public storage_interface, boost::noncopyable
{
thread_safe_storage(std::size_t n)
: slots(n, false)
{}
boost::mutex mutex;
boost::condition condition;
std::vector<bool> slots;
};
struct slot_lock
{
slot_lock(thread_safe_storage& s, int slot_)
: storage_(s)
, slot(slot_)
{
assert(slot_>=0 && slot_ < (int)s.slots.size());
boost::mutex::scoped_lock lock(storage_.mutex);
while (storage_.slots[slot])
storage_.condition.wait(lock);
storage_.slots[slot] = true;
}
~slot_lock()
{
storage_.slots[slot] = false;
storage_.condition.notify_all();
}
thread_safe_storage& storage_;
int slot;
};
class storage : public storage_interface, thread_safe_storage, boost::noncopyable
{ {
public: public:
storage(torrent_info const& info, fs::path const& path, file_pool& fp) storage(torrent_info const& info, fs::path const& path, file_pool& fp)
: thread_safe_storage(info.num_pieces()) : m_info(info)
, m_info(info)
, m_files(fp) , m_files(fp)
{ {
assert(info.begin_files() != info.end_files()); assert(info.begin_files(true) != info.end_files(true));
m_save_path = fs::complete(path); m_save_path = fs::complete(path);
assert(m_save_path.is_complete()); assert(m_save_path.is_complete());
} }
@ -448,8 +412,8 @@ namespace libtorrent
{ {
// first, create all missing directories // first, create all missing directories
fs::path last_path; fs::path last_path;
for (torrent_info::file_iterator file_iter = m_info.begin_files(), for (torrent_info::file_iterator file_iter = m_info.begin_files(true),
end_iter = m_info.end_files(); file_iter != end_iter; ++file_iter) end_iter = m_info.end_files(true); file_iter != end_iter; ++file_iter)
{ {
fs::path dir = (m_save_path / file_iter->path).branch_path(); fs::path dir = (m_save_path / file_iter->path).branch_path();
@ -546,11 +510,11 @@ namespace libtorrent
if (seed) if (seed)
{ {
if (m_info.num_files() != (int)file_sizes.size()) if (m_info.num_files(true) != (int)file_sizes.size())
{ {
error = "the number of files does not match the torrent (num: " error = "the number of files does not match the torrent (num: "
+ boost::lexical_cast<std::string>(file_sizes.size()) + " actual: " + boost::lexical_cast<std::string>(file_sizes.size()) + " actual: "
+ boost::lexical_cast<std::string>(m_info.num_files()) + ")"; + boost::lexical_cast<std::string>(m_info.num_files(true)) + ")";
return false; return false;
} }
@ -558,8 +522,8 @@ namespace libtorrent
fs = file_sizes.begin(); fs = file_sizes.begin();
// the resume data says we have the entire torrent // the resume data says we have the entire torrent
// make sure the file sizes are the right ones // make sure the file sizes are the right ones
for (torrent_info::file_iterator i = m_info.begin_files() for (torrent_info::file_iterator i = m_info.begin_files(true)
, end(m_info.end_files()); i != end; ++i, ++fs) , end(m_info.end_files(true)); i != end; ++i, ++fs)
{ {
if (i->size != fs->first) if (i->size != fs->first)
{ {
@ -722,11 +686,9 @@ namespace libtorrent
assert(offset < m_info.piece_size(slot)); assert(offset < m_info.piece_size(slot));
assert(size > 0); assert(size > 0);
slot_lock lock(*this, slot);
#ifndef NDEBUG #ifndef NDEBUG
std::vector<file_slice> slices std::vector<file_slice> slices
= m_info.map_block(slot, offset, size); = m_info.map_block(slot, offset, size, true);
assert(!slices.empty()); assert(!slices.empty());
#endif #endif
@ -737,7 +699,7 @@ namespace libtorrent
size_type file_offset = start; size_type file_offset = start;
std::vector<file_entry>::const_iterator file_iter; std::vector<file_entry>::const_iterator file_iter;
for (file_iter = m_info.begin_files();;) for (file_iter = m_info.begin_files(true);;)
{ {
if (file_offset < file_iter->size) if (file_offset < file_iter->size)
break; break;
@ -795,7 +757,7 @@ namespace libtorrent
assert(int(slices.size()) > counter); assert(int(slices.size()) > counter);
size_type slice_size = slices[counter].size; size_type slice_size = slices[counter].size;
assert(slice_size == read_bytes); assert(slice_size == read_bytes);
assert(m_info.file_at(slices[counter].file_index).path assert(m_info.file_at(slices[counter].file_index, true).path
== file_iter->path); == file_iter->path);
#endif #endif
@ -849,11 +811,9 @@ namespace libtorrent
assert(offset >= 0); assert(offset >= 0);
assert(size > 0); assert(size > 0);
slot_lock lock(*this, slot);
#ifndef NDEBUG #ifndef NDEBUG
std::vector<file_slice> slices std::vector<file_slice> slices
= m_info.map_block(slot, offset, size); = m_info.map_block(slot, offset, size, true);
assert(!slices.empty()); assert(!slices.empty());
#endif #endif
@ -863,14 +823,14 @@ namespace libtorrent
size_type file_offset = start; size_type file_offset = start;
std::vector<file_entry>::const_iterator file_iter; std::vector<file_entry>::const_iterator file_iter;
for (file_iter = m_info.begin_files();;) for (file_iter = m_info.begin_files(true);;)
{ {
if (file_offset < file_iter->size) if (file_offset < file_iter->size)
break; break;
file_offset -= file_iter->size; file_offset -= file_iter->size;
++file_iter; ++file_iter;
assert(file_iter != m_info.end_files()); assert(file_iter != m_info.end_files(true));
} }
fs::path p(m_save_path / file_iter->path); fs::path p(m_save_path / file_iter->path);
@ -914,7 +874,7 @@ namespace libtorrent
{ {
assert(int(slices.size()) > counter); assert(int(slices.size()) > counter);
assert(slices[counter].size == write_bytes); assert(slices[counter].size == write_bytes);
assert(m_info.file_at(slices[counter].file_index).path assert(m_info.file_at(slices[counter].file_index, true).path
== file_iter->path); == file_iter->path);
assert(buf_pos >= 0); assert(buf_pos >= 0);
@ -942,7 +902,7 @@ namespace libtorrent
#endif #endif
++file_iter; ++file_iter;
assert(file_iter != m_info.end_files()); assert(file_iter != m_info.end_files(true));
fs::path p = m_save_path / file_iter->path; fs::path p = m_save_path / file_iter->path;
file_offset = 0; file_offset = 0;
out = m_files.open_file( out = m_files.open_file(
@ -1906,8 +1866,8 @@ namespace libtorrent
// find the file that failed, and skip all the blocks in that file // find the file that failed, and skip all the blocks in that file
size_type file_offset = 0; size_type file_offset = 0;
size_type current_offset = m_current_slot * m_info.piece_length(); size_type current_offset = m_current_slot * m_info.piece_length();
for (torrent_info::file_iterator i = m_info.begin_files(); for (torrent_info::file_iterator i = m_info.begin_files(true);
i != m_info.end_files(); ++i) i != m_info.end_files(true); ++i)
{ {
file_offset += i->size; file_offset += i->size;
if (file_offset > current_offset) break; if (file_offset > current_offset) break;

View File

@ -1838,6 +1838,7 @@ namespace libtorrent
#endif #endif
assert(want_more_peers()); assert(want_more_peers());
assert(m_ses.num_connections() < m_ses.max_connections());
tcp::endpoint const& a(peerinfo->ip); tcp::endpoint const& a(peerinfo->ip);
assert((m_ses.m_ip_filter.access(a.address()) & ip_filter::blocked) == 0); assert((m_ses.m_ip_filter.access(a.address()) & ip_filter::blocked) == 0);
@ -2025,9 +2026,9 @@ namespace libtorrent
, boost::intrusive_ptr<peer_connection> const& p , boost::intrusive_ptr<peer_connection> const& p
, bool non_prioritized) , bool non_prioritized)
{ {
assert(m_bandwidth_limit[channel].throttle() > 0); assert(m_bandwidth_limit[channel].throttle() > 0);
int block_size = m_bandwidth_limit[channel].throttle() / 10; int block_size = m_bandwidth_limit[channel].throttle() / 10;
if (block_size <= 0) block_size = 1; if (block_size <= 0) block_size = 1;
if (m_bandwidth_limit[channel].max_assignable() > 0) if (m_bandwidth_limit[channel].max_assignable() > 0)
{ {

View File

@ -89,26 +89,22 @@ namespace libtorrent
throw invalid_handle(); throw invalid_handle();
} }
template<class Ret, class F> boost::shared_ptr<torrent> find_torrent(
Ret call_member(
session_impl* ses session_impl* ses
, aux::checker_impl* chk , aux::checker_impl* chk
, sha1_hash const& hash , sha1_hash const& hash)
, F f)
{ {
if (ses == 0) throw_invalid_handle(); if (ses == 0) throw_invalid_handle();
if (chk) if (chk)
{ {
mutex::scoped_lock l(chk->m_mutex);
aux::piece_checker_data* d = chk->find_torrent(hash); aux::piece_checker_data* d = chk->find_torrent(hash);
if (d != 0) return f(*d->torrent_ptr); if (d != 0) return d->torrent_ptr;
} }
{ {
session_impl::mutex_t::scoped_lock l(ses->m_mutex);
boost::shared_ptr<torrent> t = ses->find_torrent(hash).lock(); boost::shared_ptr<torrent> t = ses->find_torrent(hash).lock();
if (t) return f(*t); if (t) return t;
} }
// throwing directly instead of calling // throwing directly instead of calling
@ -133,16 +129,18 @@ namespace libtorrent
assert(max_uploads >= 2 || max_uploads == -1); assert(max_uploads >= 2 || max_uploads == -1);
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::set_max_uploads, _1, max_uploads)); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->set_max_uploads(max_uploads);
} }
void torrent_handle::use_interface(const char* net_interface) const void torrent_handle::use_interface(const char* net_interface) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::use_interface, _1, net_interface)); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->use_interface(net_interface);
} }
void torrent_handle::set_max_connections(int max_connections) const void torrent_handle::set_max_connections(int max_connections) const
@ -151,8 +149,9 @@ namespace libtorrent
assert(max_connections >= 2 || max_connections == -1); assert(max_connections >= 2 || max_connections == -1);
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::set_max_connections, _1, max_connections)); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->set_max_connections(max_connections);
} }
void torrent_handle::set_peer_upload_limit(tcp::endpoint ip, int limit) const void torrent_handle::set_peer_upload_limit(tcp::endpoint ip, int limit) const
@ -160,8 +159,9 @@ namespace libtorrent
INVARIANT_CHECK; INVARIANT_CHECK;
assert(limit >= -1); assert(limit >= -1);
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::set_peer_upload_limit, _1, ip, limit)); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->set_peer_upload_limit(ip, limit);
} }
void torrent_handle::set_peer_download_limit(tcp::endpoint ip, int limit) const void torrent_handle::set_peer_download_limit(tcp::endpoint ip, int limit) const
@ -169,8 +169,9 @@ namespace libtorrent
INVARIANT_CHECK; INVARIANT_CHECK;
assert(limit >= -1); assert(limit >= -1);
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::set_peer_download_limit, _1, ip, limit)); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->set_peer_download_limit(ip, limit);
} }
void torrent_handle::set_upload_limit(int limit) const void torrent_handle::set_upload_limit(int limit) const
@ -179,15 +180,17 @@ namespace libtorrent
assert(limit >= -1); assert(limit >= -1);
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::set_upload_limit, _1, limit)); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->set_upload_limit(limit);
} }
int torrent_handle::upload_limit() const int torrent_handle::upload_limit() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
return call_member<int>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::upload_limit, _1)); mutex::scoped_lock l2(m_chk->m_mutex);
return find_torrent(m_ses, m_chk, m_info_hash)->upload_limit();
} }
void torrent_handle::set_download_limit(int limit) const void torrent_handle::set_download_limit(int limit) const
@ -196,15 +199,18 @@ namespace libtorrent
assert(limit >= -1); assert(limit >= -1);
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::set_download_limit, _1, limit)); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->set_download_limit(limit);
} }
int torrent_handle::download_limit() const int torrent_handle::download_limit() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
return call_member<int>(m_ses, m_chk, m_info_hash
, bind(&torrent::download_limit, _1)); 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();
} }
void torrent_handle::move_storage( void torrent_handle::move_storage(
@ -212,48 +218,54 @@ namespace libtorrent
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::move_storage, _1, save_path)); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->move_storage(save_path);
} }
bool torrent_handle::has_metadata() const bool torrent_handle::has_metadata() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
return call_member<bool>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::valid_metadata, _1)); mutex::scoped_lock l2(m_chk->m_mutex);
return find_torrent(m_ses, m_chk, m_info_hash)->valid_metadata();
} }
bool torrent_handle::is_seed() const bool torrent_handle::is_seed() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
return call_member<bool>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::is_seed, _1)); mutex::scoped_lock l2(m_chk->m_mutex);
return find_torrent(m_ses, m_chk, m_info_hash)->is_seed();
} }
bool torrent_handle::is_paused() const bool torrent_handle::is_paused() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
return call_member<bool>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::is_paused, _1)); mutex::scoped_lock l2(m_chk->m_mutex);
return find_torrent(m_ses, m_chk, m_info_hash)->is_paused();
} }
void torrent_handle::pause() const void torrent_handle::pause() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::pause, _1)); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->pause();
} }
void torrent_handle::resume() const void torrent_handle::resume() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::resume, _1)); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->resume();
} }
void torrent_handle::set_tracker_login(std::string const& name void torrent_handle::set_tracker_login(std::string const& name
@ -261,8 +273,9 @@ namespace libtorrent
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::set_tracker_login, _1, name, password)); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->set_tracker_login(name, password);
} }
void torrent_handle::file_progress(std::vector<float>& progress) void torrent_handle::file_progress(std::vector<float>& progress)
@ -342,15 +355,18 @@ namespace libtorrent
void torrent_handle::set_sequenced_download_threshold(int threshold) const void torrent_handle::set_sequenced_download_threshold(int threshold) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::set_sequenced_download_threshold, _1, threshold)); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->set_sequenced_download_threshold(threshold);
} }
std::string torrent_handle::name() const std::string torrent_handle::name() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
return call_member<std::string>(m_ses, m_chk, m_info_hash
, bind(&torrent::name, _1)); 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();
} }
@ -358,40 +374,45 @@ namespace libtorrent
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::piece_availability, _1, boost::ref(avail))); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->piece_availability(avail);
} }
void torrent_handle::piece_priority(int index, int priority) const void torrent_handle::piece_priority(int index, int priority) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::set_piece_priority, _1, index, priority)); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->set_piece_priority(index, priority);
} }
int torrent_handle::piece_priority(int index) const int torrent_handle::piece_priority(int index) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
return call_member<int>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::piece_priority, _1, index)); mutex::scoped_lock l2(m_chk->m_mutex);
return find_torrent(m_ses, m_chk, m_info_hash)->piece_priority(index);
} }
void torrent_handle::prioritize_pieces(std::vector<int> const& pieces) const void torrent_handle::prioritize_pieces(std::vector<int> const& pieces) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::prioritize_pieces, _1, boost::cref(pieces))); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->prioritize_pieces(pieces);
} }
std::vector<int> torrent_handle::piece_priorities() const std::vector<int> torrent_handle::piece_priorities() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
std::vector<int> ret; std::vector<int> ret;
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::piece_priorities, _1, boost::ref(ret))); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->piece_priorities(ret);
return ret; return ret;
} }
@ -399,8 +420,9 @@ namespace libtorrent
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::prioritize_files, _1, boost::cref(files))); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->prioritize_files(files);
} }
// ============ start deprecation =============== // ============ start deprecation ===============
@ -408,38 +430,43 @@ namespace libtorrent
void torrent_handle::filter_piece(int index, bool filter) const void torrent_handle::filter_piece(int index, bool filter) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::filter_piece, _1, index, filter)); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->filter_piece(index, filter);
} }
void torrent_handle::filter_pieces(std::vector<bool> const& pieces) const void torrent_handle::filter_pieces(std::vector<bool> const& pieces) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::filter_pieces, _1, boost::cref(pieces))); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->filter_pieces(pieces);
} }
bool torrent_handle::is_piece_filtered(int index) const bool torrent_handle::is_piece_filtered(int index) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
return call_member<bool>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::is_piece_filtered, _1, index)); mutex::scoped_lock l2(m_chk->m_mutex);
return find_torrent(m_ses, m_chk, m_info_hash)->is_piece_filtered(index);
} }
std::vector<bool> torrent_handle::filtered_pieces() const std::vector<bool> torrent_handle::filtered_pieces() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
std::vector<bool> ret; std::vector<bool> ret;
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::filtered_pieces, _1, boost::ref(ret))); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->filtered_pieces(ret);
return ret; return ret;
} }
void torrent_handle::filter_files(std::vector<bool> const& files) const void torrent_handle::filter_files(std::vector<bool> const& files) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::filter_files, _1, files)); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->filter_files(files);
} }
// ============ end deprecation =============== // ============ end deprecation ===============
@ -449,32 +476,36 @@ namespace libtorrent
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
return call_member<std::vector<announce_entry> const&>(m_ses session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, m_chk, m_info_hash, bind(&torrent::trackers, _1)); mutex::scoped_lock l2(m_chk->m_mutex);
return find_torrent(m_ses, m_chk, m_info_hash)->trackers();
} }
void torrent_handle::add_url_seed(std::string const& url) const void torrent_handle::add_url_seed(std::string const& url) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::add_url_seed, _1, url)); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->add_url_seed(url);
} }
void torrent_handle::remove_url_seed(std::string const& url) const void torrent_handle::remove_url_seed(std::string const& url) const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::remove_url_seed, _1, url)); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->remove_url_seed(url);
} }
std::set<std::string> torrent_handle::url_seeds() const std::set<std::string> torrent_handle::url_seeds() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
return call_member<std::set<std::string> >(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::url_seeds, _1)); mutex::scoped_lock l2(m_chk->m_mutex);
return find_torrent(m_ses, m_chk, m_info_hash)->url_seeds();
} }
void torrent_handle::replace_trackers( void torrent_handle::replace_trackers(
@ -482,17 +513,19 @@ namespace libtorrent
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::replace_trackers, _1, urls)); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->replace_trackers(urls);
} }
torrent_info const& torrent_handle::get_torrent_info() const torrent_info const& torrent_handle::get_torrent_info() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
if (!has_metadata()) throw_invalid_handle(); mutex::scoped_lock l2(m_chk->m_mutex);
return call_member<torrent_info const&>(m_ses, m_chk, m_info_hash boost::shared_ptr<torrent> t = find_torrent(m_ses, m_chk, m_info_hash);
, bind(&torrent::torrent_file, _1)); if (!t->valid_metadata()) throw_invalid_handle();
return t->torrent_file();
} }
bool torrent_handle::is_valid() const bool torrent_handle::is_valid() const
@ -641,8 +674,9 @@ namespace libtorrent
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
return call_member<fs::path>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::save_path, _1)); mutex::scoped_lock l2(m_chk->m_mutex);
return find_torrent(m_ses, m_chk, m_info_hash)->save_path();
} }
void torrent_handle::connect_peer(tcp::endpoint const& adr, int source) const void torrent_handle::connect_peer(tcp::endpoint const& adr, int source) const
@ -709,23 +743,26 @@ namespace libtorrent
if (ratio < 1.f && ratio > 0.f) if (ratio < 1.f && ratio > 0.f)
ratio = 1.f; ratio = 1.f;
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::set_ratio, _1, ratio)); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->set_ratio(ratio);
} }
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
void torrent_handle::resolve_countries(bool r) void torrent_handle::resolve_countries(bool r)
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
call_member<void>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::resolve_countries, _1, r)); mutex::scoped_lock l2(m_chk->m_mutex);
find_torrent(m_ses, m_chk, m_info_hash)->resolve_countries(r);
} }
bool torrent_handle::resolve_countries() const bool torrent_handle::resolve_countries() const
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
return call_member<bool>(m_ses, m_chk, m_info_hash session_impl::mutex_t::scoped_lock l1(m_ses->m_mutex);
, bind(&torrent::resolving_countries, _1)); mutex::scoped_lock l2(m_chk->m_mutex);
return find_torrent(m_ses, m_chk, m_info_hash)->resolving_countries();
} }
#endif #endif

View File

@ -400,7 +400,9 @@ namespace libtorrent
{ {
if (i->first == "pieces" if (i->first == "pieces"
|| i->first == "piece length" || i->first == "piece length"
|| i->first == "length") || i->first == "length"
// || i->first == "files"
|| i->first == "name")
continue; continue;
m_extra_info[i->first] = i->second; m_extra_info[i->first] = i->second;
} }
@ -824,8 +826,33 @@ namespace libtorrent
m_nodes.push_back(node); m_nodes.push_back(node);
} }
bool torrent_info::remap_files(std::vector<std::pair<std::string
, libtorrent::size_type> > const& map)
{
typedef std::vector<std::pair<std::string, size_type> > files_t;
size_type offset = 0;
m_remapped_files.resize(map.size());
for (int i = 0; i < int(map.size()); ++i)
{
file_entry& fe = m_remapped_files[i];
fe.path = map[i].first;
fe.offset = offset;
fe.size = map[i].second;
offset += fe.size;
}
if (offset != total_size())
{
m_remapped_files.clear();
return false;
}
return true;
}
std::vector<file_slice> torrent_info::map_block(int piece, size_type offset std::vector<file_slice> torrent_info::map_block(int piece, size_type offset
, int size) const , int size, bool storage) const
{ {
assert(num_files() > 0); assert(num_files() > 0);
std::vector<file_slice> ret; std::vector<file_slice> ret;
@ -839,9 +866,9 @@ namespace libtorrent
std::vector<file_entry>::const_iterator file_iter; std::vector<file_entry>::const_iterator file_iter;
int counter = 0; int counter = 0;
for (file_iter = begin_files();; ++counter, ++file_iter) for (file_iter = begin_files(storage);; ++counter, ++file_iter)
{ {
assert(file_iter != end_files()); assert(file_iter != end_files(storage));
if (file_offset < file_iter->size) if (file_offset < file_iter->size)
{ {
file_slice f; file_slice f;
@ -862,11 +889,11 @@ namespace libtorrent
} }
peer_request torrent_info::map_file(int file_index, size_type file_offset peer_request torrent_info::map_file(int file_index, size_type file_offset
, int size) const , int size, bool storage) const
{ {
assert(file_index < (int)m_files.size()); assert(file_index < num_files(storage));
assert(file_index >= 0); assert(file_index >= 0);
size_type offset = file_offset + m_files[file_index].offset; size_type offset = file_offset + file_at(file_index, storage).offset;
peer_request ret; peer_request ret;
ret.piece = offset / piece_length(); ret.piece = offset / piece_length();