forked from premiere/premiere-libtorrent
optimized memory usage for torrent objects
This commit is contained in:
parent
fc42dbd11f
commit
c050b22d8f
|
@ -110,6 +110,7 @@ void bind_session_settings()
|
|||
.def_readwrite("drop_skipped_requests", &session_settings::drop_skipped_requests)
|
||||
.def_readwrite("low_prio_disk", &session_settings::low_prio_disk)
|
||||
.def_readwrite("local_service_announce_interval", &session_settings::local_service_announce_interval)
|
||||
.def_readwrite("dht_announce_interval", &session_settings::dht_announce_interval)
|
||||
.def_readwrite("udp_tracker_token_expiry", &session_settings::udp_tracker_token_expiry)
|
||||
.def_readwrite("volatile_read_cache", &session_settings::volatile_read_cache)
|
||||
.def_readwrite("guided_read_cache", &session_settings::guided_read_cache)
|
||||
|
|
|
@ -3759,6 +3759,7 @@ session_settings
|
|||
|
||||
bool low_prio_disk;
|
||||
int local_service_announce_interval;
|
||||
int dht_announce_interval;
|
||||
|
||||
int udp_tracker_token_expiry;
|
||||
bool volatile_read_cache;
|
||||
|
@ -4275,6 +4276,10 @@ network announces for a torrent. By default, when local service
|
|||
discovery is enabled a torrent announces itself every 5 minutes.
|
||||
This interval is specified in seconds.
|
||||
|
||||
``dht_announce_interval`` is the number of seconds between announcing
|
||||
torrents to the distributed hash table (DHT). This is specified to
|
||||
be 15 minutes which is its default.
|
||||
|
||||
``udp_tracker_token_expiry`` is the number of seconds libtorrent
|
||||
will keep UDP tracker connection tokens around for. This is specified
|
||||
to be 60 seconds, and defaults to that. The higher this value is, the
|
||||
|
|
|
@ -90,6 +90,7 @@ nobase_include_HEADERS = \
|
|||
tracker_manager.hpp \
|
||||
udp_socket.hpp \
|
||||
udp_tracker_connection.hpp \
|
||||
union_endpoint.hpp \
|
||||
upnp.hpp \
|
||||
utf8.hpp \
|
||||
variant_stream.hpp \
|
||||
|
|
|
@ -196,6 +196,8 @@ namespace libtorrent
|
|||
|
||||
entry dht_state(mutex::scoped_lock& l) const;
|
||||
void maybe_update_udp_mapping(int nat, int local_port, int external_port);
|
||||
|
||||
void on_dht_announce(error_code const& e);
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
|
@ -697,6 +699,10 @@ namespace libtorrent
|
|||
|
||||
void on_receive_udp(error_code const& e
|
||||
, udp::endpoint const& ep, char const* buf, int len);
|
||||
|
||||
// this announce timer is used
|
||||
// by the DHT.
|
||||
deadline_timer m_dht_announce_timer;
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
|
@ -720,10 +726,20 @@ namespace libtorrent
|
|||
// 5 minutes)
|
||||
torrent_map::iterator m_next_lsd_torrent;
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
// torrents are announced on the DHT in a
|
||||
// round-robin fashion. All torrents are cycled through
|
||||
// within the DHT announce interval (which defaults to
|
||||
// 15 minutes)
|
||||
torrent_map::iterator m_next_dht_torrent;
|
||||
#endif
|
||||
|
||||
// this announce timer is used
|
||||
// by Local service discovery
|
||||
deadline_timer m_lsd_announce_timer;
|
||||
|
||||
tcp::resolver m_host_resolver;
|
||||
|
||||
// the index of the torrent that will be offered to
|
||||
// connect to a peer next time on_tick is called.
|
||||
// This implements a round robin.
|
||||
|
@ -745,6 +761,17 @@ namespace libtorrent
|
|||
// the number of send buffers that are allocated
|
||||
int m_buffer_allocations;
|
||||
#endif
|
||||
|
||||
// each second tick the timer takes a little
|
||||
// bit longer than one second to trigger. The
|
||||
// extra time it took is accumulated into this
|
||||
// counter. Every time it exceeds 1000, torrents
|
||||
// will tick their timers 2 seconds instead of one.
|
||||
// this keeps the timers more accurate over time
|
||||
// as a kind of "leap second" to adjust for the
|
||||
// accumulated error
|
||||
boost::uint16_t m_tick_residual;
|
||||
|
||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
|
||||
boost::shared_ptr<logger> create_log(std::string const& name
|
||||
, int instance, bool append = true);
|
||||
|
|
|
@ -75,7 +75,7 @@ namespace libtorrent
|
|||
none_t, dict_t, list_t, string_t, int_t
|
||||
};
|
||||
|
||||
lazy_entry() : m_type(none_t), m_begin(0), m_end(0)
|
||||
lazy_entry() : m_begin(0), m_end(0), m_type(none_t)
|
||||
{ m_data.start = 0; }
|
||||
|
||||
entry_type_t type() const { return m_type; }
|
||||
|
@ -179,7 +179,7 @@ namespace libtorrent
|
|||
lazy_entry* list_at(int i)
|
||||
{
|
||||
TORRENT_ASSERT(m_type == list_t);
|
||||
TORRENT_ASSERT(i < m_size);
|
||||
TORRENT_ASSERT(i < int(m_size));
|
||||
return &m_data.list[i];
|
||||
}
|
||||
lazy_entry const* list_at(int i) const
|
||||
|
@ -192,7 +192,7 @@ namespace libtorrent
|
|||
int list_size() const
|
||||
{
|
||||
TORRENT_ASSERT(m_type == list_t);
|
||||
return m_size;
|
||||
return int(m_size);
|
||||
}
|
||||
|
||||
// end points one byte passed last byte
|
||||
|
@ -223,17 +223,20 @@ namespace libtorrent
|
|||
void swap(lazy_entry& e)
|
||||
{
|
||||
using std::swap;
|
||||
swap(m_type, e.m_type);
|
||||
entry_type_t tmp1 = e.m_type;
|
||||
e.m_type = m_type;
|
||||
m_type = tmp1;
|
||||
boost::uint32_t tmp2 = e.m_capacity;
|
||||
e.m_capacity = m_capacity;
|
||||
m_capacity = tmp2;
|
||||
swap(m_data.start, e.m_data.start);
|
||||
swap(m_size, e.m_size);
|
||||
swap(m_capacity, e.m_capacity);
|
||||
swap(m_begin, e.m_begin);
|
||||
swap(m_end, e.m_end);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
entry_type_t m_type;
|
||||
union data_t
|
||||
{
|
||||
lazy_dict_entry* dict;
|
||||
|
@ -241,13 +244,15 @@ namespace libtorrent
|
|||
char const* start;
|
||||
} m_data;
|
||||
|
||||
int m_size; // if list or dictionary, the number of items
|
||||
int m_capacity; // if list or dictionary, allocated number of items
|
||||
// used for dictionaries and lists to record the range
|
||||
// in the original buffer they are based on
|
||||
char const* m_begin;
|
||||
char const* m_end;
|
||||
|
||||
boost::uint32_t m_size; // if list or dictionary, the number of items
|
||||
boost::uint32_t m_capacity:29; // if list or dictionary, allocated number of items
|
||||
entry_type_t m_type:3;
|
||||
|
||||
// non-copyable
|
||||
lazy_entry(lazy_entry const&);
|
||||
lazy_entry const& operator=(lazy_entry const&);
|
||||
|
|
|
@ -435,12 +435,12 @@ namespace libtorrent
|
|||
|
||||
peers_t m_peers;
|
||||
|
||||
torrent* m_torrent;
|
||||
|
||||
// since the peer list can grow too large
|
||||
// to scan all of it, start at this iterator
|
||||
int m_round_robin;
|
||||
|
||||
torrent* m_torrent;
|
||||
|
||||
// The number of peers in our peer list
|
||||
// that are connect candidates. i.e. they're
|
||||
// not already connected and they have not
|
||||
|
@ -460,7 +460,7 @@ namespace libtorrent
|
|||
// this state. Every time m_torrent->is_finished()
|
||||
// is different from this state, we need to
|
||||
// recalculate the connect candidates.
|
||||
bool m_finished;
|
||||
bool m_finished:1;
|
||||
};
|
||||
|
||||
inline policy::ipv4_peer::ipv4_peer(
|
||||
|
|
|
@ -191,6 +191,7 @@ namespace libtorrent
|
|||
, drop_skipped_requests(false)
|
||||
, low_prio_disk(true)
|
||||
, local_service_announce_interval(5 * 60)
|
||||
, dht_announce_interval(15 * 60)
|
||||
, udp_tracker_token_expiry(60)
|
||||
, volatile_read_cache(false)
|
||||
, guided_read_cache(true)
|
||||
|
@ -705,6 +706,10 @@ namespace libtorrent
|
|||
// torrents. Defaults to 5 minutes
|
||||
int local_service_announce_interval;
|
||||
|
||||
// number of seconds between DHT announces for
|
||||
// torrents. Defaults to 15 minutes
|
||||
int dht_announce_interval;
|
||||
|
||||
// the number of seconds a connection ID received
|
||||
// from a UDP tracker is valid for. This is specified
|
||||
// as 60 seconds
|
||||
|
|
|
@ -96,7 +96,7 @@ namespace libtorrent
|
|||
|
||||
namespace asio = boost::asio;
|
||||
#endif
|
||||
|
||||
|
||||
#if TORRENT_USE_IPV6
|
||||
struct v6only
|
||||
{
|
||||
|
|
|
@ -53,7 +53,7 @@ namespace libtorrent
|
|||
{
|
||||
friend class invariant_access;
|
||||
public:
|
||||
enum { history = 10 };
|
||||
enum { history = 5 };
|
||||
|
||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/bitfield.hpp"
|
||||
#include "libtorrent/aux_/session_impl.hpp"
|
||||
#include "libtorrent/deadline_timer.hpp"
|
||||
#include "libtorrent/union_endpoint.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -99,18 +100,21 @@ namespace libtorrent
|
|||
// http seeds are different from url seeds in the
|
||||
// protocol they use. http seeds follows the original
|
||||
// http seed spec. by John Hoffman
|
||||
enum type_t { url_seed, http_seed} type;
|
||||
|
||||
bool resolving;
|
||||
tcp::endpoint endpoint;
|
||||
enum type_t { url_seed, http_seed } type;
|
||||
|
||||
// if this is > now, we can't reconnect yet
|
||||
ptime retry;
|
||||
|
||||
// this indicates whether or not we're resolving the
|
||||
// hostname of this URL
|
||||
bool resolving;
|
||||
|
||||
tcp::endpoint endpoint;
|
||||
|
||||
peer_connection* connection;
|
||||
|
||||
web_seed_entry(std::string const& url_, type_t type_)
|
||||
: url(url_), type(type_), resolving(false)
|
||||
, retry(time_now()), connection(0) {}
|
||||
: url(url_), type(type_), retry(time_now()), resolving(false), connection(0) {}
|
||||
|
||||
bool operator==(web_seed_entry const& e) const
|
||||
{ return url == e.url && type == e.type; }
|
||||
|
@ -195,7 +199,7 @@ namespace libtorrent
|
|||
void read_piece(int piece);
|
||||
void on_disk_read_complete(int ret, disk_io_job const& j, peer_request r, read_piece_struct* rp);
|
||||
|
||||
storage_mode_t storage_mode() const { return m_storage_mode; }
|
||||
storage_mode_t storage_mode() const { return (storage_mode_t)m_storage_mode; }
|
||||
storage_interface* get_storage()
|
||||
{
|
||||
if (!m_owning_storage) return 0;
|
||||
|
@ -209,7 +213,7 @@ namespace libtorrent
|
|||
void abort();
|
||||
bool is_aborted() const { return m_abort; }
|
||||
|
||||
torrent_status::state_t state() const { return m_state; }
|
||||
torrent_status::state_t state() const { return (torrent_status::state_t)m_state; }
|
||||
void set_state(torrent_status::state_t s);
|
||||
|
||||
session_settings const& settings() const;
|
||||
|
@ -294,7 +298,7 @@ namespace libtorrent
|
|||
void file_progress(std::vector<size_type>& fp, int flags = 0) const;
|
||||
|
||||
void use_interface(const char* net_interface);
|
||||
tcp::endpoint const& get_interface() const { return m_net_interface; }
|
||||
tcp::endpoint get_interface() const { return m_net_interface; }
|
||||
|
||||
void connect_to_url_seed(std::list<web_seed_entry>::iterator url);
|
||||
bool connect_to_peer(policy::peer* peerinfo);
|
||||
|
@ -446,10 +450,10 @@ namespace libtorrent
|
|||
void announce_with_tracker(tracker_request::event_t e
|
||||
= tracker_request::none
|
||||
, address const& bind_interface = address_v4::any());
|
||||
ptime const& last_scrape() const { return m_last_scrape; }
|
||||
int seconds_since_last_scrape() const { return m_last_scrape; }
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
void force_dht_announce();
|
||||
void dht_announce();
|
||||
#endif
|
||||
|
||||
// sets the username and password that will be sent to
|
||||
|
@ -458,7 +462,7 @@ namespace libtorrent
|
|||
|
||||
// the tcp::endpoint of the tracker that we managed to
|
||||
// announce ourself at the last time we tried to announce
|
||||
const tcp::endpoint& current_tracker() const;
|
||||
tcp::endpoint current_tracker() const;
|
||||
|
||||
announce_entry* find_tracker(tracker_request const& r);
|
||||
|
||||
|
@ -554,7 +558,7 @@ namespace libtorrent
|
|||
#endif
|
||||
}
|
||||
|
||||
int block_size() const { TORRENT_ASSERT(m_block_size > 0); return m_block_size; }
|
||||
int block_size() const { TORRENT_ASSERT(m_block_size_shift > 0); return 1 << m_block_size_shift; }
|
||||
peer_request to_req(piece_block const& p);
|
||||
|
||||
void disconnect_all(error_code const& ec);
|
||||
|
@ -781,20 +785,28 @@ namespace libtorrent
|
|||
void queue_torrent_check();
|
||||
void dequeue_torrent_check();
|
||||
|
||||
void parse_response(const entry& e, std::vector<peer_entry>& peer_list);
|
||||
|
||||
void update_tracker_timer();
|
||||
|
||||
static void on_tracker_announce_disp(boost::weak_ptr<torrent> p
|
||||
, error_code const& e);
|
||||
|
||||
void on_tracker_announce();
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
static void on_dht_announce_response_disp(boost::weak_ptr<torrent> t
|
||||
, std::vector<tcp::endpoint> const& peers);
|
||||
void on_dht_announce_response(std::vector<tcp::endpoint> const& peers);
|
||||
bool should_announce_dht() const;
|
||||
#endif
|
||||
|
||||
void remove_time_critical_piece(int piece, bool finished = false);
|
||||
void remove_time_critical_pieces(std::vector<int> const& priority);
|
||||
void request_time_critical_pieces();
|
||||
|
||||
policy m_policy;
|
||||
|
||||
// total time we've been available on this torrent
|
||||
// does not count when the torrent is stopped or paused
|
||||
time_duration m_active_time;
|
||||
|
||||
// total time we've been finished with this torrent
|
||||
// does not count when the torrent is stopped or paused
|
||||
time_duration m_finished_time;
|
||||
|
||||
// total time we've been available as a seed on this torrent
|
||||
// does not count when the torrent is stopped or paused
|
||||
time_duration m_seeding_time;
|
||||
|
||||
// all time totals of uploaded and downloaded payload
|
||||
// stored in resume data
|
||||
size_type m_total_uploaded;
|
||||
|
@ -806,17 +818,8 @@ namespace libtorrent
|
|||
// recently was started, to avoid oscillation
|
||||
ptime m_started;
|
||||
|
||||
// the last time we initiated a scrape request to
|
||||
// one of the trackers in this torrent
|
||||
ptime m_last_scrape;
|
||||
|
||||
// the time when we switched to upload mode
|
||||
ptime m_upload_mode_time;
|
||||
|
||||
boost::intrusive_ptr<torrent_info> m_torrent_file;
|
||||
|
||||
void parse_response(const entry& e, std::vector<peer_entry>& peer_list);
|
||||
|
||||
// if this pointer is 0, the torrent is in
|
||||
// a state where the metadata hasn't been
|
||||
// received yet.
|
||||
|
@ -859,40 +862,9 @@ namespace libtorrent
|
|||
extension_list_t m_extensions;
|
||||
#endif
|
||||
|
||||
// used to resolve the names of web seeds
|
||||
mutable tcp::resolver m_host_resolver;
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
// this announce timer is used both
|
||||
// by Local service discovery and
|
||||
// by the DHT.
|
||||
deadline_timer m_dht_announce_timer;
|
||||
#endif
|
||||
|
||||
// used for tracker announces
|
||||
deadline_timer m_tracker_timer;
|
||||
|
||||
void update_tracker_timer();
|
||||
|
||||
static void on_tracker_announce_disp(boost::weak_ptr<torrent> p
|
||||
, error_code const& e);
|
||||
|
||||
void on_tracker_announce();
|
||||
|
||||
void dht_announce();
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
static void on_dht_announce_response_disp(boost::weak_ptr<torrent> t
|
||||
, std::vector<tcp::endpoint> const& peers);
|
||||
void on_dht_announce_response(std::vector<tcp::endpoint> const& peers);
|
||||
bool should_announce_dht() const;
|
||||
void on_dht_announce(error_code const& e);
|
||||
|
||||
// the time when the DHT was last announced of our
|
||||
// presence on this torrent
|
||||
ptime m_last_dht_announce;
|
||||
#endif
|
||||
|
||||
// this is the upload and download statistics for the whole torrent.
|
||||
// it's updated from all its peers once every second.
|
||||
libtorrent::stat m_stat;
|
||||
|
@ -933,32 +905,15 @@ namespace libtorrent
|
|||
{ return deadline < rhs.deadline; }
|
||||
};
|
||||
|
||||
void remove_time_critical_piece(int piece, bool finished = false);
|
||||
void remove_time_critical_pieces(std::vector<int> const& priority);
|
||||
void request_time_critical_pieces();
|
||||
|
||||
// this list is sorted by time_critical_piece::deadline
|
||||
std::list<time_critical_piece> m_time_critical_pieces;
|
||||
|
||||
// the average time it takes to download one time critical piece
|
||||
time_duration m_average_piece_time;
|
||||
// the average piece download time deviation
|
||||
time_duration m_piece_time_deviation;
|
||||
|
||||
// the number of bytes that has been
|
||||
// downloaded that failed the hash-test
|
||||
size_type m_total_failed_bytes;
|
||||
size_type m_total_redundant_bytes;
|
||||
|
||||
// the number of bytes of padding files
|
||||
int m_padding;
|
||||
|
||||
std::string m_username;
|
||||
std::string m_password;
|
||||
|
||||
// the network interface all outgoing connections
|
||||
// are opened through
|
||||
tcp::endpoint m_net_interface;
|
||||
union_endpoint m_net_interface;
|
||||
|
||||
std::string m_save_path;
|
||||
|
||||
|
@ -967,18 +922,6 @@ namespace libtorrent
|
|||
// is only used in seed mode (when m_seed_mode
|
||||
// is true)
|
||||
bitfield m_verified;
|
||||
// m_num_verified = m_verified.count()
|
||||
int m_num_verified;
|
||||
|
||||
// free download we have got that hasn't
|
||||
// been distributed yet.
|
||||
size_type m_available_free_upload;
|
||||
|
||||
// determines the storage state for this torrent.
|
||||
storage_mode_t m_storage_mode;
|
||||
|
||||
// the state of this torrent (queued, checking, downloading, etc.)
|
||||
torrent_status::state_t m_state;
|
||||
|
||||
// set if there's an error on this torrent
|
||||
error_code m_error;
|
||||
|
@ -995,114 +938,75 @@ namespace libtorrent
|
|||
// longer be used and will be reset
|
||||
boost::scoped_ptr<std::string> m_name;
|
||||
|
||||
storage_constructor_type m_storage_constructor;
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
// this is SHA1("req2" + info-hash), used for
|
||||
// encrypted hand shakes
|
||||
sha1_hash m_obfuscated_hash;
|
||||
#endif
|
||||
session_settings const& m_settings;
|
||||
|
||||
storage_constructor_type m_storage_constructor;
|
||||
|
||||
int m_progress_ppm;
|
||||
|
||||
// the upload/download ratio that each peer
|
||||
// tries to maintain.
|
||||
// 0 is infinite
|
||||
float m_ratio;
|
||||
|
||||
// the maximum number of uploads for this torrent
|
||||
int m_max_uploads;
|
||||
// free download we have got that hasn't
|
||||
// been distributed yet.
|
||||
boost::uint32_t m_available_free_upload;
|
||||
|
||||
// the number of unchoked peers in this torrent
|
||||
int m_num_uploads;
|
||||
// the average time it takes to download one time critical piece
|
||||
boost::uint32_t m_average_piece_time;
|
||||
// the average piece download time deviation
|
||||
boost::uint32_t m_piece_time_deviation;
|
||||
|
||||
// the maximum number of connections for this torrent
|
||||
int m_max_connections;
|
||||
// the number of bytes that has been
|
||||
// downloaded that failed the hash-test
|
||||
boost::uint32_t m_total_failed_bytes;
|
||||
boost::uint32_t m_total_redundant_bytes;
|
||||
|
||||
// the size of a request block
|
||||
// each piece is divided into these
|
||||
// blocks when requested
|
||||
int m_block_size;
|
||||
// ==============================
|
||||
// The following members are specifically
|
||||
// ordered to make the 24 bit members
|
||||
// properly 32 bit aligned by inserting
|
||||
// 8 bits after each one
|
||||
// ==============================
|
||||
|
||||
// -----------------------------
|
||||
// DATA FROM TRACKER RESPONSE
|
||||
// the number of seconds we've been in upload mode
|
||||
unsigned int m_upload_mode_time:24;
|
||||
|
||||
// the scrape data from the tracker response, this
|
||||
// is optional and may be -1.
|
||||
int m_complete;
|
||||
int m_incomplete;
|
||||
// the state of this torrent (queued, checking, downloading, etc.)
|
||||
unsigned int m_state:3;
|
||||
|
||||
#ifdef TORRENT_DEBUG
|
||||
// this is the amount downloaded when this torrent
|
||||
// is started. i.e.
|
||||
// total_done - m_initial_done <= total_payload_download
|
||||
size_type m_initial_done;
|
||||
#endif
|
||||
// this is the deficit counter in the Deficit Round Robin
|
||||
// used to determine which torrent gets the next
|
||||
// connection attempt. See:
|
||||
// http://www.ecs.umass.edu/ece/wolf/courses/ECE697J/papers/DRR.pdf
|
||||
// The quanta assigned to each torrent depends on the torrents
|
||||
// priority, whether it's a seed and the number of connected
|
||||
// peers it has. This has the effect that some torrents
|
||||
// will have more connection attempts than other. Each
|
||||
// connection attempt costs 100 points from the deficit
|
||||
// counter. points are deducted in try_connect_peer and
|
||||
// increased in give_connect_points. Outside of the
|
||||
// torrent object, these points are called connect_points.
|
||||
int m_deficit_counter;
|
||||
// determines the storage state for this torrent.
|
||||
unsigned int m_storage_mode:2;
|
||||
|
||||
// the sequence number for this torrent, this is a
|
||||
// monotonically increasing number for each added torrent
|
||||
boost::int16_t m_sequence_number;
|
||||
// this is true while tracker announcing is enabled
|
||||
// is is disabled while paused and checking files
|
||||
bool m_announcing:1;
|
||||
|
||||
// this is true while the tracker deadline timer
|
||||
// is in use. i.e. one or more trackers are waiting
|
||||
// for a reannounce
|
||||
bool m_waiting_tracker:1;
|
||||
|
||||
// this means we haven't verified the file content
|
||||
// of the files we're seeding. the m_verified bitfield
|
||||
// indicates which pieces have been verified and which
|
||||
// haven't
|
||||
bool m_seed_mode:1;
|
||||
|
||||
// total time we've been available on this torrent
|
||||
// does not count when the torrent is stopped or paused
|
||||
// in seconds
|
||||
unsigned int m_active_time:24;
|
||||
|
||||
// the index to the last tracker that worked
|
||||
boost::int8_t m_last_working_tracker;
|
||||
|
||||
// the number of connection attempts that has
|
||||
// failed in a row, this is currently used to
|
||||
// determine the timeout until next try.
|
||||
boost::int8_t m_failed_trackers;
|
||||
|
||||
// this is a counter that is decreased every
|
||||
// second, and when it reaches 0, the policy::pulse()
|
||||
// is called and the time scaler is reset to 10.
|
||||
boost::int8_t m_time_scaler;
|
||||
|
||||
// this is the priority of the torrent. The higher
|
||||
// the value is, the more bandwidth is assigned to
|
||||
// the torrent's peers
|
||||
boost::uint8_t m_priority;
|
||||
|
||||
// is set to true when the torrent has
|
||||
// been aborted.
|
||||
bool m_abort:1;
|
||||
|
||||
// is true if this torrent has been paused
|
||||
bool m_paused:1;
|
||||
|
||||
// set to true when this torrent may not download anything
|
||||
bool m_upload_mode:1;
|
||||
|
||||
// if this is true, libtorrent may pause and resume
|
||||
// this torrent depending on queuing rules. Torrents
|
||||
// started with auto_managed flag set may be added in
|
||||
// a paused state in case there are no available
|
||||
// slots.
|
||||
bool m_auto_managed:1;
|
||||
|
||||
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
||||
// this is true while there is a country
|
||||
// resolution in progress. To avoid flodding
|
||||
// the DNS request queue, only one ip is resolved
|
||||
// at a time.
|
||||
mutable bool m_resolving_country:1;
|
||||
|
||||
// this is true if the user has enabled
|
||||
// country resolution in this torrent
|
||||
bool m_resolve_countries:1;
|
||||
#endif
|
||||
// total time we've been finished with this torrent
|
||||
// does not count when the torrent is stopped or paused
|
||||
unsigned int m_finished_time:24;
|
||||
|
||||
// in case the piece picker hasn't been constructed
|
||||
// when this settings is set, this variable will keep
|
||||
|
@ -1129,6 +1033,61 @@ namespace libtorrent
|
|||
// torrent.
|
||||
bool m_super_seeding:1;
|
||||
|
||||
// this is set when we don't want to load seed_mode,
|
||||
// paused or auto_managed from the resume data
|
||||
bool m_override_resume_data:1;
|
||||
|
||||
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
||||
// this is true while there is a country
|
||||
// resolution in progress. To avoid flodding
|
||||
// the DNS request queue, only one ip is resolved
|
||||
// at a time.
|
||||
mutable bool m_resolving_country:1;
|
||||
|
||||
// this is true if the user has enabled
|
||||
// country resolution in this torrent
|
||||
bool m_resolve_countries:1;
|
||||
#else
|
||||
unsigned int m_dummy_padding_bits_to_align:2;
|
||||
#endif
|
||||
// TODO: Add new bools here!
|
||||
unsigned int m_dummy_padding_bit_to_alignt:1;
|
||||
|
||||
// total time we've been available as a seed on this torrent
|
||||
// does not count when the torrent is stopped or paused
|
||||
unsigned int m_seeding_time:24;
|
||||
|
||||
// this is a counter that is decreased every
|
||||
// second, and when it reaches 0, the policy::pulse()
|
||||
// is called and the time scaler is reset to 10.
|
||||
boost::int8_t m_time_scaler;
|
||||
|
||||
// the maximum number of uploads for this torrent
|
||||
unsigned int m_max_uploads:24;
|
||||
|
||||
// this is the deficit counter in the Deficit Round Robin
|
||||
// used to determine which torrent gets the next
|
||||
// connection attempt. See:
|
||||
// http://www.ecs.umass.edu/ece/wolf/courses/ECE697J/papers/DRR.pdf
|
||||
// The quanta assigned to each torrent depends on the torrents
|
||||
// priority, whether it's a seed and the number of connected
|
||||
// peers it has. This has the effect that some torrents
|
||||
// will have more connection attempts than other. Each
|
||||
// connection attempt costs 100 points from the deficit
|
||||
// counter. points are deducted in try_connect_peer and
|
||||
// increased in give_connect_points. Outside of the
|
||||
// torrent object, these points are called connect_points.
|
||||
boost::uint8_t m_deficit_counter;
|
||||
|
||||
// the number of unchoked peers in this torrent
|
||||
unsigned int m_num_uploads:24;
|
||||
|
||||
// the size of a request block
|
||||
// each piece is divided into these
|
||||
// blocks when requested. The block size is
|
||||
// 1 << m_block_size_shift
|
||||
unsigned int m_block_size_shift:5;
|
||||
|
||||
// is set to true every time there is an incoming
|
||||
// connection to this torrent
|
||||
bool m_has_incoming:1;
|
||||
|
@ -1142,24 +1101,56 @@ namespace libtorrent
|
|||
// checking queue in the session
|
||||
bool m_queued_for_checking:1;
|
||||
|
||||
// this is true while tracker announcing is enabled
|
||||
// is is disabled while paused and checking files
|
||||
bool m_announcing:1;
|
||||
// the maximum number of connections for this torrent
|
||||
unsigned int m_max_connections:24;
|
||||
|
||||
// this is true while the tracker deadline timer
|
||||
// is in use. i.e. one or more trackers are waiting
|
||||
// for a reannounce
|
||||
bool m_waiting_tracker:1;
|
||||
// the number of bytes of padding files
|
||||
unsigned int m_padding:24;
|
||||
|
||||
// this means we haven't verified the file content
|
||||
// of the files we're seeding. the m_verified bitfield
|
||||
// indicates which pieces have been verified and which
|
||||
// haven't
|
||||
bool m_seed_mode:1;
|
||||
// the sequence number for this torrent, this is a
|
||||
// monotonically increasing number for each added torrent
|
||||
boost::int16_t m_sequence_number;
|
||||
|
||||
// this is set when we don't want to load seed_mode,
|
||||
// paused or auto_managed from the resume data
|
||||
bool m_override_resume_data:1;
|
||||
// the scrape data from the tracker response, this
|
||||
// is optional and may be 0xffffff
|
||||
unsigned int m_complete:24;
|
||||
|
||||
// this is the priority of the torrent. The higher
|
||||
// the value is, the more bandwidth is assigned to
|
||||
// the torrent's peers
|
||||
boost::uint8_t m_priority;
|
||||
|
||||
// the scrape data from the tracker response, this
|
||||
// is optional and may be 0xffffff
|
||||
unsigned int m_incomplete:24;
|
||||
|
||||
// progress parts per million (the number of
|
||||
// millionths of completeness)
|
||||
unsigned int m_progress_ppm:20;
|
||||
|
||||
// is set to true when the torrent has
|
||||
// been aborted.
|
||||
bool m_abort:1;
|
||||
|
||||
// is true if this torrent has been paused
|
||||
bool m_paused:1;
|
||||
|
||||
// set to true when this torrent may not download anything
|
||||
bool m_upload_mode:1;
|
||||
|
||||
// if this is true, libtorrent may pause and resume
|
||||
// this torrent depending on queuing rules. Torrents
|
||||
// started with auto_managed flag set may be added in
|
||||
// a paused state in case there are no available
|
||||
// slots.
|
||||
bool m_auto_managed:1;
|
||||
|
||||
// m_num_verified = m_verified.count()
|
||||
boost::uint16_t m_num_verified;
|
||||
|
||||
// the number of seconds since the last scrape request to
|
||||
// one of the trackers in this torrent
|
||||
boost::uint16_t m_last_scrape;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/connection_queue.hpp"
|
||||
#include "libtorrent/intrusive_ptr_base.hpp"
|
||||
#include "libtorrent/size_type.hpp"
|
||||
#include "libtorrent/union_endpoint.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -141,7 +142,7 @@ namespace libtorrent
|
|||
, const std::string& description
|
||||
, int retry_interval) = 0;
|
||||
|
||||
tcp::endpoint m_tracker_address;
|
||||
union_endpoint m_tracker_address;
|
||||
|
||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
|
||||
virtual void debug_log(const std::string& line) = 0;
|
||||
|
|
|
@ -203,7 +203,7 @@ namespace libtorrent
|
|||
lazy_dict_entry* tmp = new (std::nothrow) lazy_dict_entry[capacity];
|
||||
if (tmp == 0) return 0;
|
||||
std::memcpy(tmp, m_data.dict, sizeof(lazy_dict_entry) * m_size);
|
||||
for (int i = 0; i < m_size; ++i) m_data.dict[i].val.release();
|
||||
for (int i = 0; i < int(m_size); ++i) m_data.dict[i].val.release();
|
||||
delete[] m_data.dict;
|
||||
m_data.dict = tmp;
|
||||
m_capacity = capacity;
|
||||
|
@ -262,7 +262,7 @@ namespace libtorrent
|
|||
std::pair<std::string, lazy_entry const*> lazy_entry::dict_at(int i) const
|
||||
{
|
||||
TORRENT_ASSERT(m_type == dict_t);
|
||||
TORRENT_ASSERT(i < m_size);
|
||||
TORRENT_ASSERT(i < int(m_size));
|
||||
lazy_dict_entry const& e = m_data.dict[i];
|
||||
return std::make_pair(std::string(e.name, e.val.m_begin - e.name), &e.val);
|
||||
}
|
||||
|
@ -319,7 +319,7 @@ namespace libtorrent
|
|||
lazy_entry* lazy_entry::dict_find(char const* name)
|
||||
{
|
||||
TORRENT_ASSERT(m_type == dict_t);
|
||||
for (int i = 0; i < m_size; ++i)
|
||||
for (int i = 0; i < int(m_size); ++i)
|
||||
{
|
||||
lazy_dict_entry& e = m_data.dict[i];
|
||||
if (string_equal(name, e.name, e.val.m_begin - e.name))
|
||||
|
@ -345,7 +345,7 @@ namespace libtorrent
|
|||
lazy_entry* tmp = new (std::nothrow) lazy_entry[capacity];
|
||||
if (tmp == 0) return 0;
|
||||
std::memcpy(tmp, m_data.list, sizeof(lazy_entry) * m_size);
|
||||
for (int i = 0; i < m_size; ++i) m_data.list[i].release();
|
||||
for (int i = 0; i < int(m_size); ++i) m_data.list[i].release();
|
||||
delete[] m_data.list;
|
||||
m_data.list = tmp;
|
||||
m_capacity = capacity;
|
||||
|
|
|
@ -1335,7 +1335,7 @@ namespace libtorrent
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_suggested_pieces.size() > m_ses.m_settings.max_suggest_pieces)
|
||||
if (int(m_suggested_pieces.size()) > m_ses.m_settings.max_suggest_pieces)
|
||||
m_suggested_pieces.erase(m_suggested_pieces.begin());
|
||||
|
||||
m_suggested_pieces.push_back(index);
|
||||
|
@ -3520,7 +3520,7 @@ namespace libtorrent
|
|||
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||
assert(t);
|
||||
|
||||
for (int i = 0; i < m_have_piece.size(); ++i)
|
||||
for (int i = 0; i < int(m_have_piece.size()); ++i)
|
||||
{
|
||||
if (m_have_piece[i] || !t->have_piece(i)) continue;
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
|
@ -4546,7 +4546,7 @@ namespace libtorrent
|
|||
(*m_logger) << "read " << bytes_transferred << " bytes\n";
|
||||
#endif
|
||||
// correct the dl quota usage, if not all of the buffer was actually read
|
||||
TORRENT_ASSERT(bytes_transferred <= m_quota[download_channel]);
|
||||
TORRENT_ASSERT(int(bytes_transferred) <= m_quota[download_channel]);
|
||||
m_quota[download_channel] -= bytes_transferred;
|
||||
|
||||
if (m_disconnecting)
|
||||
|
@ -4576,7 +4576,7 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(m_statistics.last_protocol_downloaded() - cur_protocol_dl >= 0);
|
||||
size_type stats_diff = m_statistics.last_payload_downloaded() - cur_payload_dl +
|
||||
m_statistics.last_protocol_downloaded() - cur_protocol_dl;
|
||||
TORRENT_ASSERT(stats_diff == bytes_transferred);
|
||||
TORRENT_ASSERT(stats_diff == int(bytes_transferred));
|
||||
#endif
|
||||
|
||||
TORRENT_ASSERT(m_packet_size > 0);
|
||||
|
@ -4860,7 +4860,7 @@ namespace libtorrent
|
|||
|
||||
m_channel_state[upload_channel] = peer_info::bw_idle;
|
||||
|
||||
TORRENT_ASSERT(bytes_transferred <= m_quota[upload_channel]);
|
||||
TORRENT_ASSERT(int(bytes_transferred) <= m_quota[upload_channel]);
|
||||
m_quota[upload_channel] -= bytes_transferred;
|
||||
|
||||
m_statistics.trancieve_ip_packet(bytes_transferred, m_remote.address().is_v6());
|
||||
|
@ -4894,7 +4894,7 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(m_statistics.last_protocol_uploaded() - cur_protocol_ul >= 0);
|
||||
size_type stats_diff = m_statistics.last_payload_uploaded() - cur_payload_ul
|
||||
+ m_statistics.last_protocol_uploaded() - cur_protocol_ul;
|
||||
TORRENT_ASSERT(stats_diff == bytes_transferred);
|
||||
TORRENT_ASSERT(stats_diff == int(bytes_transferred));
|
||||
#endif
|
||||
|
||||
fill_send_buffer();
|
||||
|
|
|
@ -289,8 +289,8 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
policy::policy(torrent* t)
|
||||
: m_round_robin(0)
|
||||
, m_torrent(t)
|
||||
: m_torrent(t)
|
||||
, m_round_robin(0)
|
||||
, m_num_connect_candidates(0)
|
||||
, m_num_seeds(0)
|
||||
, m_finished(false)
|
||||
|
|
|
@ -453,9 +453,12 @@ namespace aux {
|
|||
, m_external_udp_port(0)
|
||||
, m_dht_socket(m_io_service, bind(&session_impl::on_receive_udp, this, _1, _2, _3, _4)
|
||||
, m_half_open)
|
||||
, m_dht_announce_timer(m_io_service)
|
||||
#endif
|
||||
, m_timer(m_io_service)
|
||||
, m_lsd_announce_timer(m_io_service)
|
||||
, m_host_resolver(m_io_service)
|
||||
, m_tick_residual(0)
|
||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
|
||||
, m_logpath(logpath)
|
||||
#endif
|
||||
|
@ -466,6 +469,9 @@ namespace aux {
|
|||
, m_total_failed_bytes(0)
|
||||
, m_total_redundant_bytes(0)
|
||||
{
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
m_next_dht_torrent = m_torrents.begin();
|
||||
#endif
|
||||
m_next_lsd_torrent = m_torrents.begin();
|
||||
m_next_connect_torrent = m_torrents.begin();
|
||||
|
||||
|
@ -507,6 +513,7 @@ namespace aux {
|
|||
#define PRINT_SIZEOF(x) (*m_logger) << "sizeof(" #x "): " << sizeof(x) << "\n";
|
||||
#define PRINT_OFFSETOF(x, y) (*m_logger) << " offsetof(" #x "," #y "): " << offsetof(x, y) << "\n";
|
||||
|
||||
PRINT_SIZEOF(union_endpoint)
|
||||
PRINT_SIZEOF(request_callback)
|
||||
PRINT_SIZEOF(stat)
|
||||
PRINT_SIZEOF(bandwidth_channel)
|
||||
|
@ -621,6 +628,14 @@ namespace aux {
|
|||
m_lsd_announce_timer.async_wait(
|
||||
bind(&session_impl::on_lsd_announce, this, _1));
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
delay = (std::max)(m_settings.dht_announce_interval
|
||||
/ (std::max)(int(m_torrents.size()), 1), 1);
|
||||
m_dht_announce_timer.expires_from_now(seconds(delay), ec);
|
||||
m_dht_announce_timer.async_wait(
|
||||
bind(&session_impl::on_dht_announce, this, _1));
|
||||
#endif
|
||||
|
||||
m_thread.reset(new thread(boost::bind(&session_impl::main_thread, this)));
|
||||
}
|
||||
|
||||
|
@ -929,6 +944,7 @@ namespace aux {
|
|||
#ifndef TORRENT_DISABLE_DHT
|
||||
if (m_dht) m_dht->stop();
|
||||
m_dht_socket.close();
|
||||
m_dht_announce_timer.cancel(ec);
|
||||
#endif
|
||||
m_timer.cancel(ec);
|
||||
m_lsd_announce_timer.cancel(ec);
|
||||
|
@ -1086,6 +1102,18 @@ namespace aux {
|
|||
m_unchoke_time_scaler = 0;
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
if (m_settings.dht_announce_interval != s.dht_announce_interval)
|
||||
{
|
||||
error_code ec;
|
||||
int delay = (std::max)(s.dht_announce_interval
|
||||
/ (std::max)(int(m_torrents.size()), 1), 1);
|
||||
m_dht_announce_timer.expires_from_now(seconds(delay), ec);
|
||||
m_dht_announce_timer.async_wait(
|
||||
bind(&session_impl::on_dht_announce, this, _1));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_settings.local_service_announce_interval != s.local_service_announce_interval)
|
||||
{
|
||||
error_code ec;
|
||||
|
@ -1745,6 +1773,7 @@ namespace aux {
|
|||
|
||||
int tick_interval_ms = total_milliseconds(now - m_last_second_tick);
|
||||
m_last_second_tick = now;
|
||||
m_tick_residual += tick_interval_ms - 1000;
|
||||
|
||||
int session_time = total_seconds(now - m_created);
|
||||
if (session_time > 65000)
|
||||
|
@ -1884,7 +1913,8 @@ namespace aux {
|
|||
{
|
||||
++num_paused_auto_managed;
|
||||
if (least_recently_scraped == m_torrents.end()
|
||||
|| least_recently_scraped->second->last_scrape() > t.last_scrape())
|
||||
|| least_recently_scraped->second->seconds_since_last_scrape()
|
||||
< t.seconds_since_last_scrape())
|
||||
{
|
||||
least_recently_scraped = i;
|
||||
}
|
||||
|
@ -2191,9 +2221,36 @@ namespace aux {
|
|||
}
|
||||
}
|
||||
|
||||
while (m_tick_residual >= 1000) m_tick_residual -= 1000;
|
||||
// m_peer_pool.release_memory();
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
|
||||
void session_impl::on_dht_announce(error_code const& e)
|
||||
{
|
||||
if (e) return;
|
||||
|
||||
mutex::scoped_lock l(m_mutex);
|
||||
if (m_abort) return;
|
||||
|
||||
// announce to DHT every 15 minutes
|
||||
int delay = (std::max)(m_settings.dht_announce_interval
|
||||
/ (std::max)(int(m_torrents.size()), 1), 1);
|
||||
error_code ec;
|
||||
m_dht_announce_timer.expires_from_now(seconds(delay), ec);
|
||||
m_dht_announce_timer.async_wait(
|
||||
bind(&session_impl::on_dht_announce, this, _1));
|
||||
|
||||
if (m_next_dht_torrent == m_torrents.end())
|
||||
m_next_dht_torrent = m_torrents.begin();
|
||||
m_next_dht_torrent->second->dht_announce();
|
||||
++m_next_dht_torrent;
|
||||
if (m_next_dht_torrent == m_torrents.end())
|
||||
m_next_dht_torrent = m_torrents.begin();
|
||||
}
|
||||
#endif
|
||||
|
||||
void session_impl::on_lsd_announce(error_code const& e)
|
||||
{
|
||||
if (e) return;
|
||||
|
@ -2895,6 +2952,10 @@ namespace aux {
|
|||
|
||||
#ifdef TORRENT_DEBUG
|
||||
sha1_hash i_hash = t.torrent_file().info_hash();
|
||||
#endif
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
if (i == m_next_dht_torrent)
|
||||
++m_next_dht_torrent;
|
||||
#endif
|
||||
if (i == m_next_lsd_torrent)
|
||||
++m_next_lsd_torrent;
|
||||
|
@ -2904,6 +2965,10 @@ namespace aux {
|
|||
t.set_queue_position(-1);
|
||||
m_torrents.erase(i);
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
if (m_next_dht_torrent == m_torrents.end())
|
||||
m_next_dht_torrent = m_torrents.begin();
|
||||
#endif
|
||||
if (m_next_lsd_torrent == m_torrents.end())
|
||||
m_next_lsd_torrent = m_torrents.begin();
|
||||
if (m_next_connect_torrent == m_torrents.end())
|
||||
|
@ -3195,7 +3260,7 @@ namespace aux {
|
|||
for (torrent_map::const_iterator i = m_torrents.begin()
|
||||
, end(m_torrents.end()); i != end; ++i)
|
||||
{
|
||||
i->second->force_dht_announce();
|
||||
i->second->dht_announce();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
470
src/torrent.cpp
470
src/torrent.cpp
File diff suppressed because it is too large
Load Diff
|
@ -667,7 +667,7 @@ namespace libtorrent
|
|||
void torrent_handle::force_dht_announce() const
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
TORRENT_FORWARD(force_dht_announce());
|
||||
TORRENT_FORWARD(dht_announce());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ namespace libtorrent
|
|||
void trim_path_element(std::string& path_element)
|
||||
{
|
||||
const int max_path_len = TORRENT_MAX_PATH;
|
||||
if (path_element.size() > max_path_len)
|
||||
if (int(path_element.size()) > max_path_len)
|
||||
{
|
||||
// truncate filenames that are too long. But keep extensions!
|
||||
std::string ext = extension(path_element);
|
||||
|
|
Loading…
Reference in New Issue