forked from premiere/premiere-libtorrent
introduced a more scalable API for torrent status updates (post_torrent_updates())
This commit is contained in:
parent
b0271e993c
commit
c4232065d8
|
@ -1,3 +1,4 @@
|
|||
* introduced a more scalable API for torrent status updates (post_torrent_updates())
|
||||
* updated the API to add_torrent_params turning all bools into flags of a flags field
|
||||
* added async_add_torrent() function to significantly improve performance when
|
||||
adding many torrents
|
||||
|
|
|
@ -394,7 +394,8 @@ async_add_torrent() add_torrent()
|
|||
flag_paused = 0x020,
|
||||
flag_auto_managed = 0x040.
|
||||
flag_duplicate_is_error = 0x080,
|
||||
flag_merge_resume_trackers = 0x100
|
||||
flag_merge_resume_trackers = 0x100,
|
||||
flag_update_subscribe = 0x200
|
||||
};
|
||||
|
||||
int version;
|
||||
|
@ -524,7 +525,8 @@ and how it's added. These are the flags::
|
|||
flag_paused = 0x020,
|
||||
flag_auto_managed = 0x040.
|
||||
flag_duplicate_is_error = 0x080,
|
||||
flag_merge_resume_trackers = 0x100
|
||||
flag_merge_resume_trackers = 0x100,
|
||||
flag_update_subscribe = 0x200
|
||||
}
|
||||
|
||||
``flag_apply_ip_filter`` determines if the IP filter should apply to this torrent or not. By
|
||||
|
@ -535,6 +537,9 @@ an auto-update torrent for instance.
|
|||
``flag_merge_resume_trackers`` defaults to off and specifies whether tracker URLs loaded from
|
||||
resume data should be added to the trackers in the torrent or replace the trackers.
|
||||
|
||||
``flag_update_subscribe`` is on by default and means that this torrent will be part of state
|
||||
updates when calling `post_torrent_updates()`_.
|
||||
|
||||
``flag_paused`` specifies whether or not the torrent is to be started in a paused
|
||||
state. I.e. it won't connect to the tracker or any of the peers until it's
|
||||
resumed. This is typically a good way of avoiding race conditions when setting
|
||||
|
@ -637,6 +642,11 @@ get_torrent_status() refresh_torrent_status()
|
|||
void refresh_torrent_status(std::vector<torrent_status>* ret
|
||||
, boost::uint32_t flags = 0) const;
|
||||
|
||||
.. note::
|
||||
these calls are potentially expensive and won't scale well
|
||||
with lots of torrents. If you're concerned about performance, consider
|
||||
using ``post_torrent_updates()`` instead.
|
||||
|
||||
``get_torrent_status`` returns a vector of the ``torrent_status`` for every
|
||||
torrent which satisfies ``pred``, which is a predicate function which determines
|
||||
if a torrent should be included in the returned set or not. Returning true means
|
||||
|
@ -656,6 +666,21 @@ if you have a lot of torrents.
|
|||
Any ``torrent_status`` object whose ``handle`` member is not referring to a
|
||||
valid torrent are ignored.
|
||||
|
||||
post_torrent_updates()
|
||||
----------------------
|
||||
|
||||
::
|
||||
|
||||
void post_torrent_updates();
|
||||
|
||||
This functions instructs the session to post the state_update_alert_, containing
|
||||
the status of all torrents whose state changed since the last time this function
|
||||
was called.
|
||||
|
||||
Only torrents who has the state subscription flag set will be included. This flag
|
||||
is on by default. See ``add_torrent_params`` under `async_add_torrent() add_torrent()`_.
|
||||
|
||||
|
||||
load_asnum_db() load_country_db() as_for_ip()
|
||||
---------------------------------------------
|
||||
|
||||
|
@ -7430,6 +7455,28 @@ as:
|
|||
|
||||
``ip`` is the IP address and port the connection came from.
|
||||
|
||||
state_update_alert
|
||||
------------------
|
||||
|
||||
This alert is only posted when requested by the user, by calling `post_torrent_updates()`_
|
||||
on the session. It contains the torrent status of all torrents that changed
|
||||
since last time this message was posted. Its category is ``status_notification``, but
|
||||
it's not subject to filtering, since it's only manually posted anyway.
|
||||
|
||||
::
|
||||
|
||||
|
||||
struct state_update_alert: alert
|
||||
{
|
||||
// ...
|
||||
std::vector<torrent_status> status;
|
||||
};
|
||||
|
||||
``status`` contains the torrent status of all torrents that changed since last time
|
||||
this message was posted. Note that you can map a torrent status to a specific torrent
|
||||
via its ``handle`` member. The receiving end is suggested to have all torrents sorted
|
||||
by the ``torrent_handle`` or hashed by it, for efficient updates.
|
||||
|
||||
|
||||
alert dispatcher
|
||||
================
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace libtorrent
|
|||
, userdata(0)
|
||||
, file_priorities(0)
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
, flags(flag_ignore_flags)
|
||||
, flags(flag_ignore_flags | default_flags)
|
||||
, seed_mode(false)
|
||||
, override_resume_data(false)
|
||||
, upload_mode(false)
|
||||
|
@ -68,26 +68,30 @@ namespace libtorrent
|
|||
, duplicate_is_error(false)
|
||||
, merge_resume_trackers(false)
|
||||
#else
|
||||
, flags(flag_apply_ip_filter | flag_paused | flag_auto_managed)
|
||||
, flags(default_flags)
|
||||
#endif
|
||||
{
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
if (flags == flag_ignore_flags)
|
||||
{
|
||||
flags = 0;
|
||||
if (seed_mode) flags |= flag_seed_mode;
|
||||
if (override_resume_data) flags |= flag_override_resume_data;
|
||||
if (upload_mode) flags |= flag_upload_mode;
|
||||
if (share_mode) flags |= flag_share_mode;
|
||||
if (apply_ip_filter) flags |= flag_apply_ip_filter;
|
||||
if (paused) flags |= flag_paused;
|
||||
if (auto_managed) flags |= flag_auto_managed;
|
||||
if (duplicate_is_error) flags |= flag_duplicate_is_error;
|
||||
if (merge_resume_trackers) flags |= flag_merge_resume_trackers;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
void update_flags() const
|
||||
{
|
||||
if (flags != (flag_ignore_flags | default_flags)) return;
|
||||
|
||||
boost::uint64_t& f = const_cast<boost::uint64_t&>(flags);
|
||||
f = flag_update_subscribe;
|
||||
if (seed_mode) f |= flag_seed_mode;
|
||||
if (override_resume_data) f |= flag_override_resume_data;
|
||||
if (upload_mode) f |= flag_upload_mode;
|
||||
if (share_mode) f |= flag_share_mode;
|
||||
if (apply_ip_filter) f |= flag_apply_ip_filter;
|
||||
if (paused) f |= flag_paused;
|
||||
if (auto_managed) f |= flag_auto_managed;
|
||||
if (duplicate_is_error) f |= flag_duplicate_is_error;
|
||||
if (merge_resume_trackers) f |= flag_merge_resume_trackers;
|
||||
}
|
||||
#endif
|
||||
|
||||
enum flags_t
|
||||
{
|
||||
flag_seed_mode = 0x001,
|
||||
|
@ -98,8 +102,10 @@ namespace libtorrent
|
|||
flag_paused = 0x020,
|
||||
flag_auto_managed = 0x040,
|
||||
flag_duplicate_is_error = 0x080,
|
||||
flag_merge_resume_trackers = 0x100
|
||||
flag_merge_resume_trackers = 0x100,
|
||||
flag_update_subscribe = 0x200,
|
||||
|
||||
default_flags = flag_update_subscribe | flag_auto_managed | flag_paused | flag_apply_ip_filter
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
, flag_ignore_flags = 0x80000000
|
||||
#endif
|
||||
|
|
|
@ -133,6 +133,7 @@ namespace libtorrent {
|
|||
~alert_manager();
|
||||
|
||||
void post_alert(const alert& alert_);
|
||||
void post_alert_ptr(alert* alert_);
|
||||
bool pending() const;
|
||||
std::auto_ptr<alert> get();
|
||||
void get_all(std::deque<alert*>* alerts);
|
||||
|
@ -165,6 +166,8 @@ namespace libtorrent {
|
|||
#endif
|
||||
|
||||
private:
|
||||
void post_impl(std::auto_ptr<alert>& alert_);
|
||||
|
||||
std::deque<alert*> m_alerts;
|
||||
mutable mutex m_mutex;
|
||||
// event m_condition;
|
||||
|
|
|
@ -1312,6 +1312,16 @@ namespace libtorrent
|
|||
error_code error;
|
||||
};
|
||||
|
||||
struct TORRENT_EXPORT state_update_alert : alert
|
||||
{
|
||||
TORRENT_DEFINE_ALERT(state_update_alert);
|
||||
|
||||
const static int static_category = alert::status_notification;
|
||||
virtual std::string message() const;
|
||||
virtual bool discardable() const { return false; }
|
||||
|
||||
std::vector<torrent_status> status;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -326,6 +326,7 @@ namespace libtorrent
|
|||
, boost::uint32_t flags) const;
|
||||
void refresh_torrent_status(std::vector<torrent_status>* ret
|
||||
, boost::uint32_t flags) const;
|
||||
void post_torrent_updates();
|
||||
|
||||
std::vector<torrent_handle> get_torrents() const;
|
||||
|
||||
|
@ -1062,6 +1063,10 @@ namespace libtorrent
|
|||
|
||||
std::vector<boost::shared_ptr<feed> > m_feeds;
|
||||
|
||||
// this is the set of (subscribed) torrents that have changed
|
||||
// their states since the last time the user requested updates.
|
||||
std::vector<boost::weak_ptr<torrent> > m_state_updates;
|
||||
|
||||
// the main working thread
|
||||
boost::scoped_ptr<thread> m_thread;
|
||||
|
||||
|
|
|
@ -184,6 +184,7 @@ namespace libtorrent
|
|||
, boost::uint32_t flags = 0) const;
|
||||
void refresh_torrent_status(std::vector<torrent_status>* ret
|
||||
, boost::uint32_t flags = 0) const;
|
||||
void post_torrent_updates();
|
||||
|
||||
// returns a list of all torrents in this session
|
||||
std::vector<torrent_handle> get_torrents() const;
|
||||
|
|
|
@ -304,6 +304,10 @@ namespace libtorrent
|
|||
|
||||
void status(torrent_status* st, boost::uint32_t flags);
|
||||
|
||||
// this torrent changed state, if the user is subscribing to
|
||||
// it, add it to the m_state_updates list in session_impl
|
||||
void state_updated();
|
||||
|
||||
void file_progress(std::vector<size_type>& fp, int flags = 0) const;
|
||||
|
||||
void use_interface(std::string net_interface);
|
||||
|
@ -325,6 +329,7 @@ namespace libtorrent
|
|||
if (prio > 255) prio = 255;
|
||||
else if (prio < 0) prio = 0;
|
||||
m_priority = prio;
|
||||
state_updated();
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
||||
|
@ -839,6 +844,9 @@ namespace libtorrent
|
|||
void queue_torrent_check();
|
||||
void dequeue_torrent_check();
|
||||
|
||||
void clear_in_state_update()
|
||||
{ m_in_state_updates = false; }
|
||||
|
||||
#ifdef TORRENT_USE_OPENSSL
|
||||
void set_ssl_cert(std::string const& certificate
|
||||
, std::string const& private_key
|
||||
|
@ -1322,7 +1330,7 @@ namespace libtorrent
|
|||
|
||||
// these are the flags sent in on a call to save_resume_data
|
||||
// we need to save them to check them in write_resume_data
|
||||
boost::uint8_t m_save_resume_flags;
|
||||
boost::uint8_t m_save_resume_flags;
|
||||
|
||||
// set to true when this torrent has been paused but
|
||||
// is waiting to finish all current download requests
|
||||
|
@ -1359,6 +1367,16 @@ namespace libtorrent
|
|||
// paused it's removed and when it's started again, it's
|
||||
// re-added
|
||||
bool m_in_encrypted_list:1;
|
||||
|
||||
// state subscription. If set, a pointer to this torrent
|
||||
// will be added to the m_state_updates set in session_impl
|
||||
// whenever this torrent's state changes (any state).
|
||||
bool m_state_subscription:1;
|
||||
|
||||
// in state_updates list. When adding a torrent to the
|
||||
// session_impl's m_state_update list, this bit is set
|
||||
// to never add the same torrent twice
|
||||
bool m_in_state_updates:1;
|
||||
|
||||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS
|
||||
public:
|
||||
|
|
|
@ -403,22 +403,20 @@ namespace libtorrent {
|
|||
dispatcher(*alert_);
|
||||
}
|
||||
|
||||
void alert_manager::post_alert(const alert& alert_)
|
||||
void alert_manager::post_alert_ptr(alert* alert_)
|
||||
{
|
||||
|
||||
std::auto_ptr<alert> a(alert_);
|
||||
mutex::scoped_lock lock(m_mutex);
|
||||
|
||||
if (m_dispatch)
|
||||
{
|
||||
TORRENT_ASSERT(m_alerts.empty());
|
||||
TORRENT_TRY {
|
||||
m_dispatch(std::auto_ptr<alert>(alert_.clone()));
|
||||
} TORRENT_CATCH(std::exception&) {}
|
||||
}
|
||||
else if (m_alerts.size() < m_queue_size_limit || !alert_.discardable())
|
||||
{
|
||||
m_alerts.push_back(alert_.clone().release());
|
||||
}
|
||||
post_impl(a);
|
||||
}
|
||||
|
||||
void alert_manager::post_alert(const alert& alert_)
|
||||
{
|
||||
std::auto_ptr<alert> a(alert_.clone());
|
||||
mutex::scoped_lock lock(m_mutex);
|
||||
|
||||
post_impl(a);
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
lock.unlock();
|
||||
|
@ -433,6 +431,21 @@ namespace libtorrent {
|
|||
#endif
|
||||
|
||||
}
|
||||
|
||||
void alert_manager::post_impl(std::auto_ptr<alert>& alert_)
|
||||
{
|
||||
if (m_dispatch)
|
||||
{
|
||||
TORRENT_ASSERT(m_alerts.empty());
|
||||
TORRENT_TRY {
|
||||
m_dispatch(alert_);
|
||||
} TORRENT_CATCH(std::exception&) {}
|
||||
}
|
||||
else if (m_alerts.size() < m_queue_size_limit || !alert_->discardable())
|
||||
{
|
||||
m_alerts.push_back(alert_.release());
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
void alert_manager::add_extension(boost::shared_ptr<plugin> ext)
|
||||
|
@ -601,5 +614,12 @@ namespace libtorrent {
|
|||
return msg;
|
||||
}
|
||||
|
||||
std::string state_update_alert::message() const
|
||||
{
|
||||
char msg[600];
|
||||
snprintf(msg, sizeof(msg), "state updates for %d torrents", int(status.size()));
|
||||
return msg;
|
||||
}
|
||||
|
||||
} // namespace libtorrent
|
||||
|
||||
|
|
|
@ -2139,11 +2139,15 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(m_outstanding_bytes >= bytes);
|
||||
m_outstanding_bytes -= bytes;
|
||||
if (m_outstanding_bytes < 0) m_outstanding_bytes = 0;
|
||||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS
|
||||
boost::shared_ptr<torrent> t = associated_torrent().lock();
|
||||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS
|
||||
TORRENT_ASSERT(m_received_in_piece + bytes <= t->block_size());
|
||||
m_received_in_piece += bytes;
|
||||
#endif
|
||||
|
||||
// progress of this torrent increased
|
||||
t->state_updated();
|
||||
|
||||
#if !defined TORRENT_DISABLE_INVARIANT_CHECKS && defined TORRENT_DEBUG
|
||||
check_invariant();
|
||||
#endif
|
||||
|
|
|
@ -939,6 +939,7 @@ namespace libtorrent
|
|||
// this cannot be a connect candidate anymore, since i->connection is set
|
||||
TORRENT_ASSERT(!is_connect_candidate(*i, m_finished));
|
||||
TORRENT_ASSERT(has_connection(&c));
|
||||
m_torrent->state_updated();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1091,6 +1092,8 @@ namespace libtorrent
|
|||
if (is_connect_candidate(*p, m_finished))
|
||||
++m_num_connect_candidates;
|
||||
|
||||
m_torrent->state_updated();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1195,6 +1198,7 @@ namespace libtorrent
|
|||
p = *iter;
|
||||
update_peer(p, src, flags, tcp::endpoint(), destination);
|
||||
}
|
||||
m_torrent->state_updated();
|
||||
return p;
|
||||
}
|
||||
#endif // TORRENT_USE_I2P
|
||||
|
|
|
@ -567,6 +567,11 @@ namespace libtorrent
|
|||
TORRENT_SYNC_CALL2(refresh_torrent_status, ret, flags);
|
||||
}
|
||||
|
||||
void session::post_torrent_updates()
|
||||
{
|
||||
TORRENT_ASYNC_CALL(post_torrent_updates);
|
||||
}
|
||||
|
||||
std::vector<torrent_handle> session::get_torrents() const
|
||||
{
|
||||
TORRENT_SYNC_CALL_RET(std::vector<torrent_handle>, get_torrents);
|
||||
|
|
|
@ -4342,6 +4342,25 @@ namespace aux {
|
|||
t->status(&*i, flags);
|
||||
}
|
||||
}
|
||||
|
||||
void session_impl::post_torrent_updates()
|
||||
{
|
||||
std::auto_ptr<state_update_alert> alert(new state_update_alert());
|
||||
alert->status.reserve(m_state_updates.size());
|
||||
|
||||
for (std::vector<boost::weak_ptr<torrent> >::iterator i = m_state_updates.begin()
|
||||
, end(m_state_updates.end()); i != end; ++i)
|
||||
{
|
||||
boost::shared_ptr<torrent> t = i->lock();
|
||||
if (!t) continue;
|
||||
alert->status.push_back(torrent_status());
|
||||
t->clear_in_state_update();
|
||||
t->status(&alert->status.back(), 0xffffffff);
|
||||
}
|
||||
m_state_updates.clear();
|
||||
|
||||
m_alerts.post_alert_ptr(alert.release());
|
||||
}
|
||||
|
||||
std::vector<torrent_handle> session_impl::get_torrents() const
|
||||
{
|
||||
|
@ -4378,6 +4397,10 @@ namespace aux {
|
|||
{
|
||||
TORRENT_ASSERT(!params.save_path.empty());
|
||||
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
params.update_flags();
|
||||
#endif
|
||||
|
||||
if (params.ti && params.ti->is_valid() && params.ti->num_files() == 0)
|
||||
{
|
||||
ec = errors::no_files_in_torrent;
|
||||
|
|
|
@ -427,6 +427,8 @@ namespace libtorrent
|
|||
, m_apply_ip_filter(p.flags & add_torrent_params::flag_apply_ip_filter)
|
||||
, m_merge_resume_trackers(p.flags & add_torrent_params::flag_merge_resume_trackers)
|
||||
, m_in_encrypted_list(false)
|
||||
, m_state_subscription(p.flags & add_torrent_params::flag_update_subscribe)
|
||||
, m_in_state_updates(false)
|
||||
{
|
||||
#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS
|
||||
m_resume_data_loaded = false;
|
||||
|
@ -700,6 +702,8 @@ namespace libtorrent
|
|||
get_handle()));
|
||||
}
|
||||
|
||||
state_updated();
|
||||
|
||||
set_state(torrent_status::downloading);
|
||||
|
||||
m_override_resume_data = true;
|
||||
|
@ -855,6 +859,7 @@ namespace libtorrent
|
|||
}
|
||||
m_apply_ip_filter = b;
|
||||
m_policy.ip_filter_updated();
|
||||
state_updated();
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
|
@ -1001,6 +1006,7 @@ namespace libtorrent
|
|||
|
||||
m_upload_mode = b;
|
||||
|
||||
state_updated();
|
||||
send_upload_only();
|
||||
|
||||
if (m_upload_mode)
|
||||
|
@ -2471,16 +2477,21 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
INVARIANT_CHECK;
|
||||
TORRENT_ASSERT(req.kind == tracker_request::scrape_request);
|
||||
|
||||
if (complete >= 0) m_complete = complete;
|
||||
if (incomplete >= 0) m_incomplete = incomplete;
|
||||
if (downloaders >= 0) m_downloaders = downloaders;
|
||||
|
||||
if (m_ses.m_alerts.should_post<scrape_reply_alert>())
|
||||
{
|
||||
m_ses.m_alerts.post_alert(scrape_reply_alert(
|
||||
get_handle(), m_incomplete, m_complete, req.url));
|
||||
}
|
||||
}
|
||||
if ((complete >= 0 && m_complete != complete)
|
||||
|| (incomplete >= 0 && m_incomplete != incomplete)
|
||||
|| (downloaders >= 0 && m_downloaders != downloaders))
|
||||
state_updated();
|
||||
|
||||
if (complete >= 0) m_complete = complete;
|
||||
if (incomplete >= 0) m_incomplete = incomplete;
|
||||
if (downloaders >= 0) m_downloaders = downloaders;
|
||||
|
||||
if (m_ses.m_alerts.should_post<scrape_reply_alert>())
|
||||
{
|
||||
m_ses.m_alerts.post_alert(scrape_reply_alert(
|
||||
get_handle(), m_incomplete, m_complete, req.url));
|
||||
}
|
||||
}
|
||||
|
||||
void torrent::tracker_response(
|
||||
tracker_request const& r
|
||||
|
@ -2673,6 +2684,8 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
++m_ses.m_boost_connections;
|
||||
}
|
||||
}
|
||||
|
||||
state_updated();
|
||||
}
|
||||
|
||||
ptime torrent::next_announce() const
|
||||
|
@ -3061,6 +3074,8 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
|
||||
TORRENT_ASSERT(!m_picker->have_piece(index));
|
||||
|
||||
state_updated();
|
||||
|
||||
// even though the piece passed the hash-check
|
||||
// it might still have failed being written to disk
|
||||
// if so, piece_picker::write_failed() has been
|
||||
|
@ -3176,6 +3191,7 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
, index));
|
||||
}
|
||||
|
||||
state_updated();
|
||||
m_need_save_resume_data = true;
|
||||
|
||||
remove_time_critical_piece(index, true);
|
||||
|
@ -3593,6 +3609,7 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
write_resume_data(*j.resume_data);
|
||||
alerts().post_alert(save_resume_data_alert(j.resume_data
|
||||
, get_handle()));
|
||||
state_updated();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3828,6 +3845,8 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
update_peer_interest(was_finished);
|
||||
remove_time_critical_pieces(pieces);
|
||||
}
|
||||
|
||||
state_updated();
|
||||
}
|
||||
|
||||
void torrent::piece_priorities(std::vector<int>* pieces) const
|
||||
|
@ -4178,6 +4197,7 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
TORRENT_ASSERT(m_num_uploads > 0);
|
||||
if (!c.send_choke()) return false;
|
||||
--m_num_uploads;
|
||||
state_updated();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -4194,6 +4214,7 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
if (m_num_uploads >= m_max_uploads && !optimistic) return false;
|
||||
if (!c.send_unchoke()) return false;
|
||||
++m_num_uploads;
|
||||
state_updated();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -5288,7 +5309,6 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
file_priority.clear();
|
||||
for (int i = 0, end(m_file_priority.size()); i < end; ++i)
|
||||
file_priority.push_back(m_file_priority[i]);
|
||||
|
||||
}
|
||||
|
||||
void torrent::get_full_peer_list(std::vector<peer_list_entry>& v) const
|
||||
|
@ -5846,6 +5866,8 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
|
||||
send_upload_only();
|
||||
|
||||
state_updated();
|
||||
|
||||
m_completed_time = time(0);
|
||||
|
||||
// disconnect all seeds
|
||||
|
@ -6294,7 +6316,10 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
void torrent::set_sequential_download(bool sd)
|
||||
{
|
||||
TORRENT_ASSERT(m_ses.is_network_thread());
|
||||
if (m_sequential_download == sd) return;
|
||||
m_sequential_download = sd;
|
||||
|
||||
state_updated();
|
||||
}
|
||||
|
||||
void torrent::queue_up()
|
||||
|
@ -6317,6 +6342,8 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
if (is_finished() && p != -1) return;
|
||||
if (p == m_sequence_number) return;
|
||||
|
||||
state_updated();
|
||||
|
||||
session_impl::torrent_map& torrents = m_ses.m_torrents;
|
||||
if (p >= 0 && m_sequence_number == -1)
|
||||
{
|
||||
|
@ -6386,6 +6413,7 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
TORRENT_ASSERT(m_ses.is_network_thread());
|
||||
TORRENT_ASSERT(limit >= -1);
|
||||
if (limit <= 0) limit = (std::numeric_limits<int>::max)();
|
||||
if (m_max_uploads != limit) state_updated();
|
||||
m_max_uploads = limit;
|
||||
}
|
||||
|
||||
|
@ -6394,6 +6422,7 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
TORRENT_ASSERT(m_ses.is_network_thread());
|
||||
TORRENT_ASSERT(limit >= -1);
|
||||
if (limit <= 0) limit = (std::numeric_limits<int>::max)();
|
||||
if (m_max_connections != limit) state_updated();
|
||||
m_max_connections = limit;
|
||||
|
||||
if (num_peers() > int(m_max_connections))
|
||||
|
@ -6446,6 +6475,8 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
TORRENT_ASSERT(m_ses.is_network_thread());
|
||||
TORRENT_ASSERT(limit >= -1);
|
||||
if (limit <= 0) limit = 0;
|
||||
if (m_bandwidth_channel[peer_connection::upload_channel].throttle() != limit)
|
||||
state_updated();
|
||||
m_bandwidth_channel[peer_connection::upload_channel].throttle(limit);
|
||||
}
|
||||
|
||||
|
@ -6462,6 +6493,8 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
TORRENT_ASSERT(m_ses.is_network_thread());
|
||||
TORRENT_ASSERT(limit >= -1);
|
||||
if (limit <= 0) limit = 0;
|
||||
if (m_bandwidth_channel[peer_connection::download_channel].throttle() != limit)
|
||||
state_updated();
|
||||
m_bandwidth_channel[peer_connection::download_channel].throttle(limit);
|
||||
}
|
||||
|
||||
|
@ -6502,6 +6535,8 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
m_error = error_code();
|
||||
m_error_file.clear();
|
||||
|
||||
state_updated();
|
||||
|
||||
// if we haven't downloaded the metadata from m_url, try again
|
||||
if (!m_url.empty() && !m_torrent_file->is_valid())
|
||||
{
|
||||
|
@ -6541,6 +6576,8 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
dequeue_torrent_check();
|
||||
set_state(torrent_status::queued_for_checking);
|
||||
}
|
||||
|
||||
state_updated();
|
||||
}
|
||||
|
||||
void torrent::auto_managed(bool a)
|
||||
|
@ -6552,6 +6589,8 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
bool checking_files = should_check_files();
|
||||
m_auto_managed = a;
|
||||
|
||||
state_updated();
|
||||
|
||||
// we need to save this new state as well
|
||||
m_need_save_resume_data = true;
|
||||
|
||||
|
@ -6665,6 +6704,7 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
m_need_save_resume_data = false;
|
||||
m_last_saved_resume = time(0);
|
||||
m_save_resume_flags = boost::uint8_t(flags);
|
||||
state_updated();
|
||||
|
||||
TORRENT_ASSERT(m_storage);
|
||||
if (m_state == torrent_status::queued_for_checking
|
||||
|
@ -6734,6 +6774,7 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
|
||||
// we need to save this new state
|
||||
m_need_save_resume_data = true;
|
||||
state_updated();
|
||||
|
||||
bool prev_graceful = m_graceful_pause_mode;
|
||||
m_graceful_pause_mode = graceful;
|
||||
|
@ -6765,6 +6806,8 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
}
|
||||
#endif
|
||||
|
||||
state_updated();
|
||||
|
||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING || defined TORRENT_LOGGING
|
||||
log_to_all_peers("PAUSING TORRENT");
|
||||
#endif
|
||||
|
@ -6926,6 +6969,8 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
if (alerts().should_post<torrent_resumed_alert>())
|
||||
alerts().post_alert(torrent_resumed_alert(get_handle()));
|
||||
|
||||
state_updated();
|
||||
|
||||
m_started = time_now();
|
||||
clear_error();
|
||||
start_announcing();
|
||||
|
@ -7155,6 +7200,9 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
// let the stats fade out to 0
|
||||
accumulator += m_stat;
|
||||
m_stat.second_tick(tick_interval_ms);
|
||||
// if the rate is 0, there's no update because of network transfers
|
||||
if (m_stat.low_pass_upload_rate() > 0 || m_stat.low_pass_download_rate() > 0)
|
||||
state_updated();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -7250,6 +7298,10 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
m_total_uploaded += m_stat.last_payload_uploaded();
|
||||
m_total_downloaded += m_stat.last_payload_downloaded();
|
||||
m_stat.second_tick(tick_interval_ms);
|
||||
|
||||
// if the rate is 0, there's no update because of network transfers
|
||||
if (m_stat.low_pass_upload_rate() > 0 || m_stat.low_pass_download_rate() > 0)
|
||||
state_updated();
|
||||
}
|
||||
|
||||
void torrent::recalc_share_mode()
|
||||
|
@ -7697,6 +7749,8 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
TORRENT_ASSERT(m_ses.is_network_thread());
|
||||
peer_id id(0);
|
||||
m_policy.add_peer(adr, id, source, 0);
|
||||
|
||||
state_updated();
|
||||
}
|
||||
|
||||
void torrent::async_verify_piece(int piece_index, boost::function<void(int)> const& f)
|
||||
|
@ -7944,6 +7998,8 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
m_ses.m_alerts.post_alert(state_changed_alert(get_handle(), s, (torrent_status::state_t)m_state));
|
||||
m_state = s;
|
||||
|
||||
state_updated();
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
for (extension_list_t::iterator i = m_extensions.begin()
|
||||
, end(m_extensions.end()); i != end; ++i)
|
||||
|
@ -7969,6 +8025,17 @@ ctx->set_verify_callback(verify_function, ec);
|
|||
}
|
||||
#endif
|
||||
|
||||
void torrent::state_updated()
|
||||
{
|
||||
// we're either not subscribing to this torrent, or
|
||||
// it has already been updated this round, no need to
|
||||
// add it to the list twice
|
||||
if (!m_state_subscription || m_in_state_updates) return;
|
||||
|
||||
m_ses.m_state_updates.push_back(shared_from_this());
|
||||
m_in_state_updates = true;
|
||||
}
|
||||
|
||||
void torrent::status(torrent_status* st, boost::uint32_t flags)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
|
Loading…
Reference in New Issue