mirror of
https://github.com/codex-storage/deluge.git
synced 2025-02-19 14:54:21 +00:00
lt sync 2537
This commit is contained in:
parent
bfe4cb0f71
commit
4f50438b61
@ -74,7 +74,7 @@ namespace
|
|||||||
|
|
||||||
list file_progress(torrent_handle& handle)
|
list file_progress(torrent_handle& handle)
|
||||||
{
|
{
|
||||||
std::vector<float> p;
|
std::vector<size_type> p;
|
||||||
|
|
||||||
{
|
{
|
||||||
allow_threading_guard guard;
|
allow_threading_guard guard;
|
||||||
@ -84,7 +84,7 @@ list file_progress(torrent_handle& handle)
|
|||||||
|
|
||||||
list result;
|
list result;
|
||||||
|
|
||||||
for (std::vector<float>::iterator i(p.begin()), e(p.end()); i != e; ++i)
|
for (std::vector<size_type>::iterator i(p.begin()), e(p.end()); i != e; ++i)
|
||||||
result.append(*i);
|
result.append(*i);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -267,6 +267,7 @@ void bind_torrent_handle()
|
|||||||
.def("is_paused", _(&torrent_handle::is_paused))
|
.def("is_paused", _(&torrent_handle::is_paused))
|
||||||
.def("pause", _(&torrent_handle::pause))
|
.def("pause", _(&torrent_handle::pause))
|
||||||
.def("resume", _(&torrent_handle::resume))
|
.def("resume", _(&torrent_handle::resume))
|
||||||
|
.def("clear_error", _(&torrent_handle::clear_error))
|
||||||
|
|
||||||
.def("is_auto_managed", _(&torrent_handle::is_auto_managed))
|
.def("is_auto_managed", _(&torrent_handle::is_auto_managed))
|
||||||
.def("auto_managed", _(&torrent_handle::auto_managed))
|
.def("auto_managed", _(&torrent_handle::auto_managed))
|
||||||
|
@ -85,7 +85,7 @@ namespace libtorrent
|
|||||||
, std::string const& url_)
|
, std::string const& url_)
|
||||||
: torrent_alert(h)
|
: torrent_alert(h)
|
||||||
, url(url_)
|
, url(url_)
|
||||||
{ assert(!url.empty()); }
|
{}
|
||||||
|
|
||||||
const static int static_category = alert::tracker_notification;
|
const static int static_category = alert::tracker_notification;
|
||||||
virtual int category() const { return static_category; }
|
virtual int category() const { return static_category; }
|
||||||
@ -191,7 +191,7 @@ namespace libtorrent
|
|||||||
, times_in_row(times)
|
, times_in_row(times)
|
||||||
, status_code(status)
|
, status_code(status)
|
||||||
, msg(msg_)
|
, msg(msg_)
|
||||||
{}
|
{ TORRENT_ASSERT(!url.empty()); }
|
||||||
|
|
||||||
virtual std::auto_ptr<alert> clone() const
|
virtual std::auto_ptr<alert> clone() const
|
||||||
{ return std::auto_ptr<alert>(new tracker_error_alert(*this)); }
|
{ return std::auto_ptr<alert>(new tracker_error_alert(*this)); }
|
||||||
@ -218,7 +218,7 @@ namespace libtorrent
|
|||||||
, std::string const& msg_)
|
, std::string const& msg_)
|
||||||
: tracker_alert(h, url)
|
: tracker_alert(h, url)
|
||||||
, msg(msg_)
|
, msg(msg_)
|
||||||
{}
|
{ TORRENT_ASSERT(!url.empty()); }
|
||||||
|
|
||||||
std::string msg;
|
std::string msg;
|
||||||
|
|
||||||
@ -242,7 +242,7 @@ namespace libtorrent
|
|||||||
: tracker_alert(h, url)
|
: tracker_alert(h, url)
|
||||||
, incomplete(incomplete_)
|
, incomplete(incomplete_)
|
||||||
, complete(complete_)
|
, complete(complete_)
|
||||||
{}
|
{ TORRENT_ASSERT(!url.empty()); }
|
||||||
|
|
||||||
int incomplete;
|
int incomplete;
|
||||||
int complete;
|
int complete;
|
||||||
@ -265,7 +265,7 @@ namespace libtorrent
|
|||||||
, std::string const& msg_)
|
, std::string const& msg_)
|
||||||
: tracker_alert(h, url)
|
: tracker_alert(h, url)
|
||||||
, msg(msg_)
|
, msg(msg_)
|
||||||
{}
|
{ TORRENT_ASSERT(!url.empty()); }
|
||||||
|
|
||||||
std::string msg;
|
std::string msg;
|
||||||
|
|
||||||
@ -287,7 +287,7 @@ namespace libtorrent
|
|||||||
, std::string const& url)
|
, std::string const& url)
|
||||||
: tracker_alert(h, url)
|
: tracker_alert(h, url)
|
||||||
, num_peers(np)
|
, num_peers(np)
|
||||||
{}
|
{ TORRENT_ASSERT(!url.empty()); }
|
||||||
|
|
||||||
int num_peers;
|
int num_peers;
|
||||||
|
|
||||||
@ -324,16 +324,20 @@ namespace libtorrent
|
|||||||
struct TORRENT_EXPORT tracker_announce_alert: tracker_alert
|
struct TORRENT_EXPORT tracker_announce_alert: tracker_alert
|
||||||
{
|
{
|
||||||
tracker_announce_alert(torrent_handle const& h
|
tracker_announce_alert(torrent_handle const& h
|
||||||
, std::string const& url)
|
, std::string const& url, int event_)
|
||||||
: tracker_alert(h, url)
|
: tracker_alert(h, url)
|
||||||
{}
|
, event(event_)
|
||||||
|
{ TORRENT_ASSERT(!url.empty()); }
|
||||||
|
|
||||||
|
int event;
|
||||||
|
|
||||||
virtual std::auto_ptr<alert> clone() const
|
virtual std::auto_ptr<alert> clone() const
|
||||||
{ return std::auto_ptr<alert>(new tracker_announce_alert(*this)); }
|
{ return std::auto_ptr<alert>(new tracker_announce_alert(*this)); }
|
||||||
virtual char const* what() const { return "tracker announce sent"; }
|
virtual char const* what() const { return "tracker announce sent"; }
|
||||||
virtual std::string message() const
|
virtual std::string message() const
|
||||||
{
|
{
|
||||||
return tracker_alert::message() + " sending announce";
|
const static char* event_str[] = {"none", "completed", "started", "stopped"};
|
||||||
|
return tracker_alert::message() + " sending announce (" + event_str[event] + ")";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -319,6 +319,18 @@ namespace libtorrent
|
|||||||
|
|
||||||
int next_port();
|
int next_port();
|
||||||
|
|
||||||
|
void add_redundant_bytes(size_type b)
|
||||||
|
{
|
||||||
|
TORRENT_ASSERT(b > 0);
|
||||||
|
m_total_redundant_bytes += b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_failed_bytes(size_type b)
|
||||||
|
{
|
||||||
|
TORRENT_ASSERT(b > 0);
|
||||||
|
m_total_failed_bytes += b;
|
||||||
|
}
|
||||||
|
|
||||||
// handles delayed alerts
|
// handles delayed alerts
|
||||||
alert_manager m_alerts;
|
alert_manager m_alerts;
|
||||||
|
|
||||||
@ -608,6 +620,10 @@ namespace libtorrent
|
|||||||
std::map<int, int> m_as_peak;
|
std::map<int, int> m_as_peak;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// total redundant and failed bytes
|
||||||
|
size_type m_total_failed_bytes;
|
||||||
|
size_type m_total_redundant_bytes;
|
||||||
|
|
||||||
// the main working thread
|
// the main working thread
|
||||||
boost::scoped_ptr<boost::thread> m_thread;
|
boost::scoped_ptr<boost::thread> m_thread;
|
||||||
};
|
};
|
||||||
|
@ -58,6 +58,8 @@ namespace libtorrent
|
|||||||
int piece;
|
int piece;
|
||||||
std::vector<bool> blocks;
|
std::vector<bool> blocks;
|
||||||
ptime last_use;
|
ptime last_use;
|
||||||
|
enum kind_t { read_cache = 0, write_cache = 1 };
|
||||||
|
kind_t kind;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct disk_io_job
|
struct disk_io_job
|
||||||
|
@ -87,8 +87,8 @@ namespace libtorrent
|
|||||||
, tracker_receive_timeout(40)
|
, tracker_receive_timeout(40)
|
||||||
, stop_tracker_timeout(5)
|
, stop_tracker_timeout(5)
|
||||||
, tracker_maximum_response_length(1024*1024)
|
, tracker_maximum_response_length(1024*1024)
|
||||||
, piece_timeout(10)
|
, piece_timeout(20)
|
||||||
, request_timeout(40)
|
, request_timeout(50)
|
||||||
, request_queue_time(3.f)
|
, request_queue_time(3.f)
|
||||||
, max_allowed_in_request_queue(250)
|
, max_allowed_in_request_queue(250)
|
||||||
, max_out_request_queue(200)
|
, max_out_request_queue(200)
|
||||||
@ -121,6 +121,7 @@ namespace libtorrent
|
|||||||
, upnp_ignore_nonrouters(true)
|
, upnp_ignore_nonrouters(true)
|
||||||
, send_buffer_watermark(80 * 1024)
|
, send_buffer_watermark(80 * 1024)
|
||||||
, auto_upload_slots(true)
|
, auto_upload_slots(true)
|
||||||
|
, use_parole_mode(true)
|
||||||
, cache_size(512)
|
, cache_size(512)
|
||||||
, cache_expiry(60)
|
, cache_expiry(60)
|
||||||
, outgoing_ports(0,0)
|
, outgoing_ports(0,0)
|
||||||
@ -342,6 +343,13 @@ namespace libtorrent
|
|||||||
// the manual settings, through max_uploads.
|
// the manual settings, through max_uploads.
|
||||||
bool auto_upload_slots;
|
bool auto_upload_slots;
|
||||||
|
|
||||||
|
// if set to true, peers that participate in a failing
|
||||||
|
// piece is put in parole mode. i.e. They will only
|
||||||
|
// download whole pieces until they either fail or pass.
|
||||||
|
// they are taken out of parole mode as soon as they
|
||||||
|
// participate in a piece that passes.
|
||||||
|
bool use_parole_mode;
|
||||||
|
|
||||||
// the disk write cache, specified in 16 KiB blocks.
|
// the disk write cache, specified in 16 KiB blocks.
|
||||||
// default is 512 (= 8 MB)
|
// default is 512 (= 8 MB)
|
||||||
int cache_size;
|
int cache_size;
|
||||||
|
@ -53,6 +53,9 @@ namespace libtorrent
|
|||||||
size_type total_payload_download;
|
size_type total_payload_download;
|
||||||
size_type total_payload_upload;
|
size_type total_payload_upload;
|
||||||
|
|
||||||
|
size_type total_redundant_bytes;
|
||||||
|
size_type total_failed_bytes;
|
||||||
|
|
||||||
int num_peers;
|
int num_peers;
|
||||||
int num_unchoked;
|
int num_unchoked;
|
||||||
int allowed_upload_slots;
|
int allowed_upload_slots;
|
||||||
|
@ -156,6 +156,9 @@ namespace libtorrent
|
|||||||
void files_checked();
|
void files_checked();
|
||||||
void start_checking();
|
void start_checking();
|
||||||
|
|
||||||
|
void start_announcing();
|
||||||
|
void stop_announcing();
|
||||||
|
|
||||||
int seed_rank(session_settings const& s) const;
|
int seed_rank(session_settings const& s) const;
|
||||||
|
|
||||||
storage_mode_t storage_mode() const { return m_storage_mode; }
|
storage_mode_t storage_mode() const { return m_storage_mode; }
|
||||||
@ -169,6 +172,8 @@ namespace libtorrent
|
|||||||
torrent_status::state_t state() const { return m_state; }
|
torrent_status::state_t state() const { return m_state; }
|
||||||
void set_state(torrent_status::state_t s);
|
void set_state(torrent_status::state_t s);
|
||||||
|
|
||||||
|
void clear_error();
|
||||||
|
|
||||||
session_settings const& settings() const;
|
session_settings const& settings() const;
|
||||||
|
|
||||||
aux::session_impl& session() { return m_ses; }
|
aux::session_impl& session() { return m_ses; }
|
||||||
@ -219,6 +224,7 @@ namespace libtorrent
|
|||||||
bool is_piece_filtered(int index) const;
|
bool is_piece_filtered(int index) const;
|
||||||
void filtered_pieces(std::vector<bool>& bitmask) const;
|
void filtered_pieces(std::vector<bool>& bitmask) const;
|
||||||
void filter_files(std::vector<bool> const& files);
|
void filter_files(std::vector<bool> const& files);
|
||||||
|
void file_progress(std::vector<float>& fp) const;
|
||||||
// ============ end deprecation =============
|
// ============ end deprecation =============
|
||||||
|
|
||||||
void piece_availability(std::vector<int>& avail) const;
|
void piece_availability(std::vector<int>& avail) const;
|
||||||
@ -232,7 +238,8 @@ namespace libtorrent
|
|||||||
void prioritize_files(std::vector<int> const& files);
|
void prioritize_files(std::vector<int> const& files);
|
||||||
|
|
||||||
torrent_status status() const;
|
torrent_status status() const;
|
||||||
void file_progress(std::vector<float>& fp) const;
|
|
||||||
|
void file_progress(std::vector<size_type>& fp) const;
|
||||||
|
|
||||||
void use_interface(const char* net_interface);
|
void use_interface(const char* net_interface);
|
||||||
tcp::endpoint const& get_interface() const { return m_net_interface; }
|
tcp::endpoint const& get_interface() const { return m_net_interface; }
|
||||||
@ -354,10 +361,6 @@ namespace libtorrent
|
|||||||
virtual void tracker_scrape_response(tracker_request const& req
|
virtual void tracker_scrape_response(tracker_request const& req
|
||||||
, int complete, int incomplete, int downloaded);
|
, int complete, int incomplete, int downloaded);
|
||||||
|
|
||||||
// generates a request string for sending
|
|
||||||
// to the tracker
|
|
||||||
tracker_request generate_tracker_request();
|
|
||||||
|
|
||||||
// if no password and username is set
|
// if no password and username is set
|
||||||
// this will return an empty string, otherwise
|
// this will return an empty string, otherwise
|
||||||
// it will concatenate the login and password
|
// it will concatenate the login and password
|
||||||
@ -369,14 +372,12 @@ namespace libtorrent
|
|||||||
// announce will take place.
|
// announce will take place.
|
||||||
ptime next_announce() const;
|
ptime next_announce() const;
|
||||||
|
|
||||||
// returns true if it is time for this torrent to make another
|
|
||||||
// tracker request
|
|
||||||
bool should_request();
|
|
||||||
|
|
||||||
// forcefully sets next_announce to the current time
|
// forcefully sets next_announce to the current time
|
||||||
void force_tracker_request();
|
void force_tracker_request();
|
||||||
void force_tracker_request(ptime);
|
void force_tracker_request(ptime);
|
||||||
void scrape_tracker();
|
void scrape_tracker();
|
||||||
|
void announce_with_tracker(tracker_request::event_t e
|
||||||
|
= tracker_request::none);
|
||||||
ptime const& last_scrape() const { return m_last_scrape; }
|
ptime const& last_scrape() const { return m_last_scrape; }
|
||||||
|
|
||||||
// sets the username and password that will be sent to
|
// sets the username and password that will be sent to
|
||||||
@ -524,8 +525,8 @@ namespace libtorrent
|
|||||||
// this is done when a piece fails
|
// this is done when a piece fails
|
||||||
void restore_piece_state(int index);
|
void restore_piece_state(int index);
|
||||||
|
|
||||||
void received_redundant_data(int num_bytes)
|
void add_redundant_bytes(int b);
|
||||||
{ TORRENT_ASSERT(num_bytes > 0); m_total_redundant_bytes += num_bytes; }
|
void add_failed_bytes(int b);
|
||||||
|
|
||||||
// this is true if we have all the pieces
|
// this is true if we have all the pieces
|
||||||
bool is_seed() const
|
bool is_seed() const
|
||||||
@ -631,7 +632,7 @@ namespace libtorrent
|
|||||||
void on_piece_verified(int ret, disk_io_job const& j
|
void on_piece_verified(int ret, disk_io_job const& j
|
||||||
, boost::function<void(int)> f);
|
, boost::function<void(int)> f);
|
||||||
|
|
||||||
void try_next_tracker();
|
void try_next_tracker(tracker_request const& req);
|
||||||
int prioritize_tracker(int tracker_index);
|
int prioritize_tracker(int tracker_index);
|
||||||
void on_country_lookup(error_code const& error, tcp::resolver::iterator i
|
void on_country_lookup(error_code const& error, tcp::resolver::iterator i
|
||||||
, boost::intrusive_ptr<peer_connection> p) const;
|
, boost::intrusive_ptr<peer_connection> p) const;
|
||||||
@ -666,8 +667,6 @@ namespace libtorrent
|
|||||||
|
|
||||||
boost::intrusive_ptr<torrent_info> m_torrent_file;
|
boost::intrusive_ptr<torrent_info> m_torrent_file;
|
||||||
|
|
||||||
tracker_request::event_t m_event;
|
|
||||||
|
|
||||||
void parse_response(const entry& e, std::vector<peer_entry>& peer_list);
|
void parse_response(const entry& e, std::vector<peer_entry>& peer_list);
|
||||||
|
|
||||||
// if this pointer is 0, the torrent is in
|
// if this pointer is 0, the torrent is in
|
||||||
@ -695,8 +694,8 @@ namespace libtorrent
|
|||||||
// the object.
|
// the object.
|
||||||
piece_manager* m_storage;
|
piece_manager* m_storage;
|
||||||
|
|
||||||
// the time of next tracker request
|
// the time of next tracker announce
|
||||||
ptime m_next_request;
|
ptime m_next_tracker_announce;
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
public:
|
public:
|
||||||
@ -729,13 +728,24 @@ namespace libtorrent
|
|||||||
// this announce timer is used both
|
// this announce timer is used both
|
||||||
// by Local service discovery and
|
// by Local service discovery and
|
||||||
// by the DHT.
|
// by the DHT.
|
||||||
deadline_timer m_announce_timer;
|
deadline_timer m_lsd_announce_timer;
|
||||||
|
|
||||||
static void on_announce_disp(boost::weak_ptr<torrent> p
|
// used for tracker announces
|
||||||
|
deadline_timer m_tracker_timer;
|
||||||
|
|
||||||
|
void restart_tracker_timer(ptime announce_at);
|
||||||
|
|
||||||
|
static void on_tracker_announce_disp(boost::weak_ptr<torrent> p
|
||||||
, error_code const& e);
|
, error_code const& e);
|
||||||
|
|
||||||
// this is called once per announce interval
|
void on_tracker_announce();
|
||||||
void on_announce();
|
|
||||||
|
static void on_lsd_announce_disp(boost::weak_ptr<torrent> p
|
||||||
|
, error_code const& e);
|
||||||
|
|
||||||
|
// this is called once every 5 minutes for torrents
|
||||||
|
// that are not private
|
||||||
|
void on_lsd_announce();
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
static void on_dht_announce_response_disp(boost::weak_ptr<torrent> t
|
static void on_dht_announce_response_disp(boost::weak_ptr<torrent> t
|
||||||
@ -885,9 +895,6 @@ namespace libtorrent
|
|||||||
|
|
||||||
// is true if this torrent has been paused
|
// is true if this torrent has been paused
|
||||||
bool m_paused:1;
|
bool m_paused:1;
|
||||||
// this is true from the time when the torrent was
|
|
||||||
// paused to the time should_request() is called
|
|
||||||
bool m_just_paused:1;
|
|
||||||
|
|
||||||
// if this is true, libtorrent may pause and resume
|
// if this is true, libtorrent may pause and resume
|
||||||
// this torrent depending on queuing rules. Torrents
|
// this torrent depending on queuing rules. Torrents
|
||||||
@ -937,21 +944,31 @@ namespace libtorrent
|
|||||||
// before the files are checked, we don't try to
|
// before the files are checked, we don't try to
|
||||||
// connect to peers
|
// connect to peers
|
||||||
bool m_files_checked:1;
|
bool m_files_checked:1;
|
||||||
|
|
||||||
|
// this is true while tracker announcing is enabled
|
||||||
|
// is is disabled while paused and checking files
|
||||||
|
bool m_announcing:1;
|
||||||
|
|
||||||
|
// this is true if event start has been sent to the tracker
|
||||||
|
bool m_start_sent:1;
|
||||||
|
|
||||||
|
// this is true if event completed has been sent to the tracker
|
||||||
|
bool m_complete_sent:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline ptime torrent::next_announce() const
|
inline ptime torrent::next_announce() const
|
||||||
{
|
{
|
||||||
return m_next_request;
|
return m_next_tracker_announce;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void torrent::force_tracker_request()
|
inline void torrent::force_tracker_request()
|
||||||
{
|
{
|
||||||
m_next_request = time_now();
|
if (!is_paused()) announce_with_tracker();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void torrent::force_tracker_request(ptime t)
|
inline void torrent::force_tracker_request(ptime t)
|
||||||
{
|
{
|
||||||
m_next_request = t;
|
if (!is_paused()) restart_tracker_timer(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void torrent::set_tracker_login(
|
inline void torrent::set_tracker_login(
|
||||||
|
@ -322,7 +322,10 @@ namespace libtorrent
|
|||||||
// fills the specified vector with the download progress [0, 1]
|
// fills the specified vector with the download progress [0, 1]
|
||||||
// of each file in the torrent. The files are ordered as in
|
// of each file in the torrent. The files are ordered as in
|
||||||
// the torrent_info.
|
// the torrent_info.
|
||||||
void file_progress(std::vector<float>& progress);
|
void file_progress(std::vector<float>& progress) const TORRENT_DEPRECATED;
|
||||||
|
void file_progress(std::vector<size_type>& progress) const;
|
||||||
|
|
||||||
|
void clear_error() const;
|
||||||
|
|
||||||
std::vector<announce_entry> const& trackers() const;
|
std::vector<announce_entry> const& trackers() const;
|
||||||
void replace_trackers(std::vector<announce_entry> const&) const;
|
void replace_trackers(std::vector<announce_entry> const&) const;
|
||||||
|
@ -101,6 +101,22 @@ namespace libtorrent
|
|||||||
cached_piece_info info;
|
cached_piece_info info;
|
||||||
info.piece = i->piece;
|
info.piece = i->piece;
|
||||||
info.last_use = i->last_use;
|
info.last_use = i->last_use;
|
||||||
|
info.kind = cached_piece_info::write_cache;
|
||||||
|
int blocks_in_piece = (ti.piece_size(i->piece) + (m_block_size) - 1) / m_block_size;
|
||||||
|
info.blocks.resize(blocks_in_piece);
|
||||||
|
for (int b = 0; b < blocks_in_piece; ++b)
|
||||||
|
if (i->blocks[b]) info.blocks[b] = true;
|
||||||
|
ret.push_back(info);
|
||||||
|
}
|
||||||
|
for (cache_t::const_iterator i = m_read_pieces.begin()
|
||||||
|
, end(m_read_pieces.end()); i != end; ++i)
|
||||||
|
{
|
||||||
|
torrent_info const& ti = *i->storage->info();
|
||||||
|
if (ti.info_hash() != ih) continue;
|
||||||
|
cached_piece_info info;
|
||||||
|
info.piece = i->piece;
|
||||||
|
info.last_use = i->last_use;
|
||||||
|
info.kind = cached_piece_info::read_cache;
|
||||||
int blocks_in_piece = (ti.piece_size(i->piece) + (m_block_size) - 1) / m_block_size;
|
int blocks_in_piece = (ti.piece_size(i->piece) + (m_block_size) - 1) / m_block_size;
|
||||||
info.blocks.resize(blocks_in_piece);
|
info.blocks.resize(blocks_in_piece);
|
||||||
for (int b = 0; b < blocks_in_piece; ++b)
|
for (int b = 0; b < blocks_in_piece; ++b)
|
||||||
|
@ -161,25 +161,19 @@ namespace libtorrent
|
|||||||
bool open(fs::path const& path, int mode)
|
bool open(fs::path const& path, int mode)
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
#if defined(_WIN32) && defined(UNICODE)
|
#if defined _WIN32 && defined UNICODE
|
||||||
std::wstring wpath(safe_convert(path.native_file_string()));
|
std::wstring wpath(safe_convert(path.native_file_string()));
|
||||||
m_fd = ::_wopen(
|
m_fd = ::_wopen(
|
||||||
wpath.c_str()
|
wpath.c_str()
|
||||||
, map_open_mode(mode)
|
, map_open_mode(mode));
|
||||||
, S_IREAD | S_IWRITE);
|
#elif defined _WIN32
|
||||||
#else
|
|
||||||
#ifdef _WIN32
|
|
||||||
m_fd = ::_open(
|
m_fd = ::_open(
|
||||||
|
utf8_native(path.native_file_string()).c_str()
|
||||||
|
, map_open_mode(mode));
|
||||||
#else
|
#else
|
||||||
m_fd = ::open(
|
m_fd = ::open(
|
||||||
#endif
|
|
||||||
utf8_native(path.native_file_string()).c_str()
|
utf8_native(path.native_file_string()).c_str()
|
||||||
, map_open_mode(mode)
|
, map_open_mode(mode));
|
||||||
#ifdef _WIN32
|
|
||||||
, S_IREAD | S_IWRITE);
|
|
||||||
#else
|
|
||||||
, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
if (m_fd == -1)
|
if (m_fd == -1)
|
||||||
{
|
{
|
||||||
|
@ -632,7 +632,9 @@ namespace libtorrent
|
|||||||
|
|
||||||
if (peer_info_struct())
|
if (peer_info_struct())
|
||||||
{
|
{
|
||||||
peer_info_struct()->on_parole = true;
|
if (m_ses.settings().use_parole_mode)
|
||||||
|
peer_info_struct()->on_parole = true;
|
||||||
|
|
||||||
++peer_info_struct()->hashfails;
|
++peer_info_struct()->hashfails;
|
||||||
boost::int8_t& trust_points = peer_info_struct()->trust_points;
|
boost::int8_t& trust_points = peer_info_struct()->trust_points;
|
||||||
|
|
||||||
@ -1509,7 +1511,7 @@ namespace libtorrent
|
|||||||
// just ignore it
|
// just ignore it
|
||||||
if (t->is_seed())
|
if (t->is_seed())
|
||||||
{
|
{
|
||||||
t->received_redundant_data(p.length);
|
t->add_redundant_bytes(p.length);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1541,7 +1543,7 @@ namespace libtorrent
|
|||||||
(*m_logger) << " *** The block we just got was not in the "
|
(*m_logger) << " *** The block we just got was not in the "
|
||||||
"request queue ***\n";
|
"request queue ***\n";
|
||||||
#endif
|
#endif
|
||||||
t->received_redundant_data(p.length);
|
t->add_redundant_bytes(p.length);
|
||||||
request_a_block(*t, *this);
|
request_a_block(*t, *this);
|
||||||
send_block_requests();
|
send_block_requests();
|
||||||
return;
|
return;
|
||||||
@ -1578,7 +1580,7 @@ namespace libtorrent
|
|||||||
// if the block we got is already finished, then ignore it
|
// if the block we got is already finished, then ignore it
|
||||||
if (picker.is_downloaded(block_finished))
|
if (picker.is_downloaded(block_finished))
|
||||||
{
|
{
|
||||||
t->received_redundant_data(p.length);
|
t->add_redundant_bytes(p.length);
|
||||||
|
|
||||||
m_download_queue.erase(b);
|
m_download_queue.erase(b);
|
||||||
m_timeout_extend = 0;
|
m_timeout_extend = 0;
|
||||||
@ -2813,6 +2815,11 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
m_desired_queue_size = 1;
|
m_desired_queue_size = 1;
|
||||||
|
|
||||||
|
if (on_parole())
|
||||||
|
{
|
||||||
|
m_timeout_extend += m_ses.settings().request_timeout;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!t->has_picker()) return;
|
if (!t->has_picker()) return;
|
||||||
piece_picker& picker = t->picker();
|
piece_picker& picker = t->picker();
|
||||||
|
|
||||||
@ -3579,9 +3586,6 @@ namespace libtorrent
|
|||||||
boost::shared_ptr<torrent> t = m_torrent.lock();
|
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||||
if (m_disconnecting)
|
if (m_disconnecting)
|
||||||
{
|
{
|
||||||
for (aux::session_impl::torrent_map::const_iterator i = m_ses.m_torrents.begin()
|
|
||||||
, end(m_ses.m_torrents.end()); i != end; ++i)
|
|
||||||
TORRENT_ASSERT(!i->second->has_peer((peer_connection*)this));
|
|
||||||
TORRENT_ASSERT(!t);
|
TORRENT_ASSERT(!t);
|
||||||
}
|
}
|
||||||
else if (!m_in_constructor)
|
else if (!m_in_constructor)
|
||||||
@ -3622,11 +3626,13 @@ namespace libtorrent
|
|||||||
|
|
||||||
if (!t)
|
if (!t)
|
||||||
{
|
{
|
||||||
|
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
|
||||||
// since this connection doesn't have a torrent reference
|
// since this connection doesn't have a torrent reference
|
||||||
// no torrent should have a reference to this connection either
|
// no torrent should have a reference to this connection either
|
||||||
for (aux::session_impl::torrent_map::const_iterator i = m_ses.m_torrents.begin()
|
for (aux::session_impl::torrent_map::const_iterator i = m_ses.m_torrents.begin()
|
||||||
, end(m_ses.m_torrents.end()); i != end; ++i)
|
, end(m_ses.m_torrents.end()); i != end; ++i)
|
||||||
TORRENT_ASSERT(!i->second->has_peer((peer_connection*)this));
|
TORRENT_ASSERT(!i->second->has_peer((peer_connection*)this));
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3636,7 +3642,9 @@ namespace libtorrent
|
|||||||
for (torrent::const_peer_iterator i = t->begin(); i != t->end(); ++i)
|
for (torrent::const_peer_iterator i = t->begin(); i != t->end(); ++i)
|
||||||
{
|
{
|
||||||
// make sure this peer is not a dangling pointer
|
// make sure this peer is not a dangling pointer
|
||||||
|
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
|
||||||
TORRENT_ASSERT(m_ses.has_peer(*i));
|
TORRENT_ASSERT(m_ses.has_peer(*i));
|
||||||
|
#endif
|
||||||
peer_connection const& p = *(*i);
|
peer_connection const& p = *(*i);
|
||||||
for (std::deque<piece_block>::const_iterator i = p.request_queue().begin()
|
for (std::deque<piece_block>::const_iterator i = p.request_queue().begin()
|
||||||
, end(p.request_queue().end()); i != end; ++i)
|
, end(p.request_queue().end()); i != end; ++i)
|
||||||
@ -3652,16 +3660,18 @@ namespace libtorrent
|
|||||||
TORRENT_ASSERT(t->picker().num_peers(i->first) == i->second);
|
TORRENT_ASSERT(t->picker().num_peers(i->first) == i->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
|
||||||
if (m_peer_info)
|
if (m_peer_info)
|
||||||
{
|
{
|
||||||
policy::const_iterator i;
|
policy::const_iterator i;
|
||||||
for (i = t->get_policy().begin_peer();
|
for (i = t->get_policy().begin_peer()
|
||||||
i != t->get_policy().end_peer(); ++i)
|
, end(t->get_policy().end_peer()); i != end; ++i)
|
||||||
{
|
{
|
||||||
if (&i->second == m_peer_info) break;
|
if (&i->second == m_peer_info) break;
|
||||||
}
|
}
|
||||||
TORRENT_ASSERT(i != t->get_policy().end_peer());
|
TORRENT_ASSERT(i != t->get_policy().end_peer());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (t->has_picker() && !t->is_aborted())
|
if (t->has_picker() && !t->is_aborted())
|
||||||
{
|
{
|
||||||
// make sure that pieces that have completed the download
|
// make sure that pieces that have completed the download
|
||||||
|
@ -502,8 +502,6 @@ namespace libtorrent
|
|||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (m_torrent->is_paused()) return;
|
|
||||||
|
|
||||||
// ------------------------
|
// ------------------------
|
||||||
// upload shift
|
// upload shift
|
||||||
// ------------------------
|
// ------------------------
|
||||||
|
@ -185,6 +185,8 @@ namespace aux {
|
|||||||
, m_asnum_db(0)
|
, m_asnum_db(0)
|
||||||
, m_country_db(0)
|
, m_country_db(0)
|
||||||
#endif
|
#endif
|
||||||
|
, m_total_failed_bytes(0)
|
||||||
|
, m_total_redundant_bytes(0)
|
||||||
{
|
{
|
||||||
m_tcp_mapping[0] = -1;
|
m_tcp_mapping[0] = -1;
|
||||||
m_tcp_mapping[1] = -1;
|
m_tcp_mapping[1] = -1;
|
||||||
@ -466,31 +468,9 @@ namespace aux {
|
|||||||
i != m_torrents.end(); ++i)
|
i != m_torrents.end(); ++i)
|
||||||
{
|
{
|
||||||
torrent& t = *i->second;
|
torrent& t = *i->second;
|
||||||
|
t.abort();
|
||||||
if ((!t.is_paused() || t.should_request())
|
|
||||||
&& !t.trackers().empty())
|
|
||||||
{
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
|
||||||
++counter;
|
|
||||||
#endif
|
|
||||||
tracker_request req = t.generate_tracker_request();
|
|
||||||
TORRENT_ASSERT(req.event == tracker_request::stopped);
|
|
||||||
req.listen_port = 0;
|
|
||||||
if (!m_listen_sockets.empty())
|
|
||||||
req.listen_port = m_listen_sockets.front().external_port;
|
|
||||||
req.key = m_key;
|
|
||||||
std::string login = i->second->tracker_login();
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
|
||||||
boost::shared_ptr<tracker_logger> tl(new tracker_logger(*this));
|
|
||||||
m_tracker_loggers.push_back(tl);
|
|
||||||
m_tracker_manager.queue_request(m_io_service, m_half_open, req, login
|
|
||||||
, m_listen_interface.address(), tl);
|
|
||||||
#else
|
|
||||||
m_tracker_manager.queue_request(m_io_service, m_half_open, req, login
|
|
||||||
, m_listen_interface.address());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
(*m_logger) << time_now_string() << " sent " << counter << " tracker stop requests\n";
|
(*m_logger) << time_now_string() << " sent " << counter << " tracker stop requests\n";
|
||||||
#endif
|
#endif
|
||||||
@ -1035,7 +1015,7 @@ namespace aux {
|
|||||||
// ignore connections that already have a torrent, since they
|
// ignore connections that already have a torrent, since they
|
||||||
// are ticket through the torrents' second_ticket
|
// are ticket through the torrents' second_ticket
|
||||||
if (!p->associated_torrent().expired()) continue;
|
if (!p->associated_torrent().expired()) continue;
|
||||||
if (m_last_tick - p->connected_time() > seconds(m_settings.peer_connect_timeout))
|
if (m_last_tick - p->connected_time() > seconds(m_settings.handshake_timeout))
|
||||||
p->disconnect("timeout: incoming connection");
|
p->disconnect("timeout: incoming connection");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1090,23 +1070,6 @@ namespace aux {
|
|||||||
num_downloads_peers += t.num_peers();
|
num_downloads_peers += t.num_peers();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t.should_request())
|
|
||||||
{
|
|
||||||
tracker_request req = t.generate_tracker_request();
|
|
||||||
req.listen_port = 0;
|
|
||||||
if (!m_listen_sockets.empty())
|
|
||||||
req.listen_port = m_listen_sockets.front().external_port;
|
|
||||||
req.key = m_key;
|
|
||||||
m_tracker_manager.queue_request(m_io_service, m_half_open, req
|
|
||||||
, t.tracker_login(), m_listen_interface.address(), i->second);
|
|
||||||
|
|
||||||
if (m_alerts.should_post<tracker_announce_alert>())
|
|
||||||
{
|
|
||||||
m_alerts.post_alert(
|
|
||||||
tracker_announce_alert(t.get_handle(), req.url));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
t.second_tick(m_stat, tick_interval);
|
t.second_tick(m_stat, tick_interval);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
@ -1838,32 +1801,6 @@ namespace aux {
|
|||||||
t.delete_files();
|
t.delete_files();
|
||||||
t.abort();
|
t.abort();
|
||||||
|
|
||||||
if ((!t.is_paused() || t.should_request())
|
|
||||||
&& !t.trackers().empty())
|
|
||||||
{
|
|
||||||
tracker_request req = t.generate_tracker_request();
|
|
||||||
TORRENT_ASSERT(req.event == tracker_request::stopped);
|
|
||||||
req.listen_port = 0;
|
|
||||||
if (!m_listen_sockets.empty())
|
|
||||||
req.listen_port = m_listen_sockets.front().external_port;
|
|
||||||
req.key = m_key;
|
|
||||||
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
|
||||||
boost::shared_ptr<tracker_logger> tl(new tracker_logger(*this));
|
|
||||||
m_tracker_loggers.push_back(tl);
|
|
||||||
m_tracker_manager.queue_request(m_io_service, m_half_open, req
|
|
||||||
, t.tracker_login(), m_listen_interface.address(), tl);
|
|
||||||
#else
|
|
||||||
m_tracker_manager.queue_request(m_io_service, m_half_open, req
|
|
||||||
, t.tracker_login(), m_listen_interface.address());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (m_alerts.should_post<tracker_announce_alert>())
|
|
||||||
{
|
|
||||||
m_alerts.post_alert(
|
|
||||||
tracker_announce_alert(t.get_handle(), req.url));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
sha1_hash i_hash = t.torrent_file().info_hash();
|
sha1_hash i_hash = t.torrent_file().info_hash();
|
||||||
#endif
|
#endif
|
||||||
@ -2017,6 +1954,9 @@ namespace aux {
|
|||||||
s.num_unchoked = m_num_unchoked;
|
s.num_unchoked = m_num_unchoked;
|
||||||
s.allowed_upload_slots = m_allowed_upload_slots;
|
s.allowed_upload_slots = m_allowed_upload_slots;
|
||||||
|
|
||||||
|
s.total_redundant_bytes = m_total_redundant_bytes;
|
||||||
|
s.total_failed_bytes = m_total_failed_bytes;
|
||||||
|
|
||||||
s.up_bandwidth_queue = m_upload_channel.queue_size();
|
s.up_bandwidth_queue = m_upload_channel.queue_size();
|
||||||
s.down_bandwidth_queue = m_download_channel.queue_size();
|
s.down_bandwidth_queue = m_download_channel.queue_size();
|
||||||
|
|
||||||
|
@ -155,11 +155,11 @@ namespace libtorrent
|
|||||||
, m_started(time_now())
|
, m_started(time_now())
|
||||||
, m_last_scrape(min_time())
|
, m_last_scrape(min_time())
|
||||||
, m_torrent_file(tf)
|
, m_torrent_file(tf)
|
||||||
, m_event(tracker_request::started)
|
|
||||||
, m_storage(0)
|
, m_storage(0)
|
||||||
, m_next_request(time_now())
|
, m_next_tracker_announce(time_now())
|
||||||
, m_host_resolver(ses.m_io_service)
|
, m_host_resolver(ses.m_io_service)
|
||||||
, m_announce_timer(ses.m_io_service)
|
, m_lsd_announce_timer(ses.m_io_service)
|
||||||
|
, m_tracker_timer(ses.m_io_service)
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
, m_last_dht_announce(time_now() - minutes(15))
|
, m_last_dht_announce(time_now() - minutes(15))
|
||||||
#endif
|
#endif
|
||||||
@ -191,7 +191,6 @@ namespace libtorrent
|
|||||||
, m_time_scaler(0)
|
, m_time_scaler(0)
|
||||||
, m_abort(false)
|
, m_abort(false)
|
||||||
, m_paused(paused)
|
, m_paused(paused)
|
||||||
, m_just_paused(false)
|
|
||||||
, m_auto_managed(auto_managed)
|
, m_auto_managed(auto_managed)
|
||||||
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
||||||
, m_resolving_country(false)
|
, m_resolving_country(false)
|
||||||
@ -202,6 +201,9 @@ namespace libtorrent
|
|||||||
, m_connections_initialized(true)
|
, m_connections_initialized(true)
|
||||||
, m_has_incoming(false)
|
, m_has_incoming(false)
|
||||||
, m_files_checked(false)
|
, m_files_checked(false)
|
||||||
|
, m_announcing(false)
|
||||||
|
, m_start_sent(false)
|
||||||
|
, m_complete_sent(false)
|
||||||
{
|
{
|
||||||
parse_resume_data(resume_data);
|
parse_resume_data(resume_data);
|
||||||
}
|
}
|
||||||
@ -228,11 +230,11 @@ namespace libtorrent
|
|||||||
, m_started(time_now())
|
, m_started(time_now())
|
||||||
, m_last_scrape(min_time())
|
, m_last_scrape(min_time())
|
||||||
, m_torrent_file(new torrent_info(info_hash))
|
, m_torrent_file(new torrent_info(info_hash))
|
||||||
, m_event(tracker_request::started)
|
|
||||||
, m_storage(0)
|
, m_storage(0)
|
||||||
, m_next_request(time_now())
|
, m_next_tracker_announce(time_now())
|
||||||
, m_host_resolver(ses.m_io_service)
|
, m_host_resolver(ses.m_io_service)
|
||||||
, m_announce_timer(ses.m_io_service)
|
, m_lsd_announce_timer(ses.m_io_service)
|
||||||
|
, m_tracker_timer(ses.m_io_service)
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
, m_last_dht_announce(time_now() - minutes(15))
|
, m_last_dht_announce(time_now() - minutes(15))
|
||||||
#endif
|
#endif
|
||||||
@ -263,7 +265,6 @@ namespace libtorrent
|
|||||||
, m_time_scaler(0)
|
, m_time_scaler(0)
|
||||||
, m_abort(false)
|
, m_abort(false)
|
||||||
, m_paused(paused)
|
, m_paused(paused)
|
||||||
, m_just_paused(false)
|
|
||||||
, m_auto_managed(auto_managed)
|
, m_auto_managed(auto_managed)
|
||||||
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
||||||
, m_resolving_country(false)
|
, m_resolving_country(false)
|
||||||
@ -273,6 +274,10 @@ namespace libtorrent
|
|||||||
, m_got_tracker_response(false)
|
, m_got_tracker_response(false)
|
||||||
, m_connections_initialized(false)
|
, m_connections_initialized(false)
|
||||||
, m_has_incoming(false)
|
, m_has_incoming(false)
|
||||||
|
, m_files_checked(false)
|
||||||
|
, m_announcing(false)
|
||||||
|
, m_start_sent(false)
|
||||||
|
, m_complete_sent(false)
|
||||||
{
|
{
|
||||||
parse_resume_data(resume_data);
|
parse_resume_data(resume_data);
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@ -310,13 +315,8 @@ namespace libtorrent
|
|||||||
|
|
||||||
void torrent::start()
|
void torrent::start()
|
||||||
{
|
{
|
||||||
boost::weak_ptr<torrent> self(shared_from_this());
|
|
||||||
if (m_torrent_file->is_valid()) init();
|
if (m_torrent_file->is_valid()) init();
|
||||||
if (m_abort) return;
|
if (m_abort) return;
|
||||||
error_code ec;
|
|
||||||
m_announce_timer.expires_from_now(seconds(1), ec);
|
|
||||||
m_announce_timer.async_wait(
|
|
||||||
bind(&torrent::on_announce_disp, self, _1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
@ -748,41 +748,57 @@ namespace libtorrent
|
|||||||
m_net_interface = tcp::endpoint(address::from_string(net_interface), 0);
|
m_net_interface = tcp::endpoint(address::from_string(net_interface), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::on_announce_disp(boost::weak_ptr<torrent> p
|
void torrent::on_tracker_announce_disp(boost::weak_ptr<torrent> p
|
||||||
, error_code const& e)
|
, error_code const& e)
|
||||||
{
|
{
|
||||||
if (e) return;
|
if (e) return;
|
||||||
boost::shared_ptr<torrent> t = p.lock();
|
boost::shared_ptr<torrent> t = p.lock();
|
||||||
if (!t) return;
|
if (!t) return;
|
||||||
t->on_announce();
|
t->on_tracker_announce();
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::on_announce()
|
void torrent::on_tracker_announce()
|
||||||
{
|
{
|
||||||
|
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||||
|
|
||||||
if (m_abort) return;
|
if (m_abort) return;
|
||||||
|
announce_with_tracker();
|
||||||
|
}
|
||||||
|
|
||||||
|
void torrent::on_lsd_announce_disp(boost::weak_ptr<torrent> p
|
||||||
|
, error_code const& e)
|
||||||
|
{
|
||||||
|
if (e) return;
|
||||||
|
boost::shared_ptr<torrent> t = p.lock();
|
||||||
|
if (!t) return;
|
||||||
|
t->on_lsd_announce();
|
||||||
|
}
|
||||||
|
|
||||||
|
void torrent::on_lsd_announce()
|
||||||
|
{
|
||||||
|
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||||
|
|
||||||
|
if (m_abort) return;
|
||||||
|
|
||||||
|
TORRENT_ASSERT(!m_torrent_file->priv());
|
||||||
|
if (m_torrent_file->is_valid() && m_torrent_file->priv())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (is_paused()) return;
|
||||||
|
|
||||||
boost::weak_ptr<torrent> self(shared_from_this());
|
boost::weak_ptr<torrent> self(shared_from_this());
|
||||||
|
|
||||||
error_code ec;
|
error_code ec;
|
||||||
if (!m_torrent_file->priv())
|
|
||||||
{
|
|
||||||
// announce on local network every 5 minutes
|
|
||||||
m_announce_timer.expires_from_now(minutes(5), ec);
|
|
||||||
m_announce_timer.async_wait(
|
|
||||||
bind(&torrent::on_announce_disp, self, _1));
|
|
||||||
|
|
||||||
// announce with the local discovery service
|
// announce on local network every 5 minutes
|
||||||
if (!is_paused()) m_ses.announce_lsd(m_torrent_file->info_hash());
|
m_lsd_announce_timer.expires_from_now(minutes(5), ec);
|
||||||
}
|
m_lsd_announce_timer.async_wait(
|
||||||
else
|
bind(&torrent::on_lsd_announce_disp, self, _1));
|
||||||
{
|
|
||||||
m_announce_timer.expires_from_now(minutes(15), ec);
|
// announce with the local discovery service
|
||||||
m_announce_timer.async_wait(
|
m_ses.announce_lsd(m_torrent_file->info_hash());
|
||||||
bind(&torrent::on_announce_disp, self, _1));
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
if (is_paused()) return;
|
|
||||||
if (!m_ses.m_dht) return;
|
if (!m_ses.m_dht) return;
|
||||||
ptime now = time_now();
|
ptime now = time_now();
|
||||||
if (should_announce_dht() && now - m_last_dht_announce > minutes(14))
|
if (should_announce_dht() && now - m_last_dht_announce > minutes(14))
|
||||||
@ -821,6 +837,61 @@ namespace libtorrent
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void torrent::announce_with_tracker(tracker_request::event_t e)
|
||||||
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
|
TORRENT_ASSERT(!m_trackers.empty());
|
||||||
|
|
||||||
|
restart_tracker_timer(time_now() + seconds(tracker_retry_delay_max));
|
||||||
|
|
||||||
|
if (e == tracker_request::none)
|
||||||
|
{
|
||||||
|
if (!m_start_sent) e = tracker_request::started;
|
||||||
|
if (!m_complete_sent && is_seed()) e = tracker_request::completed;
|
||||||
|
}
|
||||||
|
|
||||||
|
tracker_request req;
|
||||||
|
req.info_hash = m_torrent_file->info_hash();
|
||||||
|
req.pid = m_ses.get_peer_id();
|
||||||
|
req.downloaded = m_stat.total_payload_download();
|
||||||
|
req.uploaded = m_stat.total_payload_upload();
|
||||||
|
req.left = bytes_left();
|
||||||
|
if (req.left == -1) req.left = 16*1024;
|
||||||
|
req.event = e;
|
||||||
|
tcp::endpoint ep = m_ses.get_ipv6_interface();
|
||||||
|
if (ep != tcp::endpoint())
|
||||||
|
req.ipv6 = ep.address().to_string();
|
||||||
|
|
||||||
|
req.url = m_trackers[m_currently_trying_tracker].url;
|
||||||
|
// if we are aborting. we don't want any new peers
|
||||||
|
req.num_want = (req.event == tracker_request::stopped)
|
||||||
|
?0:m_settings.num_want;
|
||||||
|
|
||||||
|
req.listen_port = m_ses.m_listen_sockets.empty()
|
||||||
|
?0:m_ses.m_listen_sockets.front().external_port;
|
||||||
|
req.key = m_ses.m_key;
|
||||||
|
|
||||||
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
|
if (m_abort)
|
||||||
|
{
|
||||||
|
boost::shared_ptr<tracker_logger> tl(new tracker_logger(m_ses));
|
||||||
|
m_ses.m_tracker_manager.queue_request(m_ses.m_io_service, m_ses.m_half_open, req
|
||||||
|
, tracker_login(), m_ses.m_listen_interface.address(), tl);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
m_ses.m_tracker_manager.queue_request(m_ses.m_io_service, m_ses.m_half_open, req
|
||||||
|
, tracker_login(), m_ses.m_listen_interface.address()
|
||||||
|
, m_abort?boost::shared_ptr<torrent>():shared_from_this());
|
||||||
|
|
||||||
|
if (m_ses.m_alerts.should_post<tracker_announce_alert>())
|
||||||
|
{
|
||||||
|
m_ses.m_alerts.post_alert(
|
||||||
|
tracker_announce_alert(get_handle(), req.url, req.event));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void torrent::scrape_tracker()
|
void torrent::scrape_tracker()
|
||||||
{
|
{
|
||||||
if (m_trackers.empty()) return;
|
if (m_trackers.empty()) return;
|
||||||
@ -838,23 +909,6 @@ namespace libtorrent
|
|||||||
m_last_scrape = time_now();
|
m_last_scrape = time_now();
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns true if it is time for this torrent to make another
|
|
||||||
// tracker request
|
|
||||||
bool torrent::should_request()
|
|
||||||
{
|
|
||||||
// INVARIANT_CHECK;
|
|
||||||
|
|
||||||
if (m_trackers.empty()) return false;
|
|
||||||
if (!m_files_checked) return false;
|
|
||||||
|
|
||||||
if (m_just_paused)
|
|
||||||
{
|
|
||||||
m_just_paused = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return !is_paused() && m_next_request < time_now();
|
|
||||||
}
|
|
||||||
|
|
||||||
void torrent::tracker_warning(tracker_request const& req, std::string const& msg)
|
void torrent::tracker_warning(tracker_request const& req, std::string const& msg)
|
||||||
{
|
{
|
||||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||||
@ -899,6 +953,11 @@ namespace libtorrent
|
|||||||
if (external_ip != address())
|
if (external_ip != address())
|
||||||
m_ses.set_external_address(external_ip);
|
m_ses.set_external_address(external_ip);
|
||||||
|
|
||||||
|
if (!m_start_sent && r.event == tracker_request::started)
|
||||||
|
m_start_sent = true;
|
||||||
|
if (!m_complete_sent && r.event == tracker_request::completed)
|
||||||
|
m_complete_sent = true;
|
||||||
|
|
||||||
m_failed_trackers = 0;
|
m_failed_trackers = 0;
|
||||||
// announce intervals less than 5 minutes
|
// announce intervals less than 5 minutes
|
||||||
// are insane.
|
// are insane.
|
||||||
@ -909,16 +968,13 @@ namespace libtorrent
|
|||||||
m_currently_trying_tracker = 0;
|
m_currently_trying_tracker = 0;
|
||||||
|
|
||||||
m_duration = interval;
|
m_duration = interval;
|
||||||
m_next_request = time_now() + seconds(m_duration);
|
restart_tracker_timer(time_now() + seconds(m_duration));
|
||||||
|
|
||||||
if (complete >= 0) m_complete = complete;
|
if (complete >= 0) m_complete = complete;
|
||||||
if (incomplete >= 0) m_incomplete = incomplete;
|
if (incomplete >= 0) m_incomplete = incomplete;
|
||||||
if (complete >= 0 && incomplete >= 0)
|
if (complete >= 0 && incomplete >= 0)
|
||||||
m_last_scrape = time_now();
|
m_last_scrape = time_now();
|
||||||
|
|
||||||
// connect to random peers from the list
|
|
||||||
std::random_shuffle(peer_list.begin(), peer_list.end());
|
|
||||||
|
|
||||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
|
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
s << "TRACKER RESPONSE:\n"
|
s << "TRACKER RESPONSE:\n"
|
||||||
@ -1363,7 +1419,7 @@ namespace libtorrent
|
|||||||
m_ses.m_alerts.post_alert(hash_failed_alert(get_handle(), index));
|
m_ses.m_alerts.post_alert(hash_failed_alert(get_handle(), index));
|
||||||
|
|
||||||
// increase the total amount of failed bytes
|
// increase the total amount of failed bytes
|
||||||
m_total_failed_bytes += m_torrent_file->piece_size(index);
|
add_failed_bytes(m_torrent_file->piece_size(index));
|
||||||
|
|
||||||
std::vector<void*> downloaders;
|
std::vector<void*> downloaders;
|
||||||
m_picker->get_downloaders(downloaders, index);
|
m_picker->get_downloaders(downloaders, index);
|
||||||
@ -1503,9 +1559,9 @@ namespace libtorrent
|
|||||||
// if the torrent is paused, it doesn't need
|
// if the torrent is paused, it doesn't need
|
||||||
// to announce with even=stopped again.
|
// to announce with even=stopped again.
|
||||||
if (!is_paused())
|
if (!is_paused())
|
||||||
m_event = tracker_request::stopped;
|
{
|
||||||
// disconnect all peers and close all
|
stop_announcing();
|
||||||
// files belonging to the torrents
|
}
|
||||||
|
|
||||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING
|
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING
|
||||||
for (peer_iterator i = m_connections.begin();
|
for (peer_iterator i = m_connections.begin();
|
||||||
@ -1515,14 +1571,14 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// disconnect all peers and close all
|
||||||
|
// files belonging to the torrents
|
||||||
disconnect_all();
|
disconnect_all();
|
||||||
if (m_owning_storage.get())
|
if (m_owning_storage.get())
|
||||||
m_storage->async_release_files(
|
m_storage->async_release_files(
|
||||||
bind(&torrent::on_files_released, shared_from_this(), _1, _2));
|
bind(&torrent::on_files_released, shared_from_this(), _1, _2));
|
||||||
|
|
||||||
m_owning_storage = 0;
|
m_owning_storage = 0;
|
||||||
error_code ec;
|
|
||||||
m_announce_timer.cancel(ec);
|
|
||||||
m_host_resolver.cancel();
|
m_host_resolver.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1880,42 +1936,6 @@ namespace libtorrent
|
|||||||
m_last_working_tracker = -1;
|
m_last_working_tracker = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tracker_request torrent::generate_tracker_request()
|
|
||||||
{
|
|
||||||
INVARIANT_CHECK;
|
|
||||||
|
|
||||||
TORRENT_ASSERT(!m_trackers.empty());
|
|
||||||
|
|
||||||
m_next_request = time_now() + seconds(tracker_retry_delay_max);
|
|
||||||
|
|
||||||
tracker_request req;
|
|
||||||
req.info_hash = m_torrent_file->info_hash();
|
|
||||||
req.pid = m_ses.get_peer_id();
|
|
||||||
req.downloaded = m_stat.total_payload_download();
|
|
||||||
req.uploaded = m_stat.total_payload_upload();
|
|
||||||
req.left = bytes_left();
|
|
||||||
if (req.left == -1) req.left = 16*1024;
|
|
||||||
req.event = m_event;
|
|
||||||
tcp::endpoint ep = m_ses.get_ipv6_interface();
|
|
||||||
if (ep != tcp::endpoint())
|
|
||||||
req.ipv6 = ep.address().to_string();
|
|
||||||
|
|
||||||
if (m_event != tracker_request::stopped)
|
|
||||||
m_event = tracker_request::none;
|
|
||||||
req.url = m_trackers[m_currently_trying_tracker].url;
|
|
||||||
req.num_want = m_settings.num_want;
|
|
||||||
// if we are aborting. we don't want any new peers
|
|
||||||
if (req.event == tracker_request::stopped)
|
|
||||||
req.num_want = 0;
|
|
||||||
|
|
||||||
// default initialize, these should be set by caller
|
|
||||||
// before passing the request to the tracker_manager
|
|
||||||
req.listen_port = 0;
|
|
||||||
req.key = 0;
|
|
||||||
|
|
||||||
return req;
|
|
||||||
}
|
|
||||||
|
|
||||||
void torrent::choke_peer(peer_connection& c)
|
void torrent::choke_peer(peer_connection& c)
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
@ -3094,11 +3114,8 @@ namespace libtorrent
|
|||||||
|
|
||||||
m_picker.reset();
|
m_picker.reset();
|
||||||
|
|
||||||
// make the next tracker request
|
|
||||||
// be a completed-event
|
|
||||||
m_event = tracker_request::completed;
|
|
||||||
set_state(torrent_status::seeding);
|
set_state(torrent_status::seeding);
|
||||||
force_tracker_request();
|
if (!m_complete_sent && m_announcing) announce_with_tracker();
|
||||||
}
|
}
|
||||||
|
|
||||||
// this will move the tracker with the given index
|
// this will move the tracker with the given index
|
||||||
@ -3119,46 +3136,48 @@ namespace libtorrent
|
|||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::try_next_tracker()
|
void torrent::try_next_tracker(tracker_request const& req)
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
++m_currently_trying_tracker;
|
++m_currently_trying_tracker;
|
||||||
|
|
||||||
if ((unsigned)m_currently_trying_tracker >= m_trackers.size())
|
if ((unsigned)m_currently_trying_tracker < m_trackers.size())
|
||||||
{
|
{
|
||||||
int delay = tracker_retry_delay_min
|
announce_with_tracker(req.event);
|
||||||
+ (std::min)(int(m_failed_trackers), int(tracker_failed_max))
|
return;
|
||||||
* (tracker_retry_delay_max - tracker_retry_delay_min)
|
}
|
||||||
/ tracker_failed_max;
|
|
||||||
|
|
||||||
++m_failed_trackers;
|
int delay = tracker_retry_delay_min
|
||||||
// if we've looped the tracker list, wait a bit before retrying
|
+ (std::min)(int(m_failed_trackers), int(tracker_failed_max))
|
||||||
m_currently_trying_tracker = 0;
|
* (tracker_retry_delay_max - tracker_retry_delay_min)
|
||||||
m_next_request = time_now() + seconds(delay);
|
/ tracker_failed_max;
|
||||||
|
|
||||||
|
++m_failed_trackers;
|
||||||
|
// if we've looped the tracker list, wait a bit before retrying
|
||||||
|
m_currently_trying_tracker = 0;
|
||||||
|
|
||||||
|
// if we're stopping, just give up. Don't bother retrying
|
||||||
|
if (req.event == tracker_request::stopped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
restart_tracker_timer(time_now() + seconds(delay));
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
if (m_abort) return;
|
if (m_abort) return;
|
||||||
|
|
||||||
// only start the announce if we want to announce with the dht
|
// only start the announce if we want to announce with the dht
|
||||||
ptime now = time_now();
|
ptime now = time_now();
|
||||||
if (should_announce_dht() && now - m_last_dht_announce > minutes(14))
|
if (should_announce_dht() && now - m_last_dht_announce > minutes(14))
|
||||||
{
|
|
||||||
// force the DHT to reannounce
|
|
||||||
m_last_dht_announce = now;
|
|
||||||
boost::weak_ptr<torrent> self(shared_from_this());
|
|
||||||
m_ses.m_dht->announce(m_torrent_file->info_hash()
|
|
||||||
, m_ses.m_listen_sockets.front().external_port
|
|
||||||
, bind(&torrent::on_dht_announce_response_disp, self, _1));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// don't delay before trying the next tracker
|
// force the DHT to reannounce
|
||||||
m_next_request = time_now();
|
m_last_dht_announce = now;
|
||||||
|
boost::weak_ptr<torrent> self(shared_from_this());
|
||||||
|
m_ses.m_dht->announce(m_torrent_file->info_hash()
|
||||||
|
, m_ses.m_listen_sockets.front().external_port
|
||||||
|
, bind(&torrent::on_dht_announce_response_disp, self, _1));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3196,7 +3215,11 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (is_seed()) finished();
|
if (is_seed())
|
||||||
|
{
|
||||||
|
m_complete_sent = true;
|
||||||
|
finished();
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_connections_initialized)
|
if (!m_connections_initialized)
|
||||||
{
|
{
|
||||||
@ -3231,6 +3254,8 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_files_checked = true;
|
m_files_checked = true;
|
||||||
|
|
||||||
|
start_announcing();
|
||||||
}
|
}
|
||||||
|
|
||||||
alert_manager& torrent::alerts() const
|
alert_manager& torrent::alerts() const
|
||||||
@ -3326,8 +3351,10 @@ namespace libtorrent
|
|||||||
std::map<piece_block, int> num_requests;
|
std::map<piece_block, int> num_requests;
|
||||||
for (const_peer_iterator i = begin(); i != end(); ++i)
|
for (const_peer_iterator i = begin(); i != end(); ++i)
|
||||||
{
|
{
|
||||||
|
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
|
||||||
// make sure this peer is not a dangling pointer
|
// make sure this peer is not a dangling pointer
|
||||||
TORRENT_ASSERT(m_ses.has_peer(*i));
|
TORRENT_ASSERT(m_ses.has_peer(*i));
|
||||||
|
#endif
|
||||||
peer_connection const& p = *(*i);
|
peer_connection const& p = *(*i);
|
||||||
for (std::deque<piece_block>::const_iterator i = p.request_queue().begin()
|
for (std::deque<piece_block>::const_iterator i = p.request_queue().begin()
|
||||||
, end(p.request_queue().end()); i != end; ++i)
|
, end(p.request_queue().end()); i != end; ++i)
|
||||||
@ -3362,11 +3389,13 @@ namespace libtorrent
|
|||||||
TORRENT_ASSERT(m_abort || m_picker->num_pieces() == 0);
|
TORRENT_ASSERT(m_abort || m_picker->num_pieces() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
|
||||||
for (policy::const_iterator i = m_policy.begin_peer()
|
for (policy::const_iterator i = m_policy.begin_peer()
|
||||||
, end(m_policy.end_peer()); i != end; ++i)
|
, end(m_policy.end_peer()); i != end; ++i)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(i->second.ip.address() == i->first);
|
TORRENT_ASSERT(i->second.ip.address() == i->first);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
size_type total_done = quantized_bytes_done();
|
size_type total_done = quantized_bytes_done();
|
||||||
if (m_torrent_file->is_valid())
|
if (m_torrent_file->is_valid())
|
||||||
@ -3569,11 +3598,7 @@ namespace libtorrent
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
disconnect_all();
|
disconnect_all();
|
||||||
if (!is_paused())
|
stop_announcing();
|
||||||
m_just_paused = true;
|
|
||||||
m_paused = true;
|
|
||||||
// tell the tracker that we stopped
|
|
||||||
m_event = tracker_request::stopped;
|
|
||||||
|
|
||||||
if (m_owning_storage.get())
|
if (m_owning_storage.get())
|
||||||
{
|
{
|
||||||
@ -3583,6 +3608,14 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void torrent::clear_error()
|
||||||
|
{
|
||||||
|
if (m_error.empty()) return;
|
||||||
|
if (m_ses.m_auto_manage_time_scaler > 2)
|
||||||
|
m_ses.m_auto_manage_time_scaler = 2;
|
||||||
|
m_error.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void torrent::auto_managed(bool a)
|
void torrent::auto_managed(bool a)
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
@ -3725,10 +3758,6 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
disconnect_all();
|
|
||||||
// tell the tracker that we stopped
|
|
||||||
m_event = tracker_request::stopped;
|
|
||||||
m_just_paused = true;
|
|
||||||
// this will make the storage close all
|
// this will make the storage close all
|
||||||
// files and flush all cached data
|
// files and flush all cached data
|
||||||
if (m_owning_storage.get())
|
if (m_owning_storage.get())
|
||||||
@ -3742,6 +3771,9 @@ namespace libtorrent
|
|||||||
if (alerts().should_post<torrent_paused_alert>())
|
if (alerts().should_post<torrent_paused_alert>())
|
||||||
alerts().post_alert(torrent_paused_alert(get_handle()));
|
alerts().post_alert(torrent_paused_alert(get_handle()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disconnect_all();
|
||||||
|
stop_announcing();
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::resume()
|
void torrent::resume()
|
||||||
@ -3771,18 +3803,64 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_started = time_now();
|
|
||||||
m_error.clear();
|
|
||||||
|
|
||||||
if (alerts().should_post<torrent_resumed_alert>())
|
if (alerts().should_post<torrent_resumed_alert>())
|
||||||
alerts().post_alert(torrent_resumed_alert(get_handle()));
|
alerts().post_alert(torrent_resumed_alert(get_handle()));
|
||||||
|
|
||||||
// tell the tracker that we're back
|
m_started = time_now();
|
||||||
m_event = tracker_request::started;
|
m_error.clear();
|
||||||
force_tracker_request();
|
start_announcing();
|
||||||
|
}
|
||||||
|
|
||||||
// make pulse be called as soon as possible
|
void torrent::restart_tracker_timer(ptime announce_at)
|
||||||
m_time_scaler = 0;
|
{
|
||||||
|
if (!m_announcing) return;
|
||||||
|
|
||||||
|
m_next_tracker_announce = announce_at;
|
||||||
|
error_code ec;
|
||||||
|
boost::weak_ptr<torrent> self(shared_from_this());
|
||||||
|
m_tracker_timer.expires_at(m_next_tracker_announce, ec);
|
||||||
|
m_tracker_timer.async_wait(bind(&torrent::on_tracker_announce_disp, self, _1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void torrent::start_announcing()
|
||||||
|
{
|
||||||
|
if (is_paused()) return;
|
||||||
|
if (!m_files_checked) return;
|
||||||
|
if (m_announcing) return;
|
||||||
|
|
||||||
|
m_announcing = true;
|
||||||
|
|
||||||
|
if (!m_trackers.empty())
|
||||||
|
{
|
||||||
|
// tell the tracker that we're back
|
||||||
|
m_start_sent = false;
|
||||||
|
announce_with_tracker();
|
||||||
|
}
|
||||||
|
|
||||||
|
// private torrents are never announced on LSD
|
||||||
|
// or on DHT, we don't need this timer.
|
||||||
|
if (!m_torrent_file->is_valid() || !m_torrent_file->priv())
|
||||||
|
{
|
||||||
|
error_code ec;
|
||||||
|
boost::weak_ptr<torrent> self(shared_from_this());
|
||||||
|
m_lsd_announce_timer.expires_from_now(seconds(1), ec);
|
||||||
|
m_lsd_announce_timer.async_wait(
|
||||||
|
bind(&torrent::on_lsd_announce_disp, self, _1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void torrent::stop_announcing()
|
||||||
|
{
|
||||||
|
if (!m_announcing) return;
|
||||||
|
|
||||||
|
error_code ec;
|
||||||
|
m_lsd_announce_timer.cancel(ec);
|
||||||
|
m_tracker_timer.cancel(ec);
|
||||||
|
|
||||||
|
m_announcing = false;
|
||||||
|
|
||||||
|
if (!m_trackers.empty())
|
||||||
|
announce_with_tracker(tracker_request::stopped);
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::second_tick(stat& accumulator, float tick_interval)
|
void torrent::second_tick(stat& accumulator, float tick_interval)
|
||||||
@ -3803,7 +3881,7 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (m_paused)
|
if (is_paused())
|
||||||
{
|
{
|
||||||
// let the stats fade out to 0
|
// let the stats fade out to 0
|
||||||
m_stat.second_tick(tick_interval);
|
m_stat.second_tick(tick_interval);
|
||||||
@ -3816,7 +3894,7 @@ namespace libtorrent
|
|||||||
|
|
||||||
// ---- WEB SEEDS ----
|
// ---- WEB SEEDS ----
|
||||||
|
|
||||||
// re-insert urls that are to be retries into the m_web_seeds
|
// re-insert urls that are to be retrieds into the m_web_seeds
|
||||||
typedef std::map<std::string, ptime>::iterator iter_t;
|
typedef std::map<std::string, ptime>::iterator iter_t;
|
||||||
for (iter_t i = m_web_seeds_next_retry.begin(); i != m_web_seeds_next_retry.end();)
|
for (iter_t i = m_web_seeds_next_retry.begin(); i != m_web_seeds_next_retry.end();)
|
||||||
{
|
{
|
||||||
@ -3972,18 +4050,34 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
|
|
||||||
void torrent::file_progress(std::vector<float>& fp) const
|
void torrent::file_progress(std::vector<float>& fp) const
|
||||||
|
{
|
||||||
|
fp.clear();
|
||||||
|
fp.resize(m_torrent_file->num_files(), 1.f);
|
||||||
|
if (is_seed()) return;
|
||||||
|
|
||||||
|
std::vector<size_type> progress;
|
||||||
|
file_progress(progress);
|
||||||
|
for (int i = 0; i < m_torrent_file->num_files(); ++i)
|
||||||
|
{
|
||||||
|
file_entry const& f = m_torrent_file->file_at(i);
|
||||||
|
if (f.size == 0) fp[i] = 1.f;
|
||||||
|
else fp[i] = float(progress[i]) / f.size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void torrent::file_progress(std::vector<size_type>& fp) const
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(valid_metadata());
|
TORRENT_ASSERT(valid_metadata());
|
||||||
|
|
||||||
fp.clear();
|
fp.resize(m_torrent_file->num_files(), 0);
|
||||||
|
TORRENT_ASSERT(has_picker());
|
||||||
|
|
||||||
if (is_seed())
|
if (is_seed())
|
||||||
{
|
{
|
||||||
fp.resize(m_torrent_file->num_files(), 1.f);
|
for (int i = 0; i < m_torrent_file->num_files(); ++i)
|
||||||
|
fp[i] = m_torrent_file->files().at(i).size;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_ASSERT(has_picker());
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
@ -3994,7 +4088,7 @@ namespace libtorrent
|
|||||||
// 100% done all the time
|
// 100% done all the time
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
fp[i] = 1.f;
|
fp[i] = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4010,7 +4104,7 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
TORRENT_ASSERT(size == 0);
|
TORRENT_ASSERT(size == 0);
|
||||||
|
|
||||||
fp[i] = static_cast<float>(done) / m_torrent_file->files().at(i).size;
|
fp[i] = done;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<piece_picker::downloading_piece>& q
|
const std::vector<piece_picker::downloading_piece>& q
|
||||||
@ -4026,28 +4120,56 @@ namespace libtorrent
|
|||||||
piece_picker::block_info const* info = i->info;
|
piece_picker::block_info const* info = i->info;
|
||||||
for (int k = 0; k < num_blocks; ++k)
|
for (int k = 0; k < num_blocks; ++k)
|
||||||
{
|
{
|
||||||
if (info[k].state != piece_picker::block_info::state_writing
|
TORRENT_ASSERT(offset == size_type(i->index) * m_torrent_file->piece_length()
|
||||||
&& info[k].state != piece_picker::block_info::state_finished)
|
+ k * m_block_size);
|
||||||
|
|
||||||
|
size_type block_size = m_block_size;
|
||||||
|
|
||||||
|
if (info[k].state == piece_picker::block_info::state_none)
|
||||||
|
{
|
||||||
|
offset += m_block_size;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info[k].state == piece_picker::block_info::state_requested)
|
||||||
|
{
|
||||||
|
block_size = 0;
|
||||||
|
policy::peer* p = static_cast<policy::peer*>(info[k].peer);
|
||||||
|
if (p && p->connection)
|
||||||
|
{
|
||||||
|
boost::optional<piece_block_progress> pbp
|
||||||
|
= p->connection->downloading_piece_progress();
|
||||||
|
if (pbp && pbp->piece_index == i->index && pbp->block_index == k)
|
||||||
|
block_size = pbp->bytes_downloaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block_size == 0)
|
||||||
|
{
|
||||||
|
offset += m_block_size;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (offset + m_block_size > file->offset + file->size)
|
if (offset + m_block_size > file->offset + file->size)
|
||||||
{
|
{
|
||||||
|
int left_over = m_block_size - block_size;
|
||||||
// split the block on multiple files
|
// split the block on multiple files
|
||||||
size_type block_size = m_block_size;
|
|
||||||
while (offset + block_size > file->offset + file->size)
|
while (offset + block_size > file->offset + file->size)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(offset <= file->offset + file->size);
|
TORRENT_ASSERT(offset <= file->offset + file->size);
|
||||||
size_type slice = file->offset + file->size - offset;
|
size_type slice = file->offset + file->size - offset;
|
||||||
fp[file_index] += float(slice) / file->size;
|
fp[file_index] += slice;
|
||||||
offset += slice;
|
offset += slice;
|
||||||
block_size -= slice;
|
block_size -= slice;
|
||||||
++file;
|
++file;
|
||||||
++file_index;
|
++file_index;
|
||||||
if (file == m_torrent_file->end_files()) break;
|
if (file == m_torrent_file->end_files()) break;
|
||||||
}
|
}
|
||||||
|
offset += left_over;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fp[file_index] += float(m_block_size) / file->size;
|
fp[file_index] += block_size;
|
||||||
offset += m_block_size;
|
offset += m_block_size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4208,6 +4330,20 @@ namespace libtorrent
|
|||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void torrent::add_redundant_bytes(int b)
|
||||||
|
{
|
||||||
|
TORRENT_ASSERT(b > 0);
|
||||||
|
m_total_redundant_bytes += b;
|
||||||
|
m_ses.add_redundant_bytes(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void torrent::add_failed_bytes(int b)
|
||||||
|
{
|
||||||
|
TORRENT_ASSERT(b > 0);
|
||||||
|
m_total_failed_bytes += b;
|
||||||
|
m_ses.add_failed_bytes(b);
|
||||||
|
}
|
||||||
|
|
||||||
int torrent::num_seeds() const
|
int torrent::num_seeds() const
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
@ -4245,7 +4381,7 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (r.kind == tracker_request::announce_request)
|
if (r.kind == tracker_request::announce_request)
|
||||||
try_next_tracker();
|
try_next_tracker(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: with some response codes, we should just consider
|
// TODO: with some response codes, we should just consider
|
||||||
@ -4278,7 +4414,7 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (r.kind == tracker_request::announce_request)
|
if (r.kind == tracker_request::announce_request)
|
||||||
try_next_tracker();
|
try_next_tracker(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -319,6 +319,12 @@ namespace libtorrent
|
|||||||
TORRENT_FORWARD(set_queue_position((std::numeric_limits<int>::max)()));
|
TORRENT_FORWARD(set_queue_position((std::numeric_limits<int>::max)()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void torrent_handle::clear_error() const
|
||||||
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
TORRENT_FORWARD(clear_error());
|
||||||
|
}
|
||||||
|
|
||||||
void torrent_handle::set_tracker_login(std::string const& name
|
void torrent_handle::set_tracker_login(std::string const& name
|
||||||
, std::string const& password) const
|
, std::string const& password) const
|
||||||
{
|
{
|
||||||
@ -326,7 +332,13 @@ namespace libtorrent
|
|||||||
TORRENT_FORWARD(set_tracker_login(name, password));
|
TORRENT_FORWARD(set_tracker_login(name, password));
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent_handle::file_progress(std::vector<float>& progress)
|
void torrent_handle::file_progress(std::vector<float>& progress) const
|
||||||
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
TORRENT_FORWARD(file_progress(progress));
|
||||||
|
}
|
||||||
|
|
||||||
|
void torrent_handle::file_progress(std::vector<size_type>& progress) const
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
TORRENT_FORWARD(file_progress(progress));
|
TORRENT_FORWARD(file_progress(progress));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user