lt sync 2388
This commit is contained in:
parent
bf00795050
commit
7107413d0e
|
@ -13,7 +13,7 @@ object pieces(torrent_status const& s)
|
||||||
{
|
{
|
||||||
list result;
|
list result;
|
||||||
|
|
||||||
for (bitfield::const_iterator i(s.pieces->begin()), e(s.pieces->end()); i != e; ++i)
|
for (bitfield::const_iterator i(s.pieces.begin()), e(s.pieces.end()); i != e; ++i)
|
||||||
result.append(*i);
|
result.append(*i);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -209,7 +209,7 @@ namespace libtorrent
|
||||||
void write_not_interested();
|
void write_not_interested();
|
||||||
void write_request(peer_request const& r);
|
void write_request(peer_request const& r);
|
||||||
void write_cancel(peer_request const& r);
|
void write_cancel(peer_request const& r);
|
||||||
void write_bitfield(bitfield const& bits);
|
void write_bitfield();
|
||||||
void write_have(int index);
|
void write_have(int index);
|
||||||
void write_piece(peer_request const& r, disk_buffer_holder& buffer);
|
void write_piece(peer_request const& r, disk_buffer_holder& buffer);
|
||||||
void write_handshake();
|
void write_handshake();
|
||||||
|
|
|
@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define TORRENT_CONFIG_HPP_INCLUDED
|
#define TORRENT_CONFIG_HPP_INCLUDED
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
|
#include <boost/version.hpp>
|
||||||
|
|
||||||
#if defined(__GNUC__) && __GNUC__ >= 4
|
#if defined(__GNUC__) && __GNUC__ >= 4
|
||||||
|
|
||||||
|
@ -81,7 +82,12 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define TORRENT_BSD
|
#define TORRENT_BSD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// should wpath or path be used?
|
||||||
|
#if defined UNICODE && !defined BOOST_FILESYSTEM_NARROW_ONLY && BOOST_VERSION >= 103400
|
||||||
|
#define TORRENT_USE_WPATH 1
|
||||||
|
#else
|
||||||
|
#define TORRENT_USE_WPATH 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // TORRENT_CONFIG_HPP_INCLUDED
|
#endif // TORRENT_CONFIG_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
|
@ -129,18 +129,13 @@ namespace libtorrent
|
||||||
boost::int16_t requested;
|
boost::int16_t requested;
|
||||||
};
|
};
|
||||||
|
|
||||||
piece_picker(int blocks_per_piece
|
piece_picker();
|
||||||
, int total_num_blocks);
|
|
||||||
|
|
||||||
void get_availability(std::vector<int>& avail) const;
|
void get_availability(std::vector<int>& avail) const;
|
||||||
|
|
||||||
void sequential_download(bool sd);
|
void sequential_download(bool sd);
|
||||||
bool sequential_download() const { return m_sequential_download >= 0; }
|
bool sequential_download() const { return m_sequential_download >= 0; }
|
||||||
|
|
||||||
// the vector tells which pieces we already have
|
|
||||||
// and which we don't have.
|
|
||||||
void init(bitfield const& pieces);
|
|
||||||
|
|
||||||
// increases the peer count for the given piece
|
// increases the peer count for the given piece
|
||||||
// (is used when a HAVE message is received)
|
// (is used when a HAVE message is received)
|
||||||
void inc_refcount(int index);
|
void inc_refcount(int index);
|
||||||
|
@ -164,6 +159,17 @@ namespace libtorrent
|
||||||
// we are not interested in this piece anymore
|
// we are not interested in this piece anymore
|
||||||
// (i.e. we don't have to maintain a refcount)
|
// (i.e. we don't have to maintain a refcount)
|
||||||
void we_have(int index);
|
void we_have(int index);
|
||||||
|
void we_dont_have(int index);
|
||||||
|
|
||||||
|
void init(int blocks_per_piece, int total_num_blocks);
|
||||||
|
int num_pieces() const { return int(m_piece_map.size()); }
|
||||||
|
|
||||||
|
bool have_piece(int index) const
|
||||||
|
{
|
||||||
|
TORRENT_ASSERT(index >= 0);
|
||||||
|
TORRENT_ASSERT(index < int(m_piece_map.size()));
|
||||||
|
return m_piece_map[index].index == piece_pos::we_have_index;
|
||||||
|
}
|
||||||
|
|
||||||
// sets the priority of a piece.
|
// sets the priority of a piece.
|
||||||
// returns true if the priority was changed from 0 to non-0
|
// returns true if the priority was changed from 0 to non-0
|
||||||
|
@ -276,6 +282,8 @@ namespace libtorrent
|
||||||
// the number of filtered pieces we already have
|
// the number of filtered pieces we already have
|
||||||
int num_have_filtered() const { return m_num_have_filtered; }
|
int num_have_filtered() const { return m_num_have_filtered; }
|
||||||
|
|
||||||
|
int num_have() const { return m_num_have; }
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// used in debug mode
|
// used in debug mode
|
||||||
void verify_priority(int start, int end, int prio) const;
|
void verify_priority(int start, int end, int prio) const;
|
||||||
|
@ -350,6 +358,7 @@ namespace libtorrent
|
||||||
|
|
||||||
bool have() const { return index == we_have_index; }
|
bool have() const { return index == we_have_index; }
|
||||||
void set_have() { index = we_have_index; TORRENT_ASSERT(have()); }
|
void set_have() { index = we_have_index; TORRENT_ASSERT(have()); }
|
||||||
|
void set_not_have() { index = 0; TORRENT_ASSERT(!have()); }
|
||||||
|
|
||||||
bool filtered() const { return piece_priority == filter_priority; }
|
bool filtered() const { return piece_priority == filter_priority; }
|
||||||
void filtered(bool f) { piece_priority = f ? filter_priority : 0; }
|
void filtered(bool f) { piece_priority = f ? filter_priority : 0; }
|
||||||
|
@ -466,10 +475,6 @@ namespace libtorrent
|
||||||
// if this is set to true, it means update_pieces()
|
// if this is set to true, it means update_pieces()
|
||||||
// has to be called before accessing m_pieces.
|
// has to be called before accessing m_pieces.
|
||||||
mutable bool m_dirty;
|
mutable bool m_dirty;
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
bool m_files_checked_called;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline int piece_picker::blocks_in_piece(int index) const
|
inline int piece_picker::blocks_in_piece(int index) const
|
||||||
|
|
|
@ -129,7 +129,7 @@ namespace libtorrent
|
||||||
, resume_data(0)
|
, resume_data(0)
|
||||||
, storage_mode(storage_mode_sparse)
|
, storage_mode(storage_mode_sparse)
|
||||||
, paused(true)
|
, paused(true)
|
||||||
, auto_managed(false)
|
, auto_managed(true)
|
||||||
, duplicate_is_error(false)
|
, duplicate_is_error(false)
|
||||||
, storage(sc)
|
, storage(sc)
|
||||||
, userdata(0)
|
, userdata(0)
|
||||||
|
|
|
@ -149,6 +149,7 @@ namespace libtorrent
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
void on_resume_data_checked(int ret, disk_io_job const& j);
|
void on_resume_data_checked(int ret, disk_io_job const& j);
|
||||||
|
void on_force_recheck(int ret, disk_io_job const& j);
|
||||||
void on_piece_checked(int ret, disk_io_job const& j);
|
void on_piece_checked(int ret, disk_io_job const& j);
|
||||||
void files_checked();
|
void files_checked();
|
||||||
void start_checking();
|
void start_checking();
|
||||||
|
@ -180,6 +181,7 @@ namespace libtorrent
|
||||||
std::string name() const;
|
std::string name() const;
|
||||||
|
|
||||||
stat statistics() const { return m_stat; }
|
stat statistics() const { return m_stat; }
|
||||||
|
void add_stats(stat const& s) { m_stat += s; }
|
||||||
size_type bytes_left() const;
|
size_type bytes_left() const;
|
||||||
boost::tuples::tuple<size_type, size_type> bytes_done() const;
|
boost::tuples::tuple<size_type, size_type> bytes_done() const;
|
||||||
size_type quantized_bytes_done() const;
|
size_type quantized_bytes_done() const;
|
||||||
|
@ -190,6 +192,7 @@ namespace libtorrent
|
||||||
void pause();
|
void pause();
|
||||||
void resume();
|
void resume();
|
||||||
bool is_paused() const { return m_paused; }
|
bool is_paused() const { return m_paused; }
|
||||||
|
void force_recheck();
|
||||||
void save_resume_data();
|
void save_resume_data();
|
||||||
|
|
||||||
bool is_auto_managed() const { return m_auto_managed; }
|
bool is_auto_managed() const { return m_auto_managed; }
|
||||||
|
@ -377,14 +380,15 @@ namespace libtorrent
|
||||||
// returns true if we have downloaded the given piece
|
// returns true if we have downloaded the given piece
|
||||||
bool have_piece(int index) const
|
bool have_piece(int index) const
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(index >= 0 && index < (signed)m_have_pieces.size());
|
return has_picker()?m_picker->have_piece(index):true;
|
||||||
return m_have_pieces[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bitfield const& pieces() const
|
int num_have() const
|
||||||
{ return m_have_pieces; }
|
{
|
||||||
|
return has_picker()
|
||||||
int num_pieces() const { return m_num_pieces; }
|
?m_picker->num_have()
|
||||||
|
:m_torrent_file->num_pieces();
|
||||||
|
}
|
||||||
|
|
||||||
// when we get a have message, this is called for that piece
|
// when we get a have message, this is called for that piece
|
||||||
void peer_has(int index)
|
void peer_has(int index)
|
||||||
|
@ -392,7 +396,6 @@ namespace libtorrent
|
||||||
if (m_picker.get())
|
if (m_picker.get())
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(!is_seed());
|
TORRENT_ASSERT(!is_seed());
|
||||||
TORRENT_ASSERT(index >= 0 && index < (signed)m_have_pieces.size());
|
|
||||||
m_picker->inc_refcount(index);
|
m_picker->inc_refcount(index);
|
||||||
}
|
}
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -439,7 +442,6 @@ namespace libtorrent
|
||||||
if (m_picker.get())
|
if (m_picker.get())
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(!is_seed());
|
TORRENT_ASSERT(!is_seed());
|
||||||
TORRENT_ASSERT(index >= 0 && index < (signed)m_have_pieces.size());
|
|
||||||
m_picker->dec_refcount(index);
|
m_picker->dec_refcount(index);
|
||||||
}
|
}
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -506,7 +508,9 @@ namespace libtorrent
|
||||||
bool is_seed() const
|
bool is_seed() const
|
||||||
{
|
{
|
||||||
return valid_metadata()
|
return valid_metadata()
|
||||||
&& m_num_pieces == m_torrent_file->num_pieces();
|
&& (!m_picker
|
||||||
|
|| m_state == torrent_status::seeding
|
||||||
|
|| m_picker->num_have() == m_picker->num_pieces());
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is true if we have all the pieces that we want
|
// this is true if we have all the pieces that we want
|
||||||
|
@ -514,7 +518,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
if (is_seed()) return true;
|
if (is_seed()) return true;
|
||||||
return valid_metadata() && m_torrent_file->num_pieces()
|
return valid_metadata() && m_torrent_file->num_pieces()
|
||||||
- m_num_pieces - m_picker->num_filtered() == 0;
|
- m_picker->num_have() - m_picker->num_filtered() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::path save_path() const;
|
fs::path save_path() const;
|
||||||
|
@ -740,9 +744,6 @@ namespace libtorrent
|
||||||
std::vector<announce_entry> m_trackers;
|
std::vector<announce_entry> m_trackers;
|
||||||
// this is an index into m_trackers
|
// this is an index into m_trackers
|
||||||
|
|
||||||
// the bitmask that says which pieces we have
|
|
||||||
bitfield m_have_pieces;
|
|
||||||
|
|
||||||
// the number of bytes that has been
|
// the number of bytes that has been
|
||||||
// downloaded that failed the hash-test
|
// downloaded that failed the hash-test
|
||||||
size_type m_total_failed_bytes;
|
size_type m_total_failed_bytes;
|
||||||
|
@ -781,11 +782,6 @@ namespace libtorrent
|
||||||
|
|
||||||
float m_progress;
|
float m_progress;
|
||||||
|
|
||||||
// the number of pieces we have. The same as
|
|
||||||
// std::accumulate(m_have_pieces.begin(),
|
|
||||||
// m_have_pieces.end(), 0)
|
|
||||||
int m_num_pieces;
|
|
||||||
|
|
||||||
// the upload/download ratio that each peer
|
// the upload/download ratio that each peer
|
||||||
// tries to maintain.
|
// tries to maintain.
|
||||||
// 0 is infinite
|
// 0 is infinite
|
||||||
|
@ -908,9 +904,14 @@ namespace libtorrent
|
||||||
// has been initialized with files_checked().
|
// has been initialized with files_checked().
|
||||||
bool m_connections_initialized:1;
|
bool m_connections_initialized:1;
|
||||||
|
|
||||||
#ifndef NDEBUG
|
// is set to true every time there is an incoming
|
||||||
|
// connection to this torrent
|
||||||
|
bool m_has_incoming:1;
|
||||||
|
|
||||||
|
// this is set to true when the files are checked
|
||||||
|
// before the files are checked, we don't try to
|
||||||
|
// connect to peers
|
||||||
bool m_files_checked:1;
|
bool m_files_checked:1;
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline ptime torrent::next_announce() const
|
inline ptime torrent::next_announce() const
|
||||||
|
|
|
@ -100,7 +100,6 @@ namespace libtorrent
|
||||||
, num_incomplete(-1)
|
, num_incomplete(-1)
|
||||||
, list_seeds(0)
|
, list_seeds(0)
|
||||||
, list_peers(0)
|
, list_peers(0)
|
||||||
, pieces(0)
|
|
||||||
, num_pieces(0)
|
, num_pieces(0)
|
||||||
, total_done(0)
|
, total_done(0)
|
||||||
, total_wanted_done(0)
|
, total_wanted_done(0)
|
||||||
|
@ -120,6 +119,7 @@ namespace libtorrent
|
||||||
, seeding_time(0)
|
, seeding_time(0)
|
||||||
, seed_rank(0)
|
, seed_rank(0)
|
||||||
, last_scrape(0)
|
, last_scrape(0)
|
||||||
|
, has_incoming(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
enum state_t
|
enum state_t
|
||||||
|
@ -200,7 +200,7 @@ namespace libtorrent
|
||||||
// we potentially could connect to
|
// we potentially could connect to
|
||||||
int connect_candidates;
|
int connect_candidates;
|
||||||
|
|
||||||
bitfield const* pieces;
|
bitfield pieces;
|
||||||
|
|
||||||
// this is the number of pieces the client has
|
// this is the number of pieces the client has
|
||||||
// downloaded. it is equal to:
|
// downloaded. it is equal to:
|
||||||
|
@ -266,6 +266,10 @@ namespace libtorrent
|
||||||
// number of seconds since last scrape, or -1 if
|
// number of seconds since last scrape, or -1 if
|
||||||
// there hasn't been a scrape
|
// there hasn't been a scrape
|
||||||
int last_scrape;
|
int last_scrape;
|
||||||
|
|
||||||
|
// true if there are incoming connections to this
|
||||||
|
// torrent
|
||||||
|
bool has_incoming;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TORRENT_EXPORT block_info
|
struct TORRENT_EXPORT block_info
|
||||||
|
@ -341,6 +345,7 @@ namespace libtorrent
|
||||||
bool is_paused() const;
|
bool is_paused() const;
|
||||||
void pause() const;
|
void pause() const;
|
||||||
void resume() const;
|
void resume() const;
|
||||||
|
void force_recheck() const;
|
||||||
void save_resume_data() const;
|
void save_resume_data() const;
|
||||||
|
|
||||||
bool is_auto_managed() const;
|
bool is_auto_managed() const;
|
||||||
|
|
|
@ -173,6 +173,9 @@ namespace libtorrent
|
||||||
// response. used to know where in the buffer the
|
// response. used to know where in the buffer the
|
||||||
// next response starts
|
// next response starts
|
||||||
int m_received_body;
|
int m_received_body;
|
||||||
|
|
||||||
|
// position in the current range response
|
||||||
|
int m_range_pos;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -245,7 +245,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
boost::shared_ptr<torrent> t = associated_torrent().lock();
|
boost::shared_ptr<torrent> t = associated_torrent().lock();
|
||||||
TORRENT_ASSERT(t);
|
TORRENT_ASSERT(t);
|
||||||
write_bitfield(t->pieces());
|
write_bitfield();
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
if (m_supports_dht_port && m_ses.m_dht)
|
if (m_supports_dht_port && m_ses.m_dht)
|
||||||
write_dht_port(m_ses.get_dht_settings().service_port);
|
write_dht_port(m_ses.get_dht_settings().service_port);
|
||||||
|
@ -1416,7 +1416,7 @@ namespace libtorrent
|
||||||
send_buffer(msg, sizeof(msg));
|
send_buffer(msg, sizeof(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_peer_connection::write_bitfield(bitfield const& bits)
|
void bt_peer_connection::write_bitfield()
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
|
@ -1426,7 +1426,7 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(t->valid_metadata());
|
TORRENT_ASSERT(t->valid_metadata());
|
||||||
|
|
||||||
// in this case, have_all or have_none should be sent instead
|
// in this case, have_all or have_none should be sent instead
|
||||||
TORRENT_ASSERT(!m_supports_fast || !t->is_seed() || t->num_pieces() != 0);
|
TORRENT_ASSERT(!m_supports_fast || !t->is_seed() || t->num_have() != 0);
|
||||||
|
|
||||||
if (m_supports_fast && t->is_seed())
|
if (m_supports_fast && t->is_seed())
|
||||||
{
|
{
|
||||||
|
@ -1434,13 +1434,13 @@ namespace libtorrent
|
||||||
send_allowed_set();
|
send_allowed_set();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (m_supports_fast && t->num_pieces() == 0)
|
else if (m_supports_fast && t->num_have() == 0)
|
||||||
{
|
{
|
||||||
write_have_none();
|
write_have_none();
|
||||||
send_allowed_set();
|
send_allowed_set();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (t->num_pieces() == 0)
|
else if (t->num_have() == 0)
|
||||||
{
|
{
|
||||||
// don't send a bitfield if we don't have any pieces
|
// don't send a bitfield if we don't have any pieces
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -1449,14 +1449,11 @@ namespace libtorrent
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int num_pieces = bits.size();
|
int num_pieces = t->torrent_file().num_pieces();
|
||||||
int lazy_pieces[50];
|
int lazy_pieces[50];
|
||||||
int num_lazy_pieces = 0;
|
int num_lazy_pieces = 0;
|
||||||
int lazy_piece = 0;
|
int lazy_piece = 0;
|
||||||
|
|
||||||
TORRENT_ASSERT(t->is_seed() == (bits.count()
|
|
||||||
== num_pieces));
|
|
||||||
|
|
||||||
if (t->is_seed() && m_ses.settings().lazy_bitfields)
|
if (t->is_seed() && m_ses.settings().lazy_bitfields)
|
||||||
{
|
{
|
||||||
num_lazy_pieces = (std::min)(50, num_pieces / 10);
|
num_lazy_pieces = (std::min)(50, num_pieces / 10);
|
||||||
|
@ -1470,26 +1467,6 @@ namespace libtorrent
|
||||||
lazy_piece = 0;
|
lazy_piece = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TORRENT_VERBOSE_LOGGING
|
|
||||||
(*m_logger) << time_now_string() << " ==> BITFIELD ";
|
|
||||||
|
|
||||||
std::stringstream bitfield_string;
|
|
||||||
for (int i = 0; i < (int)get_bitfield().size(); ++i)
|
|
||||||
{
|
|
||||||
if (lazy_piece < num_lazy_pieces
|
|
||||||
&& lazy_pieces[lazy_piece] == i)
|
|
||||||
{
|
|
||||||
bitfield_string << "0";
|
|
||||||
++lazy_piece;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (bits[i]) bitfield_string << "1";
|
|
||||||
else bitfield_string << "0";
|
|
||||||
}
|
|
||||||
bitfield_string << "\n";
|
|
||||||
(*m_logger) << bitfield_string.str();
|
|
||||||
lazy_piece = 0;
|
|
||||||
#endif
|
|
||||||
const int packet_size = (num_pieces + 7) / 8 + 5;
|
const int packet_size = (num_pieces + 7) / 8 + 5;
|
||||||
|
|
||||||
buffer::interval i = allocate_send_buffer(packet_size);
|
buffer::interval i = allocate_send_buffer(packet_size);
|
||||||
|
@ -1498,15 +1475,46 @@ namespace libtorrent
|
||||||
detail::write_int32(packet_size - 4, i.begin);
|
detail::write_int32(packet_size - 4, i.begin);
|
||||||
detail::write_uint8(msg_bitfield, i.begin);
|
detail::write_uint8(msg_bitfield, i.begin);
|
||||||
|
|
||||||
memcpy(i.begin, bits.bytes(), packet_size - 5);
|
if (t->is_seed())
|
||||||
|
{
|
||||||
|
memset(i.begin, 0xff, packet_size - 5);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset(i.begin, 0, packet_size - 5);
|
||||||
|
piece_picker const& p = t->picker();
|
||||||
|
int mask = 0x80;
|
||||||
|
unsigned char* byte = (unsigned char*)i.begin;
|
||||||
|
for (int i = 0; i < num_pieces; ++i)
|
||||||
|
{
|
||||||
|
if (p.have_piece(i)) *byte |= mask;
|
||||||
|
mask >>= 1;
|
||||||
|
if (mask == 0)
|
||||||
|
{
|
||||||
|
mask = 0x80;
|
||||||
|
++byte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
for (int c = 0; c < num_lazy_pieces; ++c)
|
for (int c = 0; c < num_lazy_pieces; ++c)
|
||||||
i.begin[lazy_pieces[c] / 8] &= ~(0x80 >> (lazy_pieces[c] & 7));
|
i.begin[lazy_pieces[c] / 8] &= ~(0x80 >> (lazy_pieces[c] & 7));
|
||||||
TORRENT_ASSERT(i.end - i.begin == (num_pieces + 7) / 8);
|
TORRENT_ASSERT(i.end - i.begin == (num_pieces + 7) / 8);
|
||||||
|
|
||||||
|
#ifdef TORRENT_VERBOSE_LOGGING
|
||||||
|
(*m_logger) << time_now_string() << " ==> BITFIELD ";
|
||||||
|
|
||||||
|
std::stringstream bitfield_string;
|
||||||
|
for (int k = 0; k < num_pieces; ++k)
|
||||||
|
{
|
||||||
|
if (i.begin[k / 8] & (0x80 >> (k % 8))) bitfield_string << "1";
|
||||||
|
else bitfield_string << "0";
|
||||||
|
}
|
||||||
|
bitfield_string << "\n";
|
||||||
|
(*m_logger) << bitfield_string.str();
|
||||||
|
#endif
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
m_sent_bitfield = true;
|
m_sent_bitfield = true;
|
||||||
#endif
|
#endif
|
||||||
setup_send();
|
|
||||||
|
|
||||||
if (num_lazy_pieces > 0)
|
if (num_lazy_pieces > 0)
|
||||||
{
|
{
|
||||||
|
@ -1522,6 +1530,7 @@ namespace libtorrent
|
||||||
|
|
||||||
if (m_supports_fast)
|
if (m_supports_fast)
|
||||||
send_allowed_set();
|
send_allowed_set();
|
||||||
|
setup_send();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||||
|
@ -2377,7 +2386,7 @@ namespace libtorrent
|
||||||
// sent the handshake
|
// sent the handshake
|
||||||
if (!is_local()) write_handshake();
|
if (!is_local()) write_handshake();
|
||||||
// if (t->valid_metadata())
|
// if (t->valid_metadata())
|
||||||
// write_bitfield(t->pieces());
|
// write_bitfield();
|
||||||
|
|
||||||
if (is_disconnecting()) return;
|
if (is_disconnecting()) return;
|
||||||
|
|
||||||
|
@ -2511,7 +2520,7 @@ namespace libtorrent
|
||||||
reset_recv_buffer(5);
|
reset_recv_buffer(5);
|
||||||
if (t->valid_metadata())
|
if (t->valid_metadata())
|
||||||
{
|
{
|
||||||
write_bitfield(t->pieces());
|
write_bitfield();
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
if (m_supports_dht_port && m_ses.m_dht)
|
if (m_supports_dht_port && m_ses.m_dht)
|
||||||
write_dht_port(m_ses.get_dht_settings().service_port);
|
write_dht_port(m_ses.get_dht_settings().service_port);
|
||||||
|
|
|
@ -301,8 +301,11 @@ void http_connection::connect(int ticket, tcp::endpoint target_address)
|
||||||
|
|
||||||
void http_connection::on_connect(error_code const& e)
|
void http_connection::on_connect(error_code const& e)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(m_connection_ticket >= 0);
|
if (m_connection_ticket >= 0)
|
||||||
m_cc.done(m_connection_ticket);
|
{
|
||||||
|
m_cc.done(m_connection_ticket);
|
||||||
|
m_connection_ticket = -1;
|
||||||
|
}
|
||||||
|
|
||||||
m_last_receive = time_now();
|
m_last_receive = time_now();
|
||||||
if (!e)
|
if (!e)
|
||||||
|
|
|
@ -63,9 +63,10 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(recv_buffer.left() >= m_recv_buffer.left());
|
TORRENT_ASSERT(recv_buffer.left() >= m_recv_buffer.left());
|
||||||
boost::tuple<int, int> ret(0, 0);
|
boost::tuple<int, int> ret(0, 0);
|
||||||
|
int start_pos = m_recv_buffer.left();
|
||||||
|
|
||||||
// early exit if there's nothing new in the receive buffer
|
// early exit if there's nothing new in the receive buffer
|
||||||
if (recv_buffer.left() == m_recv_buffer.left()) return ret;
|
if (start_pos == recv_buffer.left()) return ret;
|
||||||
m_recv_buffer = recv_buffer;
|
m_recv_buffer = recv_buffer;
|
||||||
|
|
||||||
if (m_state == error_state)
|
if (m_state == error_state)
|
||||||
|
@ -80,7 +81,11 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(!m_finished);
|
TORRENT_ASSERT(!m_finished);
|
||||||
char const* newline = std::find(pos, recv_buffer.end, '\n');
|
char const* newline = std::find(pos, recv_buffer.end, '\n');
|
||||||
// if we don't have a full line yet, wait.
|
// if we don't have a full line yet, wait.
|
||||||
if (newline == recv_buffer.end) return ret;
|
if (newline == recv_buffer.end)
|
||||||
|
{
|
||||||
|
boost::get<1>(ret) += m_recv_buffer.left() - start_pos;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if (newline == pos)
|
if (newline == pos)
|
||||||
{
|
{
|
||||||
|
@ -96,7 +101,7 @@ namespace libtorrent
|
||||||
++newline;
|
++newline;
|
||||||
int incoming = (int)std::distance(pos, newline);
|
int incoming = (int)std::distance(pos, newline);
|
||||||
m_recv_pos += incoming;
|
m_recv_pos += incoming;
|
||||||
boost::get<1>(ret) += incoming;
|
boost::get<1>(ret) += newline - (m_recv_buffer.begin + start_pos);
|
||||||
pos = newline;
|
pos = newline;
|
||||||
|
|
||||||
line >> m_protocol;
|
line >> m_protocol;
|
||||||
|
@ -114,6 +119,7 @@ namespace libtorrent
|
||||||
m_status_code = 0;
|
m_status_code = 0;
|
||||||
}
|
}
|
||||||
m_state = read_header;
|
m_state = read_header;
|
||||||
|
start_pos = pos - recv_buffer.begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_state == read_header)
|
if (m_state == read_header)
|
||||||
|
@ -131,7 +137,6 @@ namespace libtorrent
|
||||||
line.assign(pos, line_end);
|
line.assign(pos, line_end);
|
||||||
++newline;
|
++newline;
|
||||||
m_recv_pos += newline - pos;
|
m_recv_pos += newline - pos;
|
||||||
boost::get<1>(ret) += newline - pos;
|
|
||||||
pos = newline;
|
pos = newline;
|
||||||
|
|
||||||
std::string::size_type separator = line.find(':');
|
std::string::size_type separator = line.find(':');
|
||||||
|
@ -187,6 +192,7 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(m_recv_pos <= (int)recv_buffer.left());
|
TORRENT_ASSERT(m_recv_pos <= (int)recv_buffer.left());
|
||||||
newline = std::find(pos, recv_buffer.end, '\n');
|
newline = std::find(pos, recv_buffer.end, '\n');
|
||||||
}
|
}
|
||||||
|
boost::get<1>(ret) += newline - (m_recv_buffer.begin + start_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_state == read_body)
|
if (m_state == read_body)
|
||||||
|
|
|
@ -225,7 +225,14 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle tracker response
|
// handle tracker response
|
||||||
entry e = bdecode(data, data + size);
|
entry e;
|
||||||
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
|
try {
|
||||||
|
#endif
|
||||||
|
e = bdecode(data, data + size);
|
||||||
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
|
} catch (std::exception&) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (e.type() != entry::undefined_t)
|
if (e.type() != entry::undefined_t)
|
||||||
{
|
{
|
||||||
|
|
|
@ -326,15 +326,19 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(t);
|
TORRENT_ASSERT(t);
|
||||||
|
|
||||||
bool interested = false;
|
bool interested = false;
|
||||||
bitfield const& we_have = t->pieces();
|
if (!t->is_finished())
|
||||||
for (int j = 0; j != (int)we_have.size(); ++j)
|
|
||||||
{
|
{
|
||||||
if (!we_have[j]
|
piece_picker const& p = t->picker();
|
||||||
&& t->piece_priority(j) > 0
|
int num_pieces = p.num_pieces();
|
||||||
&& m_have_piece[j])
|
for (int j = 0; j != num_pieces; ++j)
|
||||||
{
|
{
|
||||||
interested = true;
|
if (!p.have_piece(j)
|
||||||
break;
|
&& t->piece_priority(j) > 0
|
||||||
|
&& m_have_piece[j])
|
||||||
|
{
|
||||||
|
interested = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
|
@ -2218,6 +2222,10 @@ namespace libtorrent
|
||||||
|
|
||||||
if (t)
|
if (t)
|
||||||
{
|
{
|
||||||
|
// make sure we keep all the stats!
|
||||||
|
calc_ip_overhead();
|
||||||
|
t->add_stats(statistics());
|
||||||
|
|
||||||
if (t->has_picker())
|
if (t->has_picker())
|
||||||
{
|
{
|
||||||
piece_picker& picker = t->picker();
|
piece_picker& picker = t->picker();
|
||||||
|
|
|
@ -58,10 +58,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
|
||||||
piece_picker::piece_picker(int blocks_per_piece, int total_num_blocks)
|
piece_picker::piece_picker()
|
||||||
: m_seeds(0)
|
: m_seeds(0)
|
||||||
, m_priority_boundries(1, int(m_pieces.size()))
|
, m_priority_boundries(1, int(m_pieces.size()))
|
||||||
, m_piece_map((total_num_blocks + blocks_per_piece-1) / blocks_per_piece)
|
|
||||||
, m_num_filtered(0)
|
, m_num_filtered(0)
|
||||||
, m_num_have_filtered(0)
|
, m_num_have_filtered(0)
|
||||||
, m_num_have(0)
|
, m_num_have(0)
|
||||||
|
@ -69,13 +68,22 @@ namespace libtorrent
|
||||||
, m_dirty(false)
|
, m_dirty(false)
|
||||||
{
|
{
|
||||||
#ifdef TORRENT_PICKER_LOG
|
#ifdef TORRENT_PICKER_LOG
|
||||||
std::cout << "new piece_picker" << std::endl;
|
std::cerr << "new piece_picker" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef NDEBUG
|
||||||
|
check_invariant();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void piece_picker::init(int blocks_per_piece, int total_num_blocks)
|
||||||
|
{
|
||||||
TORRENT_ASSERT(blocks_per_piece > 0);
|
TORRENT_ASSERT(blocks_per_piece > 0);
|
||||||
TORRENT_ASSERT(total_num_blocks >= 0);
|
TORRENT_ASSERT(total_num_blocks >= 0);
|
||||||
#ifndef NDEBUG
|
|
||||||
m_files_checked_called = false;
|
// allocate the piece_map to cover all pieces
|
||||||
#endif
|
// and make them invalid (as if we don't have a single piece)
|
||||||
|
m_piece_map.resize((total_num_blocks + blocks_per_piece-1) / blocks_per_piece
|
||||||
|
, piece_pos(0, 0));
|
||||||
|
|
||||||
// the piece index is stored in 20 bits, which limits the allowed
|
// the piece index is stored in 20 bits, which limits the allowed
|
||||||
// number of pieces somewhat
|
// number of pieces somewhat
|
||||||
|
@ -87,15 +95,6 @@ namespace libtorrent
|
||||||
if (m_blocks_in_last_piece == 0) m_blocks_in_last_piece = blocks_per_piece;
|
if (m_blocks_in_last_piece == 0) m_blocks_in_last_piece = blocks_per_piece;
|
||||||
|
|
||||||
TORRENT_ASSERT(m_blocks_in_last_piece <= m_blocks_per_piece);
|
TORRENT_ASSERT(m_blocks_in_last_piece <= m_blocks_per_piece);
|
||||||
|
|
||||||
// allocate the piece_map to cover all pieces
|
|
||||||
// and make them invalid (as if we don't have a single piece)
|
|
||||||
std::fill(m_piece_map.begin(), m_piece_map.end()
|
|
||||||
, piece_pos(0, 0));
|
|
||||||
m_num_have = 0;
|
|
||||||
#ifndef NDEBUG
|
|
||||||
check_invariant();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void piece_picker::sequential_download(bool sd)
|
void piece_picker::sequential_download(bool sd)
|
||||||
|
@ -122,24 +121,6 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pieces is a bitmask with the pieces we have
|
|
||||||
void piece_picker::init(bitfield const& pieces)
|
|
||||||
{
|
|
||||||
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
|
||||||
#ifndef NDEBUG
|
|
||||||
m_files_checked_called = true;
|
|
||||||
#endif
|
|
||||||
int index = 0;
|
|
||||||
for (bitfield::const_iterator i = pieces.begin();
|
|
||||||
i != pieces.end(); ++i, ++index)
|
|
||||||
{
|
|
||||||
TORRENT_ASSERT(index < pieces.size());
|
|
||||||
piece_pos& p = m_piece_map[index];
|
|
||||||
if (*i) we_have(index);
|
|
||||||
else TORRENT_ASSERT(p.index == 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void piece_picker::piece_info(int index, piece_picker::downloading_piece& st) const
|
void piece_picker::piece_info(int index, piece_picker::downloading_piece& st) const
|
||||||
{
|
{
|
||||||
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
||||||
|
@ -249,7 +230,7 @@ namespace libtorrent
|
||||||
for (std::vector<int>::const_iterator i = m_priority_boundries.begin()
|
for (std::vector<int>::const_iterator i = m_priority_boundries.begin()
|
||||||
, end(m_priority_boundries.end()); i != end; ++i)
|
, end(m_priority_boundries.end()); i != end; ++i)
|
||||||
{
|
{
|
||||||
std::cout << *i << " ";
|
std::cerr << *i << " ";
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
@ -260,12 +241,12 @@ namespace libtorrent
|
||||||
if (*i == -1) break;
|
if (*i == -1) break;
|
||||||
while (j != m_priority_boundries.end() && *j <= index)
|
while (j != m_priority_boundries.end() && *j <= index)
|
||||||
{
|
{
|
||||||
std::cout << "| ";
|
std::cerr << "| ";
|
||||||
++j;
|
++j;
|
||||||
}
|
}
|
||||||
std::cout << *i << "(" << m_piece_map[*i].index << ") ";
|
std::cerr << *i << "(" << m_piece_map[*i].index << ") ";
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
std::cerr << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void piece_picker::check_invariant(const torrent* t) const
|
void piece_picker::check_invariant(const torrent* t) const
|
||||||
|
@ -534,7 +515,7 @@ namespace libtorrent
|
||||||
else new_index = rand() % (range_end - range_start) + range_start;
|
else new_index = rand() % (range_end - range_start) + range_start;
|
||||||
|
|
||||||
#ifdef TORRENT_PICKER_LOG
|
#ifdef TORRENT_PICKER_LOG
|
||||||
std::cout << "add " << index << " (" << priority << ")" << std::endl;
|
std::cerr << "add " << index << " (" << priority << ")" << std::endl;
|
||||||
print_pieces();
|
print_pieces();
|
||||||
#endif
|
#endif
|
||||||
m_pieces.push_back(-1);
|
m_pieces.push_back(-1);
|
||||||
|
@ -554,7 +535,7 @@ namespace libtorrent
|
||||||
new_index = temp;
|
new_index = temp;
|
||||||
#ifdef TORRENT_PICKER_LOG
|
#ifdef TORRENT_PICKER_LOG
|
||||||
print_pieces();
|
print_pieces();
|
||||||
std::cout << " index: " << index
|
std::cerr << " index: " << index
|
||||||
<< " prio: " << priority
|
<< " prio: " << priority
|
||||||
<< " new_index: " << new_index
|
<< " new_index: " << new_index
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
@ -581,7 +562,7 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(m_sequential_download == -1);
|
TORRENT_ASSERT(m_sequential_download == -1);
|
||||||
|
|
||||||
#ifdef TORRENT_PICKER_LOG
|
#ifdef TORRENT_PICKER_LOG
|
||||||
std::cout << "remove " << m_pieces[elem_index] << " (" << priority << ")" << std::endl;
|
std::cerr << "remove " << m_pieces[elem_index] << " (" << priority << ")" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
int next_index = elem_index;
|
int next_index = elem_index;
|
||||||
TORRENT_ASSERT(m_piece_map[m_pieces[elem_index]].priority(this) == -1);
|
TORRENT_ASSERT(m_piece_map[m_pieces[elem_index]].priority(this) == -1);
|
||||||
|
@ -624,7 +605,6 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(!m_dirty);
|
TORRENT_ASSERT(!m_dirty);
|
||||||
TORRENT_ASSERT(priority >= 0);
|
TORRENT_ASSERT(priority >= 0);
|
||||||
TORRENT_ASSERT(elem_index >= 0);
|
TORRENT_ASSERT(elem_index >= 0);
|
||||||
TORRENT_ASSERT(m_files_checked_called);
|
|
||||||
TORRENT_ASSERT(m_sequential_download == -1);
|
TORRENT_ASSERT(m_sequential_download == -1);
|
||||||
|
|
||||||
TORRENT_ASSERT(int(m_priority_boundries.size()) > priority);
|
TORRENT_ASSERT(int(m_priority_boundries.size()) > priority);
|
||||||
|
@ -648,7 +628,7 @@ namespace libtorrent
|
||||||
m_priority_boundries.resize(new_priority + 1, m_pieces.size());
|
m_priority_boundries.resize(new_priority + 1, m_pieces.size());
|
||||||
|
|
||||||
#ifdef TORRENT_PICKER_LOG
|
#ifdef TORRENT_PICKER_LOG
|
||||||
std::cout << "update " << index << " (" << priority << "->" << new_priority << ")" << std::endl;
|
std::cerr << "update " << index << " (" << priority << "->" << new_priority << ")" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
if (priority > new_priority)
|
if (priority > new_priority)
|
||||||
{
|
{
|
||||||
|
@ -772,7 +752,6 @@ namespace libtorrent
|
||||||
|
|
||||||
TORRENT_ASSERT(index >= 0);
|
TORRENT_ASSERT(index >= 0);
|
||||||
TORRENT_ASSERT(index < (int)m_piece_map.size());
|
TORRENT_ASSERT(index < (int)m_piece_map.size());
|
||||||
TORRENT_ASSERT(m_files_checked_called);
|
|
||||||
|
|
||||||
TORRENT_ASSERT(m_piece_map[index].downloading == 1);
|
TORRENT_ASSERT(m_piece_map[index].downloading == 1);
|
||||||
|
|
||||||
|
@ -804,7 +783,6 @@ namespace libtorrent
|
||||||
void piece_picker::inc_refcount_all()
|
void piece_picker::inc_refcount_all()
|
||||||
{
|
{
|
||||||
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
||||||
TORRENT_ASSERT(m_files_checked_called);
|
|
||||||
++m_seeds;
|
++m_seeds;
|
||||||
if (m_sequential_download >= 0) return;
|
if (m_sequential_download >= 0) return;
|
||||||
if (m_seeds == 1)
|
if (m_seeds == 1)
|
||||||
|
@ -819,7 +797,6 @@ namespace libtorrent
|
||||||
void piece_picker::dec_refcount_all()
|
void piece_picker::dec_refcount_all()
|
||||||
{
|
{
|
||||||
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
||||||
TORRENT_ASSERT(m_files_checked_called);
|
|
||||||
|
|
||||||
if (m_sequential_download >= 0)
|
if (m_sequential_download >= 0)
|
||||||
{
|
{
|
||||||
|
@ -935,7 +912,7 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(m_sequential_download == -1);
|
TORRENT_ASSERT(m_sequential_download == -1);
|
||||||
if (m_priority_boundries.empty()) m_priority_boundries.resize(1, 0);
|
if (m_priority_boundries.empty()) m_priority_boundries.resize(1, 0);
|
||||||
#ifdef TORRENT_PICKER_LOG
|
#ifdef TORRENT_PICKER_LOG
|
||||||
std::cout << "update_pieces" << std::endl;
|
std::cerr << "update_pieces" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
std::fill(m_priority_boundries.begin(), m_priority_boundries.end(), 0);
|
std::fill(m_priority_boundries.begin(), m_priority_boundries.end(), 0);
|
||||||
for (std::vector<piece_pos>::iterator i = m_piece_map.begin()
|
for (std::vector<piece_pos>::iterator i = m_piece_map.begin()
|
||||||
|
@ -1004,6 +981,33 @@ namespace libtorrent
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void piece_picker::we_dont_have(int index)
|
||||||
|
{
|
||||||
|
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
||||||
|
TORRENT_ASSERT(index >= 0);
|
||||||
|
TORRENT_ASSERT(index < (int)m_piece_map.size());
|
||||||
|
|
||||||
|
piece_pos& p = m_piece_map[index];
|
||||||
|
TORRENT_ASSERT(p.downloading == 0);
|
||||||
|
|
||||||
|
if (!p.have()) return;
|
||||||
|
|
||||||
|
if (m_sequential_download > index)
|
||||||
|
m_sequential_download = index;
|
||||||
|
|
||||||
|
if (p.filtered())
|
||||||
|
{
|
||||||
|
++m_num_filtered;
|
||||||
|
--m_num_have_filtered;
|
||||||
|
}
|
||||||
|
|
||||||
|
--m_num_have;
|
||||||
|
p.set_not_have();
|
||||||
|
|
||||||
|
if (m_dirty) return;
|
||||||
|
if (!p.filtered()) add(index);
|
||||||
|
}
|
||||||
|
|
||||||
// this is used to indicate that we succesfully have
|
// this is used to indicate that we succesfully have
|
||||||
// downloaded a piece, and that no further attempts
|
// downloaded a piece, and that no further attempts
|
||||||
// to pick that piece should be made. The piece will
|
// to pick that piece should be made. The piece will
|
||||||
|
@ -1167,7 +1171,6 @@ namespace libtorrent
|
||||||
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
||||||
TORRENT_ASSERT(num_blocks > 0);
|
TORRENT_ASSERT(num_blocks > 0);
|
||||||
TORRENT_ASSERT(pieces.size() == m_piece_map.size());
|
TORRENT_ASSERT(pieces.size() == m_piece_map.size());
|
||||||
TORRENT_ASSERT(m_files_checked_called);
|
|
||||||
|
|
||||||
TORRENT_ASSERT(!m_priority_boundries.empty()
|
TORRENT_ASSERT(!m_priority_boundries.empty()
|
||||||
|| m_sequential_download >= 0
|
|| m_sequential_download >= 0
|
||||||
|
|
|
@ -200,7 +200,7 @@ namespace libtorrent
|
||||||
|
|
||||||
int prefer_whole_pieces = c.prefer_whole_pieces();
|
int prefer_whole_pieces = c.prefer_whole_pieces();
|
||||||
|
|
||||||
bool rarest_first = t.num_pieces() >= t.settings().initial_picker_threshold;
|
bool rarest_first = t.num_have() >= t.settings().initial_picker_threshold;
|
||||||
|
|
||||||
if (prefer_whole_pieces == 0)
|
if (prefer_whole_pieces == 0)
|
||||||
{
|
{
|
||||||
|
@ -644,7 +644,7 @@ namespace libtorrent
|
||||||
error_code ec;
|
error_code ec;
|
||||||
TORRENT_ASSERT(c.remote() == c.get_socket()->remote_endpoint(ec) || ec);
|
TORRENT_ASSERT(c.remote() == c.get_socket()->remote_endpoint(ec) || ec);
|
||||||
|
|
||||||
if (m_peers.size() >= m_torrent->settings().max_peerlist_size)
|
if (int(m_peers.size()) >= m_torrent->settings().max_peerlist_size)
|
||||||
{
|
{
|
||||||
c.disconnect("peer list size exceeded, refusing incoming connection");
|
c.disconnect("peer list size exceeded, refusing incoming connection");
|
||||||
return false;
|
return false;
|
||||||
|
@ -773,7 +773,7 @@ namespace libtorrent
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_peers.size() >= m_torrent->settings().max_peerlist_size)
|
if (int(m_peers.size()) >= m_torrent->settings().max_peerlist_size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// we don't have any info about this peer.
|
// we don't have any info about this peer.
|
||||||
|
@ -1018,11 +1018,14 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(!p->second.connection);
|
TORRENT_ASSERT(!p->second.connection);
|
||||||
TORRENT_ASSERT(p->second.type == peer::connectable);
|
TORRENT_ASSERT(p->second.type == peer::connectable);
|
||||||
|
|
||||||
|
TORRENT_ASSERT(is_connect_candidate(p->second, m_torrent->is_finished()));
|
||||||
if (!m_torrent->connect_to_peer(&p->second))
|
if (!m_torrent->connect_to_peer(&p->second))
|
||||||
{
|
{
|
||||||
++p->second.failcount;
|
++p->second.failcount;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
TORRENT_ASSERT(!is_connect_candidate(p->second, m_torrent->is_finished()));
|
||||||
|
--m_num_connect_candidates;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,9 +95,12 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(UNICODE)
|
#if TORRENT_USE_WPATH
|
||||||
|
|
||||||
|
#ifdef BOOST_WINDOWS
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/filesystem/exception.hpp>
|
#include <boost/filesystem/exception.hpp>
|
||||||
#include "libtorrent/utf8.hpp"
|
#include "libtorrent/utf8.hpp"
|
||||||
#include "libtorrent/buffer.hpp"
|
#include "libtorrent/buffer.hpp"
|
||||||
|
@ -249,7 +252,53 @@ namespace
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
template <class Path>
|
||||||
|
void recursive_copy(Path const& old_path, Path const& new_path, std::string& error)
|
||||||
|
{
|
||||||
|
using boost::filesystem::directory_iterator;
|
||||||
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
|
try {
|
||||||
|
#endif
|
||||||
|
TORRENT_ASSERT(error.empty());
|
||||||
|
if (is_directory(old_path))
|
||||||
|
{
|
||||||
|
create_directory(new_path);
|
||||||
|
for (directory_iterator i(old_path), end; i != end; ++i)
|
||||||
|
{
|
||||||
|
recursive_copy(i->path(), new_path / i->leaf(), error);
|
||||||
|
if (!error.empty()) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
copy_file(old_path, new_path);
|
||||||
|
}
|
||||||
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
|
} catch (std::exception& e) { error = e.what(); }
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Path>
|
||||||
|
void recursive_remove(Path const& old_path)
|
||||||
|
{
|
||||||
|
using boost::filesystem::directory_iterator;
|
||||||
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
|
try {
|
||||||
|
#endif
|
||||||
|
if (is_directory(old_path))
|
||||||
|
{
|
||||||
|
for (directory_iterator i(old_path), end; i != end; ++i)
|
||||||
|
recursive_remove(i->path());
|
||||||
|
remove(old_path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
remove(old_path);
|
||||||
|
}
|
||||||
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
|
} catch (std::exception& e) {}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
std::vector<std::pair<size_type, std::time_t> > get_filesizes(
|
std::vector<std::pair<size_type, std::time_t> > get_filesizes(
|
||||||
file_storage const& s, fs::path p)
|
file_storage const& s, fs::path p)
|
||||||
{
|
{
|
||||||
|
@ -260,7 +309,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
size_type size = 0;
|
size_type size = 0;
|
||||||
std::time_t time = 0;
|
std::time_t time = 0;
|
||||||
#if defined(_WIN32) && defined(UNICODE)
|
#if TORRENT_USE_WPATH
|
||||||
fs::wpath f = safe_convert((p / i->path).string());
|
fs::wpath f = safe_convert((p / i->path).string());
|
||||||
#else
|
#else
|
||||||
fs::path f = p / i->path;
|
fs::path f = p / i->path;
|
||||||
|
@ -310,7 +359,7 @@ namespace libtorrent
|
||||||
size_type size = 0;
|
size_type size = 0;
|
||||||
std::time_t time = 0;
|
std::time_t time = 0;
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(UNICODE)
|
#if TORRENT_USE_WPATH
|
||||||
fs::wpath f = safe_convert((p / i->path).string());
|
fs::wpath f = safe_convert((p / i->path).string());
|
||||||
#else
|
#else
|
||||||
fs::path f = p / i->path;
|
fs::path f = p / i->path;
|
||||||
|
@ -443,7 +492,7 @@ namespace libtorrent
|
||||||
last_path = dir;
|
last_path = dir;
|
||||||
if (!exists_win(last_path))
|
if (!exists_win(last_path))
|
||||||
create_directories_win(last_path);
|
create_directories_win(last_path);
|
||||||
#elif defined(_WIN32) && defined(UNICODE)
|
#elif TORRENT_USE_WPATH
|
||||||
last_path = dir;
|
last_path = dir;
|
||||||
fs::wpath wp = safe_convert(last_path.string());
|
fs::wpath wp = safe_convert(last_path.string());
|
||||||
if (!exists(wp))
|
if (!exists(wp))
|
||||||
|
@ -506,9 +555,9 @@ namespace libtorrent
|
||||||
fs::path old_name = m_save_path / files().at(index).path;
|
fs::path old_name = m_save_path / files().at(index).path;
|
||||||
m_pool.release(old_name);
|
m_pool.release(old_name);
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(UNICODE) && BOOST_VERSION >= 103400
|
#if TORRENT_USE_WPATH
|
||||||
fs::wpath old_path = safe_convert(old_name);
|
fs::wpath old_path = safe_convert(old_name.string());
|
||||||
fs::wpath new_path = safe_convert(m_save_path / new_filename);
|
fs::wpath new_path = safe_convert((m_save_path / new_filename).string());
|
||||||
#else
|
#else
|
||||||
fs::path const& old_path = old_name;
|
fs::path const& old_path = old_name;
|
||||||
fs::path new_path = m_save_path / new_filename;
|
fs::path new_path = m_save_path / new_filename;
|
||||||
|
@ -565,7 +614,7 @@ namespace libtorrent
|
||||||
std::pair<iter_t, bool> ret = directories.insert((m_save_path / bp).string());
|
std::pair<iter_t, bool> ret = directories.insert((m_save_path / bp).string());
|
||||||
bp = bp.branch_path();
|
bp = bp.branch_path();
|
||||||
}
|
}
|
||||||
#if defined(_WIN32) && defined(UNICODE)
|
#if TORRENT_USE_WPATH
|
||||||
try
|
try
|
||||||
{ fs::remove(safe_convert(p)); }
|
{ fs::remove(safe_convert(p)); }
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
|
@ -590,7 +639,7 @@ namespace libtorrent
|
||||||
for (std::set<std::string>::reverse_iterator i = directories.rbegin()
|
for (std::set<std::string>::reverse_iterator i = directories.rbegin()
|
||||||
, end(directories.rend()); i != end; ++i)
|
, end(directories.rend()); i != end; ++i)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32) && defined(UNICODE)
|
#if TORRENT_USE_WPATH
|
||||||
try
|
try
|
||||||
{ fs::remove(safe_convert(*i)); }
|
{ fs::remove(safe_convert(*i)); }
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
|
@ -725,7 +774,7 @@ namespace libtorrent
|
||||||
// returns true on success
|
// returns true on success
|
||||||
bool storage::move_storage(fs::path save_path)
|
bool storage::move_storage(fs::path save_path)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32) && defined(UNICODE) && BOOST_VERSION >= 103400
|
#if TORRENT_USE_WPATH
|
||||||
fs::wpath old_path;
|
fs::wpath old_path;
|
||||||
fs::wpath new_path;
|
fs::wpath new_path;
|
||||||
#else
|
#else
|
||||||
|
@ -741,7 +790,7 @@ namespace libtorrent
|
||||||
CreateDirectory(wsave_path.c_str(), 0);
|
CreateDirectory(wsave_path.c_str(), 0);
|
||||||
else if ((GetFileAttributes(wsave_path.c_str()) & FILE_ATTRIBUTE_DIRECTORY) == 0)
|
else if ((GetFileAttributes(wsave_path.c_str()) & FILE_ATTRIBUTE_DIRECTORY) == 0)
|
||||||
return false;
|
return false;
|
||||||
#elif defined(_WIN32) && defined(UNICODE)
|
#elif TORRENT_USE_WPATH
|
||||||
fs::wpath wp = safe_convert(save_path.string());
|
fs::wpath wp = safe_convert(save_path.string());
|
||||||
if (!exists(wp))
|
if (!exists(wp))
|
||||||
create_directory(wp);
|
create_directory(wp);
|
||||||
|
@ -756,7 +805,7 @@ namespace libtorrent
|
||||||
|
|
||||||
m_pool.release(this);
|
m_pool.release(this);
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(UNICODE) && BOOST_VERSION >= 103400
|
#if TORRENT_USE_WPATH
|
||||||
old_path = safe_convert((m_save_path / files().name()).string());
|
old_path = safe_convert((m_save_path / files().name()).string());
|
||||||
new_path = safe_convert((save_path / files().name()).string());
|
new_path = safe_convert((save_path / files().name()).string());
|
||||||
#else
|
#else
|
||||||
|
@ -770,7 +819,6 @@ namespace libtorrent
|
||||||
#endif
|
#endif
|
||||||
#if defined(_WIN32) && defined(UNICODE) && BOOST_VERSION < 103400
|
#if defined(_WIN32) && defined(UNICODE) && BOOST_VERSION < 103400
|
||||||
rename_win(old_path, new_path);
|
rename_win(old_path, new_path);
|
||||||
rename(old_path, new_path);
|
|
||||||
#else
|
#else
|
||||||
rename(old_path, new_path);
|
rename(old_path, new_path);
|
||||||
#endif
|
#endif
|
||||||
|
@ -780,8 +828,15 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
set_error((m_save_path / files().name()).string(), e.what());
|
std::string err;
|
||||||
return true;
|
recursive_copy(old_path, new_path, err);
|
||||||
|
if (!err.empty())
|
||||||
|
{
|
||||||
|
set_error((m_save_path / files().name()).string(), e.what());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
m_save_path = save_path;
|
||||||
|
recursive_remove(old_path);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
|
@ -1648,7 +1703,7 @@ namespace libtorrent
|
||||||
#endif
|
#endif
|
||||||
#if defined(_WIN32) && defined(UNICODE) && BOOST_VERSION < 103400
|
#if defined(_WIN32) && defined(UNICODE) && BOOST_VERSION < 103400
|
||||||
file_exists = exists_win(f);
|
file_exists = exists_win(f);
|
||||||
#elif defined(_WIN32) && defined(UNICODE)
|
#elif TORRENT_USE_WPATH
|
||||||
fs::wpath wf = safe_convert(f.string());
|
fs::wpath wf = safe_convert(f.string());
|
||||||
file_exists = exists(wf);
|
file_exists = exists(wf);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -164,7 +164,7 @@ namespace libtorrent
|
||||||
, m_last_dht_announce(time_now() - minutes(15))
|
, m_last_dht_announce(time_now() - minutes(15))
|
||||||
#endif
|
#endif
|
||||||
, m_ses(ses)
|
, m_ses(ses)
|
||||||
, m_picker(0)
|
, m_picker(new piece_picker())
|
||||||
, m_trackers(m_torrent_file->trackers())
|
, m_trackers(m_torrent_file->trackers())
|
||||||
, m_total_failed_bytes(0)
|
, m_total_failed_bytes(0)
|
||||||
, m_total_redundant_bytes(0)
|
, m_total_redundant_bytes(0)
|
||||||
|
@ -175,7 +175,6 @@ namespace libtorrent
|
||||||
, m_settings(ses.settings())
|
, m_settings(ses.settings())
|
||||||
, m_storage_constructor(sc)
|
, m_storage_constructor(sc)
|
||||||
, m_progress(0.f)
|
, m_progress(0.f)
|
||||||
, m_num_pieces(0)
|
|
||||||
, m_ratio(0.f)
|
, m_ratio(0.f)
|
||||||
, m_max_uploads((std::numeric_limits<int>::max)())
|
, m_max_uploads((std::numeric_limits<int>::max)())
|
||||||
, m_num_uploads(0)
|
, m_num_uploads(0)
|
||||||
|
@ -201,11 +200,10 @@ namespace libtorrent
|
||||||
, m_sequential_download(false)
|
, m_sequential_download(false)
|
||||||
, m_got_tracker_response(false)
|
, m_got_tracker_response(false)
|
||||||
, m_connections_initialized(true)
|
, m_connections_initialized(true)
|
||||||
|
, m_has_incoming(false)
|
||||||
|
, m_files_checked(false)
|
||||||
{
|
{
|
||||||
if (resume_data) m_resume_data = *resume_data;
|
if (resume_data) m_resume_data = *resume_data;
|
||||||
#ifndef NDEBUG
|
|
||||||
m_files_checked = false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
torrent::torrent(
|
torrent::torrent(
|
||||||
|
@ -239,7 +237,7 @@ namespace libtorrent
|
||||||
, m_last_dht_announce(time_now() - minutes(15))
|
, m_last_dht_announce(time_now() - minutes(15))
|
||||||
#endif
|
#endif
|
||||||
, m_ses(ses)
|
, m_ses(ses)
|
||||||
, m_picker(0)
|
, m_picker(new piece_picker())
|
||||||
, m_total_failed_bytes(0)
|
, m_total_failed_bytes(0)
|
||||||
, m_total_redundant_bytes(0)
|
, m_total_redundant_bytes(0)
|
||||||
, m_net_interface(net_interface.address(), 0)
|
, m_net_interface(net_interface.address(), 0)
|
||||||
|
@ -249,7 +247,6 @@ namespace libtorrent
|
||||||
, m_settings(ses.settings())
|
, m_settings(ses.settings())
|
||||||
, m_storage_constructor(sc)
|
, m_storage_constructor(sc)
|
||||||
, m_progress(0.f)
|
, m_progress(0.f)
|
||||||
, m_num_pieces(0)
|
|
||||||
, m_ratio(0.f)
|
, m_ratio(0.f)
|
||||||
, m_max_uploads((std::numeric_limits<int>::max)())
|
, m_max_uploads((std::numeric_limits<int>::max)())
|
||||||
, m_num_uploads(0)
|
, m_num_uploads(0)
|
||||||
|
@ -275,6 +272,7 @@ namespace libtorrent
|
||||||
, m_sequential_download(false)
|
, m_sequential_download(false)
|
||||||
, m_got_tracker_response(false)
|
, m_got_tracker_response(false)
|
||||||
, m_connections_initialized(false)
|
, m_connections_initialized(false)
|
||||||
|
, m_has_incoming(false)
|
||||||
{
|
{
|
||||||
if (resume_data) m_resume_data = *resume_data;
|
if (resume_data) m_resume_data = *resume_data;
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -308,10 +306,10 @@ namespace libtorrent
|
||||||
if (m_ses.m_listen_sockets.empty()) return false;
|
if (m_ses.m_listen_sockets.empty()) return false;
|
||||||
|
|
||||||
if (!m_ses.m_dht) return false;
|
if (!m_ses.m_dht) return false;
|
||||||
|
if (!m_files_checked) return false;
|
||||||
|
|
||||||
// don't announce private torrents
|
// don't announce private torrents
|
||||||
if (m_torrent_file->is_valid() && m_torrent_file->priv()) return false;
|
if (m_torrent_file->is_valid() && m_torrent_file->priv()) return false;
|
||||||
|
|
||||||
if (m_trackers.empty()) return true;
|
if (m_trackers.empty()) return true;
|
||||||
|
|
||||||
return m_failed_trackers > 0 || !m_ses.settings().use_dht_as_fallback;
|
return m_failed_trackers > 0 || !m_ses.settings().use_dht_as_fallback;
|
||||||
|
@ -407,16 +405,14 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(m_torrent_file->num_files() > 0);
|
TORRENT_ASSERT(m_torrent_file->num_files() > 0);
|
||||||
TORRENT_ASSERT(m_torrent_file->total_size() >= 0);
|
TORRENT_ASSERT(m_torrent_file->total_size() >= 0);
|
||||||
|
|
||||||
m_have_pieces.resize(m_torrent_file->num_pieces(), false);
|
|
||||||
// the shared_from_this() will create an intentional
|
// the shared_from_this() will create an intentional
|
||||||
// cycle of ownership, se the hpp file for description.
|
// cycle of ownership, se the hpp file for description.
|
||||||
m_owning_storage = new piece_manager(shared_from_this(), m_torrent_file
|
m_owning_storage = new piece_manager(shared_from_this(), m_torrent_file
|
||||||
, m_save_path, m_ses.m_files, m_ses.m_disk_thread, m_storage_constructor
|
, m_save_path, m_ses.m_files, m_ses.m_disk_thread, m_storage_constructor
|
||||||
, m_storage_mode);
|
, m_storage_mode);
|
||||||
m_storage = m_owning_storage.get();
|
m_storage = m_owning_storage.get();
|
||||||
m_picker.reset(new piece_picker(
|
m_picker->init(m_torrent_file->piece_length() / m_block_size
|
||||||
m_torrent_file->piece_length() / m_block_size
|
, int((m_torrent_file->total_size()+m_block_size-1)/m_block_size));
|
||||||
, int((m_torrent_file->total_size()+m_block_size-1)/m_block_size)));
|
|
||||||
|
|
||||||
std::vector<std::string> const& url_seeds = m_torrent_file->url_seeds();
|
std::vector<std::string> const& url_seeds = m_torrent_file->url_seeds();
|
||||||
std::copy(url_seeds.begin(), url_seeds.end(), std::inserter(m_web_seeds
|
std::copy(url_seeds.begin(), url_seeds.end(), std::inserter(m_web_seeds
|
||||||
|
@ -473,8 +469,6 @@ namespace libtorrent
|
||||||
" ]\n";
|
" ]\n";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
m_have_pieces.clear_all();
|
|
||||||
m_num_pieces = 0;
|
|
||||||
m_error = j.str;
|
m_error = j.str;
|
||||||
pause();
|
pause();
|
||||||
return;
|
return;
|
||||||
|
@ -548,8 +542,6 @@ namespace libtorrent
|
||||||
// there are either no files for this torrent
|
// there are either no files for this torrent
|
||||||
// or the resume_data was accepted
|
// or the resume_data was accepted
|
||||||
|
|
||||||
m_num_pieces = 0;
|
|
||||||
m_have_pieces.clear_all();
|
|
||||||
if (!fastresume_rejected)
|
if (!fastresume_rejected)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(m_resume_data.type() == entry::dictionary_t);
|
TORRENT_ASSERT(m_resume_data.type() == entry::dictionary_t);
|
||||||
|
@ -563,8 +555,7 @@ namespace libtorrent
|
||||||
for (int i = 0, end(pieces_str.size()); i < end; ++i)
|
for (int i = 0, end(pieces_str.size()); i < end; ++i)
|
||||||
{
|
{
|
||||||
if ((pieces_str[i] & 1) == 0) continue;
|
if ((pieces_str[i] & 1) == 0) continue;
|
||||||
m_have_pieces.set_bit(i);
|
m_picker->we_have(i);
|
||||||
++m_num_pieces;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -587,11 +578,8 @@ namespace libtorrent
|
||||||
if (piece_index < 0 || piece_index >= torrent_file().num_pieces())
|
if (piece_index < 0 || piece_index >= torrent_file().num_pieces())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (m_have_pieces[piece_index])
|
if (m_picker->have_piece(piece_index))
|
||||||
{
|
m_picker->we_dont_have(piece_index);
|
||||||
m_have_pieces.clear_bit(piece_index);
|
|
||||||
--m_num_pieces;
|
|
||||||
}
|
|
||||||
|
|
||||||
entry const* bitmask_ent = i->find_key("bitmask");
|
entry const* bitmask_ent = i->find_key("bitmask");
|
||||||
if (bitmask_ent == 0 || bitmask_ent->type() != entry::string_t) break;
|
if (bitmask_ent == 0 || bitmask_ent->type() != entry::string_t) break;
|
||||||
|
@ -617,13 +605,6 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
for (bitfield::const_iterator i = m_have_pieces.begin()
|
|
||||||
, end(m_have_pieces.end()); i != end; ++i, ++index)
|
|
||||||
{
|
|
||||||
if (*i) m_picker->we_have(index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
files_checked();
|
files_checked();
|
||||||
|
@ -636,6 +617,51 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void torrent::force_recheck()
|
||||||
|
{
|
||||||
|
disconnect_all();
|
||||||
|
|
||||||
|
m_owning_storage->async_release_files();
|
||||||
|
m_owning_storage = new piece_manager(shared_from_this(), m_torrent_file
|
||||||
|
, m_save_path, m_ses.m_files, m_ses.m_disk_thread, m_storage_constructor
|
||||||
|
, m_storage_mode);
|
||||||
|
m_storage = m_owning_storage.get();
|
||||||
|
m_picker.reset(new piece_picker);
|
||||||
|
m_picker->init(m_torrent_file->piece_length() / m_block_size
|
||||||
|
, int((m_torrent_file->total_size()+m_block_size-1)/m_block_size));
|
||||||
|
// assume that we don't have anything
|
||||||
|
m_files_checked = false;
|
||||||
|
m_state = torrent_status::queued_for_checking;
|
||||||
|
|
||||||
|
m_resume_data = entry();
|
||||||
|
m_storage->async_check_fastresume(&m_resume_data
|
||||||
|
, bind(&torrent::on_force_recheck
|
||||||
|
, shared_from_this(), _1, _2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void torrent::on_force_recheck(int ret, disk_io_job const& j)
|
||||||
|
{
|
||||||
|
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||||
|
|
||||||
|
if (ret == piece_manager::fatal_disk_error)
|
||||||
|
{
|
||||||
|
if (m_ses.m_alerts.should_post(alert::fatal))
|
||||||
|
{
|
||||||
|
m_ses.m_alerts.post_alert(file_error_alert(j.error_file, get_handle(), j.str));
|
||||||
|
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
|
||||||
|
(*m_ses.m_logger) << time_now_string() << ": fatal disk error ["
|
||||||
|
" error: " << j.str <<
|
||||||
|
" torrent: " << torrent_file().name() <<
|
||||||
|
" ]\n";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
m_error = j.str;
|
||||||
|
pause();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_ses.check_torrent(shared_from_this());
|
||||||
|
}
|
||||||
|
|
||||||
void torrent::start_checking()
|
void torrent::start_checking()
|
||||||
{
|
{
|
||||||
m_state = torrent_status::checking_files;
|
m_state = torrent_status::checking_files;
|
||||||
|
@ -661,8 +687,6 @@ namespace libtorrent
|
||||||
" ]\n";
|
" ]\n";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
m_have_pieces.clear_all();
|
|
||||||
m_num_pieces = 0;
|
|
||||||
m_error = j.str;
|
m_error = j.str;
|
||||||
pause();
|
pause();
|
||||||
m_ses.done_checking(shared_from_this());
|
m_ses.done_checking(shared_from_this());
|
||||||
|
@ -671,13 +695,9 @@ namespace libtorrent
|
||||||
|
|
||||||
m_progress = j.piece / float(torrent_file().num_pieces());
|
m_progress = j.piece / float(torrent_file().num_pieces());
|
||||||
|
|
||||||
if (j.offset >= 0 && !m_have_pieces[j.offset])
|
TORRENT_ASSERT(m_picker);
|
||||||
{
|
if (j.offset >= 0 && !m_picker->have_piece(j.offset))
|
||||||
m_have_pieces.set_bit(j.offset);
|
|
||||||
++m_num_pieces;
|
|
||||||
TORRENT_ASSERT(m_picker);
|
|
||||||
m_picker->we_have(j.offset);
|
m_picker->we_have(j.offset);
|
||||||
}
|
|
||||||
|
|
||||||
// we're not done checking yet
|
// we're not done checking yet
|
||||||
// this handler will be called repeatedly until
|
// this handler will be called repeatedly until
|
||||||
|
@ -793,6 +813,7 @@ namespace libtorrent
|
||||||
// INVARIANT_CHECK;
|
// INVARIANT_CHECK;
|
||||||
|
|
||||||
if (m_trackers.empty()) return false;
|
if (m_trackers.empty()) return false;
|
||||||
|
if (!m_files_checked) return false;
|
||||||
|
|
||||||
if (m_just_paused)
|
if (m_just_paused)
|
||||||
{
|
{
|
||||||
|
@ -982,12 +1003,12 @@ namespace libtorrent
|
||||||
const int last_piece = m_torrent_file->num_pieces() - 1;
|
const int last_piece = m_torrent_file->num_pieces() - 1;
|
||||||
|
|
||||||
size_type total_done
|
size_type total_done
|
||||||
= size_type(m_num_pieces) * m_torrent_file->piece_length();
|
= size_type(num_have()) * m_torrent_file->piece_length();
|
||||||
|
|
||||||
// if we have the last piece, we have to correct
|
// if we have the last piece, we have to correct
|
||||||
// the amount we have, since the first calculation
|
// the amount we have, since the first calculation
|
||||||
// assumed all pieces were of equal size
|
// assumed all pieces were of equal size
|
||||||
if (m_have_pieces[last_piece])
|
if (m_picker->have_piece(last_piece))
|
||||||
{
|
{
|
||||||
int corr = m_torrent_file->piece_size(last_piece)
|
int corr = m_torrent_file->piece_size(last_piece)
|
||||||
- m_torrent_file->piece_length();
|
- m_torrent_file->piece_length();
|
||||||
|
@ -1013,19 +1034,19 @@ namespace libtorrent
|
||||||
return make_tuple(m_torrent_file->total_size()
|
return make_tuple(m_torrent_file->total_size()
|
||||||
, m_torrent_file->total_size());
|
, m_torrent_file->total_size());
|
||||||
|
|
||||||
TORRENT_ASSERT(m_num_pieces >= m_picker->num_have_filtered());
|
TORRENT_ASSERT(num_have() >= m_picker->num_have_filtered());
|
||||||
size_type wanted_done = size_type(m_num_pieces - m_picker->num_have_filtered())
|
size_type wanted_done = size_type(num_have() - m_picker->num_have_filtered())
|
||||||
* piece_size;
|
* piece_size;
|
||||||
TORRENT_ASSERT(wanted_done >= 0);
|
TORRENT_ASSERT(wanted_done >= 0);
|
||||||
|
|
||||||
size_type total_done
|
size_type total_done
|
||||||
= size_type(m_num_pieces) * piece_size;
|
= size_type(num_have()) * piece_size;
|
||||||
TORRENT_ASSERT(m_num_pieces < m_torrent_file->num_pieces());
|
TORRENT_ASSERT(num_have() < m_torrent_file->num_pieces());
|
||||||
|
|
||||||
// if we have the last piece, we have to correct
|
// if we have the last piece, we have to correct
|
||||||
// the amount we have, since the first calculation
|
// the amount we have, since the first calculation
|
||||||
// assumed all pieces were of equal size
|
// assumed all pieces were of equal size
|
||||||
if (m_have_pieces[last_piece])
|
if (m_picker->have_piece(last_piece))
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(total_done >= piece_size);
|
TORRENT_ASSERT(total_done >= piece_size);
|
||||||
int corr = m_torrent_file->piece_size(last_piece)
|
int corr = m_torrent_file->piece_size(last_piece)
|
||||||
|
@ -1054,7 +1075,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
int corr = 0;
|
int corr = 0;
|
||||||
int index = i->index;
|
int index = i->index;
|
||||||
if (m_have_pieces[index]) continue;
|
if (m_picker->have_piece(index)) continue;
|
||||||
TORRENT_ASSERT(i->finished <= m_picker->blocks_in_piece(index));
|
TORRENT_ASSERT(i->finished <= m_picker->blocks_in_piece(index));
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -1099,7 +1120,7 @@ namespace libtorrent
|
||||||
= pc->downloading_piece_progress();
|
= pc->downloading_piece_progress();
|
||||||
if (p)
|
if (p)
|
||||||
{
|
{
|
||||||
if (m_have_pieces[p->piece_index])
|
if (m_picker->have_piece(p->piece_index))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
piece_block block(p->piece_index, p->block_index);
|
piece_block block(p->piece_index, p->block_index);
|
||||||
|
@ -1136,16 +1157,16 @@ namespace libtorrent
|
||||||
wanted_done += i->second;
|
wanted_done += i->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TORRENT_ASSERT(total_done <= m_torrent_file->total_size());
|
||||||
|
TORRENT_ASSERT(wanted_done <= m_torrent_file->total_size());
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
|
||||||
if (total_done >= m_torrent_file->total_size())
|
if (total_done >= m_torrent_file->total_size())
|
||||||
{
|
{
|
||||||
// Thist happens when a piece has been downloaded completely
|
// Thist happens when a piece has been downloaded completely
|
||||||
// but not yet verified against the hash
|
// but not yet verified against the hash
|
||||||
std::copy(m_have_pieces.begin(), m_have_pieces.end()
|
std::cerr << "num_have: " << num_have() << std::endl;
|
||||||
, std::ostream_iterator<bool>(std::cerr, " "));
|
|
||||||
std::cerr << std::endl;
|
|
||||||
std::cerr << "num_pieces: " << m_num_pieces << std::endl;
|
|
||||||
|
|
||||||
std::cerr << "unfinished:" << std::endl;
|
std::cerr << "unfinished:" << std::endl;
|
||||||
|
|
||||||
|
@ -1195,7 +1216,7 @@ namespace libtorrent
|
||||||
?"disk failed":"failed") << " ]\n";
|
?"disk failed":"failed") << " ]\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool was_finished = m_picker->num_filtered() + num_pieces()
|
bool was_finished = m_picker->num_filtered() + num_have()
|
||||||
== torrent_file().num_pieces();
|
== torrent_file().num_pieces();
|
||||||
|
|
||||||
if (passed_hash_check == 0)
|
if (passed_hash_check == 0)
|
||||||
|
@ -1226,7 +1247,7 @@ namespace libtorrent
|
||||||
|
|
||||||
if (!was_finished
|
if (!was_finished
|
||||||
&& (is_seed()
|
&& (is_seed()
|
||||||
|| m_picker->num_filtered() + num_pieces()
|
|| m_picker->num_filtered() + num_have()
|
||||||
== torrent_file().num_pieces()))
|
== torrent_file().num_pieces()))
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(passed_hash_check == 0);
|
TORRENT_ASSERT(passed_hash_check == 0);
|
||||||
|
@ -1350,7 +1371,7 @@ namespace libtorrent
|
||||||
m_picker->restore_piece(index);
|
m_picker->restore_piece(index);
|
||||||
TORRENT_ASSERT(m_storage);
|
TORRENT_ASSERT(m_storage);
|
||||||
|
|
||||||
TORRENT_ASSERT(m_have_pieces[index] == false);
|
TORRENT_ASSERT(m_picker->have_piece(index) == false);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
for (std::vector<void*>::iterator i = downloaders.begin()
|
for (std::vector<void*>::iterator i = downloaders.begin()
|
||||||
|
@ -1486,13 +1507,6 @@ namespace libtorrent
|
||||||
std::set<void*> peers;
|
std::set<void*> peers;
|
||||||
std::copy(downloaders.begin(), downloaders.end(), std::inserter(peers, peers.begin()));
|
std::copy(downloaders.begin(), downloaders.end(), std::inserter(peers, peers.begin()));
|
||||||
|
|
||||||
if (!m_have_pieces[index])
|
|
||||||
m_num_pieces++;
|
|
||||||
m_have_pieces.set_bit(index);
|
|
||||||
|
|
||||||
TORRENT_ASSERT(std::accumulate(m_have_pieces.begin(), m_have_pieces.end(), 0)
|
|
||||||
== m_num_pieces);
|
|
||||||
|
|
||||||
m_picker->we_have(index);
|
m_picker->we_have(index);
|
||||||
for (peer_iterator i = m_connections.begin(); i != m_connections.end(); ++i)
|
for (peer_iterator i = m_connections.begin(); i != m_connections.end(); ++i)
|
||||||
(*i)->announce_piece(index);
|
(*i)->announce_piece(index);
|
||||||
|
@ -1558,7 +1572,7 @@ namespace libtorrent
|
||||||
|
|
||||||
bool was_finished = is_finished();
|
bool was_finished = is_finished();
|
||||||
bool filter_updated = m_picker->set_piece_priority(index, priority);
|
bool filter_updated = m_picker->set_piece_priority(index, priority);
|
||||||
TORRENT_ASSERT(m_num_pieces >= m_picker->num_have_filtered());
|
TORRENT_ASSERT(num_have() >= m_picker->num_have_filtered());
|
||||||
if (filter_updated) update_peer_interest(was_finished);
|
if (filter_updated) update_peer_interest(was_finished);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1596,7 +1610,7 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(*i >= 0);
|
TORRENT_ASSERT(*i >= 0);
|
||||||
TORRENT_ASSERT(*i <= 7);
|
TORRENT_ASSERT(*i <= 7);
|
||||||
filter_updated |= m_picker->set_piece_priority(index, *i);
|
filter_updated |= m_picker->set_piece_priority(index, *i);
|
||||||
TORRENT_ASSERT(m_num_pieces >= m_picker->num_have_filtered());
|
TORRENT_ASSERT(num_have() >= m_picker->num_have_filtered());
|
||||||
}
|
}
|
||||||
if (filter_updated) update_peer_interest(was_finished);
|
if (filter_updated) update_peer_interest(was_finished);
|
||||||
}
|
}
|
||||||
|
@ -2442,8 +2456,16 @@ namespace libtorrent
|
||||||
// write have bitmask
|
// write have bitmask
|
||||||
entry::string_type& pieces = ret["pieces"].string();
|
entry::string_type& pieces = ret["pieces"].string();
|
||||||
pieces.resize(m_torrent_file->num_pieces());
|
pieces.resize(m_torrent_file->num_pieces());
|
||||||
for (int i = 0, end(pieces.size()); i < end; ++i)
|
if (is_seed())
|
||||||
pieces[i] = m_have_pieces[i] ? 1 : 0;
|
{
|
||||||
|
for (int i = 0, end(pieces.size()); i < end; ++i)
|
||||||
|
pieces[i] = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0, end(pieces.size()); i < end; ++i)
|
||||||
|
pieces[i] = m_picker->have_piece(i) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
// write local peers
|
// write local peers
|
||||||
|
|
||||||
|
@ -2714,6 +2736,8 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(p != 0);
|
TORRENT_ASSERT(p != 0);
|
||||||
TORRENT_ASSERT(!p->is_local());
|
TORRENT_ASSERT(!p->is_local());
|
||||||
|
|
||||||
|
m_has_incoming = true;
|
||||||
|
|
||||||
if ((m_state == torrent_status::queued_for_checking
|
if ((m_state == torrent_status::queued_for_checking
|
||||||
|| m_state == torrent_status::checking_files)
|
|| m_state == torrent_status::checking_files)
|
||||||
&& valid_metadata())
|
&& valid_metadata())
|
||||||
|
@ -3115,7 +3139,6 @@ namespace libtorrent
|
||||||
|
|
||||||
if (!is_seed())
|
if (!is_seed())
|
||||||
{
|
{
|
||||||
m_picker->init(m_have_pieces);
|
|
||||||
if (m_sequential_download)
|
if (m_sequential_download)
|
||||||
picker().sequential_download(m_sequential_download);
|
picker().sequential_download(m_sequential_download);
|
||||||
}
|
}
|
||||||
|
@ -3169,9 +3192,7 @@ namespace libtorrent
|
||||||
, "torrent finished checking"));
|
, "torrent finished checking"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
m_files_checked = true;
|
m_files_checked = true;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
alert_manager& torrent::alerts() const
|
alert_manager& torrent::alerts() const
|
||||||
|
@ -3289,16 +3310,16 @@ namespace libtorrent
|
||||||
if (!m_picker->is_downloaded(i->first))
|
if (!m_picker->is_downloaded(i->first))
|
||||||
TORRENT_ASSERT(m_picker->num_peers(i->first) == i->second);
|
TORRENT_ASSERT(m_picker->num_peers(i->first) == i->second);
|
||||||
}
|
}
|
||||||
TORRENT_ASSERT(m_num_pieces >= m_picker->num_have_filtered());
|
TORRENT_ASSERT(num_have() >= m_picker->num_have_filtered());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid_metadata())
|
if (valid_metadata())
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(m_abort || int(m_have_pieces.size()) == m_torrent_file->num_pieces());
|
TORRENT_ASSERT(m_abort || !m_picker || m_picker->num_pieces() == m_torrent_file->num_pieces());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(m_abort || m_have_pieces.empty());
|
TORRENT_ASSERT(m_abort || m_picker->num_pieces() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (policy::const_iterator i = m_policy.begin_peer()
|
for (policy::const_iterator i = m_policy.begin_peer()
|
||||||
|
@ -3313,7 +3334,7 @@ namespace libtorrent
|
||||||
if (is_seed())
|
if (is_seed())
|
||||||
TORRENT_ASSERT(total_done == m_torrent_file->total_size());
|
TORRENT_ASSERT(total_done == m_torrent_file->total_size());
|
||||||
else
|
else
|
||||||
TORRENT_ASSERT(total_done != m_torrent_file->total_size());
|
TORRENT_ASSERT(total_done != m_torrent_file->total_size() || !m_files_checked);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3344,8 +3365,6 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
// This check is very expensive.
|
// This check is very expensive.
|
||||||
TORRENT_ASSERT(m_num_pieces
|
|
||||||
== std::count(m_have_pieces.begin(), m_have_pieces.end(), true));
|
|
||||||
TORRENT_ASSERT(!valid_metadata() || m_block_size > 0);
|
TORRENT_ASSERT(!valid_metadata() || m_block_size > 0);
|
||||||
TORRENT_ASSERT(!valid_metadata() || (m_torrent_file->piece_length() % m_block_size) == 0);
|
TORRENT_ASSERT(!valid_metadata() || (m_torrent_file->piece_length() % m_block_size) == 0);
|
||||||
// if (is_seed()) TORRENT_ASSERT(m_picker.get() == 0);
|
// if (is_seed()) TORRENT_ASSERT(m_picker.get() == 0);
|
||||||
|
@ -3412,6 +3431,9 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
m_sequence_number = (std::min)(max_seq + 1, p);
|
m_sequence_number = (std::min)(max_seq + 1, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_ses.m_auto_manage_time_scaler > 2)
|
||||||
|
m_ses.m_auto_manage_time_scaler = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::set_max_uploads(int limit)
|
void torrent::set_max_uploads(int limit)
|
||||||
|
@ -3814,7 +3836,7 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(m_storage->refcount() > 0);
|
TORRENT_ASSERT(m_storage->refcount() > 0);
|
||||||
TORRENT_ASSERT(piece_index >= 0);
|
TORRENT_ASSERT(piece_index >= 0);
|
||||||
TORRENT_ASSERT(piece_index < m_torrent_file->num_pieces());
|
TORRENT_ASSERT(piece_index < m_torrent_file->num_pieces());
|
||||||
TORRENT_ASSERT(piece_index < (int)m_have_pieces.size());
|
TORRENT_ASSERT(piece_index < (int)m_picker->num_pieces());
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
if (m_picker)
|
if (m_picker)
|
||||||
{
|
{
|
||||||
|
@ -3865,6 +3887,12 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(valid_metadata());
|
TORRENT_ASSERT(valid_metadata());
|
||||||
|
|
||||||
fp.clear();
|
fp.clear();
|
||||||
|
if (is_seed())
|
||||||
|
{
|
||||||
|
fp.resize(m_torrent_file->num_files(), 1.f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fp.resize(m_torrent_file->num_files(), 0.f);
|
fp.resize(m_torrent_file->num_files(), 0.f);
|
||||||
|
|
||||||
for (int i = 0; i < m_torrent_file->num_files(); ++i)
|
for (int i = 0; i < m_torrent_file->num_files(); ++i)
|
||||||
|
@ -3885,7 +3913,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
size_type bytes_step = (std::min)(size_type(m_torrent_file->piece_size(ret.piece)
|
size_type bytes_step = (std::min)(size_type(m_torrent_file->piece_size(ret.piece)
|
||||||
- ret.start), size);
|
- ret.start), size);
|
||||||
if (m_have_pieces[ret.piece]) done += bytes_step;
|
if (m_picker->have_piece(ret.piece)) done += bytes_step;
|
||||||
++ret.piece;
|
++ret.piece;
|
||||||
ret.start = 0;
|
ret.start = 0;
|
||||||
size -= bytes_step;
|
size -= bytes_step;
|
||||||
|
@ -3900,15 +3928,11 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
TORRENT_ASSERT(std::accumulate(
|
|
||||||
m_have_pieces.begin()
|
|
||||||
, m_have_pieces.end()
|
|
||||||
, 0) == m_num_pieces);
|
|
||||||
|
|
||||||
ptime now = time_now();
|
ptime now = time_now();
|
||||||
|
|
||||||
torrent_status st;
|
torrent_status st;
|
||||||
|
|
||||||
|
st.has_incoming = m_has_incoming;
|
||||||
st.error = m_error;
|
st.error = m_error;
|
||||||
|
|
||||||
if (m_last_scrape == min_time())
|
if (m_last_scrape == min_time())
|
||||||
|
@ -4030,8 +4054,14 @@ namespace libtorrent
|
||||||
else st.progress = st.total_wanted_done
|
else st.progress = st.total_wanted_done
|
||||||
/ static_cast<float>(st.total_wanted);
|
/ static_cast<float>(st.total_wanted);
|
||||||
|
|
||||||
st.pieces = &m_have_pieces;
|
if (has_picker())
|
||||||
st.num_pieces = m_num_pieces;
|
{
|
||||||
|
int num_pieces = m_picker->num_pieces();
|
||||||
|
st.pieces.resize(num_pieces, false);
|
||||||
|
for (int i = 0; i < num_pieces; ++i)
|
||||||
|
if (m_picker->have_piece(i)) st.pieces.set_bit(i);
|
||||||
|
}
|
||||||
|
st.num_pieces = num_have();
|
||||||
st.num_seeds = num_seeds();
|
st.num_seeds = num_seeds();
|
||||||
if (m_picker.get())
|
if (m_picker.get())
|
||||||
st.distributed_copies = m_picker->distributed_copies();
|
st.distributed_copies = m_picker->distributed_copies();
|
||||||
|
|
|
@ -265,6 +265,12 @@ namespace libtorrent
|
||||||
TORRENT_FORWARD(save_resume_data());
|
TORRENT_FORWARD(save_resume_data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void torrent_handle::force_recheck() const
|
||||||
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
TORRENT_FORWARD(force_recheck());
|
||||||
|
}
|
||||||
|
|
||||||
void torrent_handle::resume() const
|
void torrent_handle::resume() const
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
|
@ -67,6 +67,7 @@ namespace libtorrent
|
||||||
: peer_connection(ses, t, s, remote, peerinfo)
|
: peer_connection(ses, t, s, remote, peerinfo)
|
||||||
, m_url(url)
|
, m_url(url)
|
||||||
, m_first_request(true)
|
, m_first_request(true)
|
||||||
|
, m_range_pos(0)
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
|
@ -350,7 +351,8 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
bool error = false;
|
bool error = false;
|
||||||
boost::tie(payload, protocol) = m_parser.incoming(recv_buffer, error);
|
boost::tie(payload, protocol) = m_parser.incoming(recv_buffer, error);
|
||||||
m_statistics.received_bytes(payload, protocol);
|
m_statistics.received_bytes(0, protocol);
|
||||||
|
bytes_transferred -= protocol;
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
|
@ -363,7 +365,12 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(recv_buffer.left() <= packet_size());
|
TORRENT_ASSERT(recv_buffer.left() <= packet_size());
|
||||||
|
|
||||||
// this means the entire status line hasn't been received yet
|
// this means the entire status line hasn't been received yet
|
||||||
if (m_parser.status_code() == -1) break;
|
if (m_parser.status_code() == -1)
|
||||||
|
{
|
||||||
|
TORRENT_ASSERT(payload == 0);
|
||||||
|
TORRENT_ASSERT(bytes_transferred == 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// if the status code is not one of the accepted ones, abort
|
// if the status code is not one of the accepted ones, abort
|
||||||
if (m_parser.status_code() != 206 // partial content
|
if (m_parser.status_code() != 206 // partial content
|
||||||
|
@ -388,15 +395,16 @@ namespace libtorrent
|
||||||
disconnect(error_msg.c_str(), 1);
|
disconnect(error_msg.c_str(), 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!m_parser.header_finished()) break;
|
if (!m_parser.header_finished())
|
||||||
|
{
|
||||||
|
TORRENT_ASSERT(payload == 0);
|
||||||
|
TORRENT_ASSERT(bytes_transferred == 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
m_body_start = m_parser.body_start();
|
m_body_start = m_parser.body_start();
|
||||||
m_received_body = 0;
|
m_received_body = 0;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
m_statistics.received_bytes(bytes_transferred, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// we just completed reading the header
|
// we just completed reading the header
|
||||||
if (!header_finished)
|
if (!header_finished)
|
||||||
|
@ -460,9 +468,11 @@ namespace libtorrent
|
||||||
|
|
||||||
m_body_start = m_parser.body_start();
|
m_body_start = m_parser.body_start();
|
||||||
m_received_body = 0;
|
m_received_body = 0;
|
||||||
|
m_range_pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
recv_buffer.begin += m_body_start;
|
recv_buffer.begin += m_body_start;
|
||||||
|
|
||||||
// we only received the header, no data
|
// we only received the header, no data
|
||||||
if (recv_buffer.left() == 0) break;
|
if (recv_buffer.left() == 0) break;
|
||||||
|
|
||||||
|
@ -499,6 +509,13 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int left_in_response = range_end - range_start - m_range_pos;
|
||||||
|
int payload_transferred = (std::min)(left_in_response, int(bytes_transferred));
|
||||||
|
m_statistics.received_bytes(payload_transferred, 0);
|
||||||
|
bytes_transferred -= payload_transferred;
|
||||||
|
m_range_pos += payload_transferred;;
|
||||||
|
if (m_range_pos > range_end - range_start) m_range_pos = range_end - range_start;
|
||||||
|
|
||||||
// std::cerr << "REQUESTS: m_requests: " << m_requests.size()
|
// std::cerr << "REQUESTS: m_requests: " << m_requests.size()
|
||||||
// << " file_requests: " << m_file_requests.size() << std::endl;
|
// << " file_requests: " << m_file_requests.size() << std::endl;
|
||||||
|
|
||||||
|
@ -641,8 +658,9 @@ namespace libtorrent
|
||||||
m_received_body = 0;
|
m_received_body = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
if (bytes_transferred == 0) break;
|
||||||
}
|
}
|
||||||
|
TORRENT_ASSERT(bytes_transferred == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void web_peer_connection::get_specific_peer_info(peer_info& p) const
|
void web_peer_connection::get_specific_peer_info(peer_info& p) const
|
||||||
|
|
Loading…
Reference in New Issue