From c5af2c2eaf945fffc59ac547e940b44c51fb78c5 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sat, 12 Jul 2008 08:25:19 +0000 Subject: [PATCH] moved tracker announces into a timer instead of polling every second. Added state to properly send complete, started and stopped events --- include/libtorrent/torrent.hpp | 59 +++--- src/policy.cpp | 2 - src/session_impl.cpp | 71 +------ src/torrent.cpp | 362 +++++++++++++++++++-------------- 4 files changed, 253 insertions(+), 241 deletions(-) diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 7475e0a36..b7d45e364 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -156,6 +156,9 @@ namespace libtorrent void files_checked(); void start_checking(); + void start_announcing(); + void stop_announcing(); + int seed_rank(session_settings const& s) const; storage_mode_t storage_mode() const { return m_storage_mode; } @@ -354,10 +357,6 @@ namespace libtorrent virtual void tracker_scrape_response(tracker_request const& req , 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 // this will return an empty string, otherwise // it will concatenate the login and password @@ -369,14 +368,12 @@ namespace libtorrent // announce will take place. 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 void force_tracker_request(); void force_tracker_request(ptime); void scrape_tracker(); + void announce_with_tracker(tracker_request::event_t e + = tracker_request::none); ptime const& last_scrape() const { return m_last_scrape; } // sets the username and password that will be sent to @@ -631,7 +628,7 @@ namespace libtorrent void on_piece_verified(int ret, disk_io_job const& j , boost::function f); - void try_next_tracker(); + void try_next_tracker(tracker_request const& req); int prioritize_tracker(int tracker_index); void on_country_lookup(error_code const& error, tcp::resolver::iterator i , boost::intrusive_ptr p) const; @@ -666,8 +663,6 @@ namespace libtorrent boost::intrusive_ptr m_torrent_file; - tracker_request::event_t m_event; - void parse_response(const entry& e, std::vector& peer_list); // if this pointer is 0, the torrent is in @@ -695,8 +690,8 @@ namespace libtorrent // the object. piece_manager* m_storage; - // the time of next tracker request - ptime m_next_request; + // the time of next tracker announce + ptime m_next_tracker_announce; #ifndef NDEBUG public: @@ -729,13 +724,24 @@ namespace libtorrent // this announce timer is used both // by Local service discovery and // by the DHT. - deadline_timer m_announce_timer; + deadline_timer m_lsd_announce_timer; - static void on_announce_disp(boost::weak_ptr 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 p , error_code const& e); - // this is called once per announce interval - void on_announce(); + void on_tracker_announce(); + + static void on_lsd_announce_disp(boost::weak_ptr 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 static void on_dht_announce_response_disp(boost::weak_ptr t @@ -885,9 +891,6 @@ namespace libtorrent // is true if this torrent has been paused 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 // this torrent depending on queuing rules. Torrents @@ -937,21 +940,31 @@ namespace libtorrent // before the files are checked, we don't try to // connect to peers 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 { - return m_next_request; + return m_next_tracker_announce; } inline void torrent::force_tracker_request() { - m_next_request = time_now(); + announce_with_tracker(); } inline void torrent::force_tracker_request(ptime t) { - m_next_request = t; + restart_tracker_timer(t); } inline void torrent::set_tracker_login( diff --git a/src/policy.cpp b/src/policy.cpp index 2567e2424..33845b860 100644 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -502,8 +502,6 @@ namespace libtorrent { INVARIANT_CHECK; - if (m_torrent->is_paused()) return; - // ------------------------ // upload shift // ------------------------ diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 789340cd9..774159b66 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -468,31 +468,9 @@ namespace aux { i != m_torrents.end(); ++i) { torrent& t = *i->second; - - 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 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 - } + t.abort(); } + #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) (*m_logger) << time_now_string() << " sent " << counter << " tracker stop requests\n"; #endif @@ -1037,7 +1015,7 @@ namespace aux { // ignore connections that already have a torrent, since they // are ticket through the torrents' second_ticket 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"); } @@ -1092,23 +1070,6 @@ namespace aux { 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()) - { - m_alerts.post_alert( - tracker_announce_alert(t.get_handle(), req.url, req.event)); - } - } - t.second_tick(m_stat, tick_interval); ++i; } @@ -1840,32 +1801,6 @@ namespace aux { t.delete_files(); 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 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()) - { - m_alerts.post_alert( - tracker_announce_alert(t.get_handle(), req.url, req.event)); - } - } #ifndef NDEBUG sha1_hash i_hash = t.torrent_file().info_hash(); #endif diff --git a/src/torrent.cpp b/src/torrent.cpp index 5fbf00b6c..577172888 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -155,11 +155,11 @@ namespace libtorrent , m_started(time_now()) , m_last_scrape(min_time()) , m_torrent_file(tf) - , m_event(tracker_request::started) , m_storage(0) - , m_next_request(time_now()) + , m_next_tracker_announce(time_now()) , 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 , m_last_dht_announce(time_now() - minutes(15)) #endif @@ -191,7 +191,6 @@ namespace libtorrent , m_time_scaler(0) , m_abort(false) , m_paused(paused) - , m_just_paused(false) , m_auto_managed(auto_managed) #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES , m_resolving_country(false) @@ -202,6 +201,9 @@ namespace libtorrent , m_connections_initialized(true) , m_has_incoming(false) , m_files_checked(false) + , m_announcing(false) + , m_start_sent(false) + , m_complete_sent(false) { parse_resume_data(resume_data); } @@ -228,11 +230,11 @@ namespace libtorrent , m_started(time_now()) , m_last_scrape(min_time()) , m_torrent_file(new torrent_info(info_hash)) - , m_event(tracker_request::started) , m_storage(0) - , m_next_request(time_now()) + , m_next_tracker_announce(time_now()) , 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 , m_last_dht_announce(time_now() - minutes(15)) #endif @@ -263,7 +265,6 @@ namespace libtorrent , m_time_scaler(0) , m_abort(false) , m_paused(paused) - , m_just_paused(false) , m_auto_managed(auto_managed) #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES , m_resolving_country(false) @@ -273,6 +274,10 @@ namespace libtorrent , m_got_tracker_response(false) , m_connections_initialized(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); #ifndef NDEBUG @@ -310,13 +315,8 @@ namespace libtorrent void torrent::start() { - boost::weak_ptr self(shared_from_this()); if (m_torrent_file->is_valid()) init(); 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 @@ -748,41 +748,57 @@ namespace libtorrent m_net_interface = tcp::endpoint(address::from_string(net_interface), 0); } - void torrent::on_announce_disp(boost::weak_ptr p + void torrent::on_tracker_announce_disp(boost::weak_ptr p , error_code const& e) { if (e) return; boost::shared_ptr t = p.lock(); 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; + announce_with_tracker(); + } + + void torrent::on_lsd_announce_disp(boost::weak_ptr p + , error_code const& e) + { + if (e) return; + boost::shared_ptr 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 self(shared_from_this()); 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 - if (!is_paused()) m_ses.announce_lsd(m_torrent_file->info_hash()); - } - else - { - m_announce_timer.expires_from_now(minutes(15), ec); - m_announce_timer.async_wait( - bind(&torrent::on_announce_disp, self, _1)); - } + // announce on local network every 5 minutes + m_lsd_announce_timer.expires_from_now(minutes(5), ec); + m_lsd_announce_timer.async_wait( + bind(&torrent::on_lsd_announce_disp, self, _1)); + + // announce with the local discovery service + m_ses.announce_lsd(m_torrent_file->info_hash()); #ifndef TORRENT_DISABLE_DHT - if (is_paused()) return; if (!m_ses.m_dht) return; ptime now = time_now(); if (should_announce_dht() && now - m_last_dht_announce > minutes(14)) @@ -821,6 +837,61 @@ namespace libtorrent #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 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():shared_from_this()); + + if (m_ses.m_alerts.should_post()) + { + m_ses.m_alerts.post_alert( + tracker_announce_alert(get_handle(), req.url, req.event)); + } + } + void torrent::scrape_tracker() { if (m_trackers.empty()) return; @@ -838,23 +909,6 @@ namespace libtorrent 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) { session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); @@ -899,6 +953,11 @@ namespace libtorrent if (external_ip != address()) 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; // announce intervals less than 5 minutes // are insane. @@ -909,16 +968,13 @@ namespace libtorrent m_currently_trying_tracker = 0; 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 (incomplete >= 0) m_incomplete = incomplete; if (complete >= 0 && incomplete >= 0) 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 std::stringstream s; s << "TRACKER RESPONSE:\n" @@ -1503,9 +1559,9 @@ namespace libtorrent // if the torrent is paused, it doesn't need // to announce with even=stopped again. if (!is_paused()) - m_event = tracker_request::stopped; - // disconnect all peers and close all - // files belonging to the torrents + { + stop_announcing(); + } #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING for (peer_iterator i = m_connections.begin(); @@ -1515,14 +1571,14 @@ namespace libtorrent } #endif + // disconnect all peers and close all + // files belonging to the torrents disconnect_all(); if (m_owning_storage.get()) m_storage->async_release_files( bind(&torrent::on_files_released, shared_from_this(), _1, _2)); m_owning_storage = 0; - error_code ec; - m_announce_timer.cancel(ec); m_host_resolver.cancel(); } @@ -1880,42 +1936,6 @@ namespace libtorrent 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) { INVARIANT_CHECK; @@ -3094,11 +3114,8 @@ namespace libtorrent m_picker.reset(); - // make the next tracker request - // be a completed-event - m_event = tracker_request::completed; 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 @@ -3119,46 +3136,48 @@ namespace libtorrent return index; } - void torrent::try_next_tracker() + void torrent::try_next_tracker(tracker_request const& req) { INVARIANT_CHECK; ++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 - + (std::min)(int(m_failed_trackers), int(tracker_failed_max)) - * (tracker_retry_delay_max - tracker_retry_delay_min) - / tracker_failed_max; + announce_with_tracker(req.event); + return; + } - ++m_failed_trackers; - // if we've looped the tracker list, wait a bit before retrying - m_currently_trying_tracker = 0; - m_next_request = time_now() + seconds(delay); + int delay = tracker_retry_delay_min + + (std::min)(int(m_failed_trackers), int(tracker_failed_max)) + * (tracker_retry_delay_max - tracker_retry_delay_min) + / 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 - if (m_abort) return; + if (m_abort) return; - // only start the announce if we want to announce with the dht - ptime now = time_now(); - if (should_announce_dht() && now - m_last_dht_announce > minutes(14)) - { - // force the DHT to reannounce - m_last_dht_announce = now; - boost::weak_ptr 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 + // only start the announce if we want to announce with the dht + ptime now = time_now(); + if (should_announce_dht() && now - m_last_dht_announce > minutes(14)) { - // don't delay before trying the next tracker - m_next_request = time_now(); + // force the DHT to reannounce + m_last_dht_announce = now; + boost::weak_ptr 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 - if (is_seed()) finished(); + if (is_seed()) + { + m_complete_sent = true; + finished(); + } if (!m_connections_initialized) { @@ -3231,6 +3254,8 @@ namespace libtorrent } m_files_checked = true; + + start_announcing(); } alert_manager& torrent::alerts() const @@ -3569,11 +3594,7 @@ namespace libtorrent #endif disconnect_all(); - if (!is_paused()) - m_just_paused = true; - m_paused = true; - // tell the tracker that we stopped - m_event = tracker_request::stopped; + stop_announcing(); if (m_owning_storage.get()) { @@ -3725,10 +3746,6 @@ namespace libtorrent } #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 // files and flush all cached data if (m_owning_storage.get()) @@ -3742,6 +3759,9 @@ namespace libtorrent if (alerts().should_post()) alerts().post_alert(torrent_paused_alert(get_handle())); } + + disconnect_all(); + stop_announcing(); } void torrent::resume() @@ -3771,18 +3791,64 @@ namespace libtorrent } #endif - m_started = time_now(); - m_error.clear(); - if (alerts().should_post()) alerts().post_alert(torrent_resumed_alert(get_handle())); - // tell the tracker that we're back - m_event = tracker_request::started; - force_tracker_request(); + m_started = time_now(); + m_error.clear(); + start_announcing(); + } - // make pulse be called as soon as possible - m_time_scaler = 0; + void torrent::restart_tracker_timer(ptime announce_at) + { + if (!m_announcing) return; + + m_next_tracker_announce = announce_at; + error_code ec; + boost::weak_ptr 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 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) @@ -3803,7 +3869,7 @@ namespace libtorrent } #endif - if (m_paused) + if (is_paused()) { // let the stats fade out to 0 m_stat.second_tick(tick_interval); @@ -3816,7 +3882,7 @@ namespace libtorrent // ---- 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::iterator iter_t; for (iter_t i = m_web_seeds_next_retry.begin(); i != m_web_seeds_next_retry.end();) { @@ -4287,7 +4353,7 @@ namespace libtorrent } if (r.kind == tracker_request::announce_request) - try_next_tracker(); + try_next_tracker(r); } // TODO: with some response codes, we should just consider @@ -4320,7 +4386,7 @@ namespace libtorrent } if (r.kind == tracker_request::announce_request) - try_next_tracker(); + try_next_tracker(r); }