lt sync 3232 and patch segfault on start

This commit is contained in:
Andrew Resch 2009-02-07 00:59:56 +00:00
commit 233b67db75
4 changed files with 95 additions and 75 deletions

View file

@ -60,7 +60,7 @@ namespace libtorrent
~bitfield() { dealloc(); } ~bitfield() { dealloc(); }
void assign(char const* bytes, int bits) void assign(char const* bytes, int bits)
{ resize(bits); std::memcpy(m_bytes, bytes, (bits + 7) / 8); } { resize(bits); std::memcpy(m_bytes, bytes, (bits + 7) / 8); clear_trailing_bits(); }
bool operator[](int index) const bool operator[](int index) const
{ return get_bit(index); } { return get_bit(index); }
@ -198,6 +198,7 @@ namespace libtorrent
if (old_size_bytes && b) m_bytes[old_size_bytes - 1] |= (0xff >> b); if (old_size_bytes && b) m_bytes[old_size_bytes - 1] |= (0xff >> b);
if (old_size_bytes < new_size_bytes) if (old_size_bytes < new_size_bytes)
std::memset(m_bytes + old_size_bytes, 0xff, new_size_bytes - old_size_bytes); std::memset(m_bytes + old_size_bytes, 0xff, new_size_bytes - old_size_bytes);
clear_trailing_bits();
} }
else else
{ {
@ -209,6 +210,7 @@ namespace libtorrent
void set_all() void set_all()
{ {
std::memset(m_bytes, 0xff, (m_size + 7) / 8); std::memset(m_bytes, 0xff, (m_size + 7) / 8);
clear_trailing_bits();
} }
void clear_all() void clear_all()
@ -240,12 +242,17 @@ namespace libtorrent
m_own = true; m_own = true;
} }
m_size = bits; m_size = bits;
// clear the tail bits in the last byte clear_trailing_bits();
if (m_size && (bits & 7)) m_bytes[(m_size + 7) / 8 - 1] &= 0xff << (7 - (bits & 7));
} }
private: private:
void clear_trailing_bits()
{
// clear the tail bits in the last byte
if (m_size & 7) m_bytes[(m_size + 7) / 8 - 1] &= 0xff << (8 - (m_size & 7));
}
void dealloc() { if (m_own) std::free(m_bytes); m_bytes = 0; } void dealloc() { if (m_own) std::free(m_bytes); m_bytes = 0; }
unsigned char* m_bytes; unsigned char* m_bytes;
int m_size; // in bits int m_size; // in bits

View file

@ -287,7 +287,7 @@ public:
m_RC4_handler->encrypt(buffer, size); m_RC4_handler->encrypt(buffer, size);
#ifdef TORRENT_DEBUG #ifdef TORRENT_DEBUG
m_encrypted_bytes += size; m_encrypted_bytes += size;
TORRENT_ASSERT(m_encrypted_bytes <= send_buffer_size() + size); TORRENT_ASSERT(m_encrypted_bytes == send_buffer_size() + size);
#endif #endif
} }
#endif #endif

View file

@ -443,6 +443,8 @@ namespace libtorrent
int pad_size = rand() % 512; int pad_size = rand() % 512;
TORRENT_ASSERT(send_buffer_size() == m_encrypted_bytes);
// synchash,skeyhash,vc,crypto_provide,len(pad),pad,len(ia) // synchash,skeyhash,vc,crypto_provide,len(pad),pad,len(ia)
buffer::interval send_buf = buffer::interval send_buf =
allocate_send_buffer(20 + 20 + 8 + 4 + 2 + pad_size + 2); allocate_send_buffer(20 + 20 + 8 + 4 + 2 + pad_size + 2);
@ -506,7 +508,7 @@ namespace libtorrent
const int packet_size = 20 + 20 + 8 + 4 + 2 + pad_size + 2; const int packet_size = 20 + 20 + 8 + 4 + 2 + pad_size + 2;
TORRENT_ASSERT(send_buffer_size() - packet_size == m_encrypted_bytes); TORRENT_ASSERT(send_buffer_size() - packet_size == m_encrypted_bytes);
m_encrypted_bytes += packet_size; m_encrypted_bytes += packet_size;
TORRENT_ASSERT(m_encrypted_bytes <= send_buffer_size()); TORRENT_ASSERT(m_encrypted_bytes == send_buffer_size());
#endif #endif
TORRENT_ASSERT(send_buf.begin == send_buf.end); TORRENT_ASSERT(send_buf.begin == send_buf.end);
@ -525,6 +527,8 @@ namespace libtorrent
int pad_size =rand() % 512; int pad_size =rand() % 512;
TORRENT_ASSERT(send_buffer_size() == m_encrypted_bytes);
const int buf_size = 8 + 4 + 2 + pad_size; const int buf_size = 8 + 4 + 2 + pad_size;
buffer::interval send_buf = allocate_send_buffer(buf_size); buffer::interval send_buf = allocate_send_buffer(buf_size);
if (send_buf.begin == 0) return; // out of memory if (send_buf.begin == 0) return; // out of memory
@ -636,7 +640,6 @@ namespace libtorrent
m_RC4_handler->encrypt(const_cast<char*>(buf), size); m_RC4_handler->encrypt(const_cast<char*>(buf), size);
#ifdef TORRENT_DEBUG #ifdef TORRENT_DEBUG
m_encrypted_bytes += size; m_encrypted_bytes += size;
TORRENT_ASSERT(m_encrypted_bytes <= send_buffer_size() + size);
#endif #endif
} }
@ -680,6 +683,7 @@ namespace libtorrent
void bt_peer_connection::setup_send() void bt_peer_connection::setup_send()
{ {
encrypt_pending_buffer(); encrypt_pending_buffer();
TORRENT_ASSERT(!m_encrypted || !m_rc4_encrypted || m_encrypted_bytes == send_buffer_size());
peer_connection::setup_send(); peer_connection::setup_send();
} }
@ -1525,7 +1529,11 @@ namespace libtorrent
if (t->is_seed()) if (t->is_seed())
{ {
memset(i.begin, 0xff, packet_size - 5); memset(i.begin, 0xff, packet_size - 6);
// Clear trailing bits
unsigned char *p = ((unsigned char *)i.begin) + packet_size - 6;
*p = (0xff << ((8 - (num_pieces & 7)) & 7)) & 0xff;
} }
else else
{ {
@ -2671,9 +2679,16 @@ namespace libtorrent
#ifdef TORRENT_DEBUG #ifdef TORRENT_DEBUG
if (m_encrypted_bytes > 0) if (m_encrypted_bytes > 0)
{ {
m_encrypted_bytes -= bytes_transferred; if (m_rc4_encrypted)
{
m_encrypted_bytes -= bytes_transferred;
TORRENT_ASSERT(m_encrypted_bytes >= 0);
}
else
{
m_encrypted_bytes -= (std::min)(int(bytes_transferred), m_encrypted_bytes);
}
TORRENT_ASSERT(m_encrypted_bytes >= 0); TORRENT_ASSERT(m_encrypted_bytes >= 0);
TORRENT_ASSERT(m_encrypted_bytes <= send_buffer_size());
} }
#endif #endif

View file

@ -101,7 +101,7 @@ namespace
: ip(a) : ip(a)
, tor(t) , tor(t)
{ TORRENT_ASSERT(t != 0); } { TORRENT_ASSERT(t != 0); }
bool operator()(session_impl::connection_map::value_type const& c) const bool operator()(session_impl::connection_map::value_type const& c) const
{ {
tcp::endpoint const& sender = c->remote(); tcp::endpoint const& sender = c->remote();
@ -117,7 +117,7 @@ namespace
struct peer_by_id struct peer_by_id
{ {
peer_by_id(const peer_id& i): pid(i) {} peer_by_id(const peer_id& i): pid(i) {}
bool operator()(session_impl::connection_map::value_type const& p) const bool operator()(session_impl::connection_map::value_type const& p) const
{ {
if (p->pid() != pid) return false; if (p->pid() != pid) return false;
@ -350,7 +350,7 @@ namespace libtorrent
// don't announce private torrents // don't announce private torrents
if (m_torrent_file->is_valid() && m_torrent_file->priv()) return false; if (m_torrent_file->is_valid() && m_torrent_file->priv()) return false;
if (m_trackers.empty()) return true; if (m_trackers.empty()) return true;
return m_failed_trackers > 0 || !m_ses.settings().use_dht_as_fallback; return m_failed_trackers > 0 || !m_ses.settings().use_dht_as_fallback;
} }
#endif #endif
@ -361,13 +361,13 @@ namespace libtorrent
// is being destructed, all weak references to it have been // is being destructed, all weak references to it have been
// reset, which means that all its peers already have an // reset, which means that all its peers already have an
// invalidated torrent pointer (so it cannot be verified to be correct) // invalidated torrent pointer (so it cannot be verified to be correct)
// i.e. the invariant can only be maintained if all connections have // i.e. the invariant can only be maintained if all connections have
// been closed by the time the torrent is destructed. And they are // been closed by the time the torrent is destructed. And they are
// supposed to be closed. So we can still do the invariant check. // supposed to be closed. So we can still do the invariant check.
TORRENT_ASSERT(m_connections.empty()); TORRENT_ASSERT(m_connections.empty());
INVARIANT_CHECK; INVARIANT_CHECK;
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING
@ -419,7 +419,7 @@ namespace libtorrent
if (!tp) return; if (!tp) return;
add_extension(tp); add_extension(tp);
for (peer_iterator i = m_connections.begin(); for (peer_iterator i = m_connections.begin();
i != m_connections.end(); ++i) i != m_connections.end(); ++i)
{ {
@ -476,7 +476,7 @@ namespace libtorrent
char const* error = 0; char const* error = 0;
if (m_resume_entry.dict_find_string_value("file-format") != "libtorrent resume file") if (m_resume_entry.dict_find_string_value("file-format") != "libtorrent resume file")
error = "invalid file format tag"; error = "invalid file format tag";
std::string info_hash = m_resume_entry.dict_find_string_value("info-hash"); std::string info_hash = m_resume_entry.dict_find_string_value("info-hash");
if (!error && info_hash.empty()) if (!error && info_hash.empty())
error = "missing info-hash"; error = "missing info-hash";
@ -504,7 +504,7 @@ namespace libtorrent
read_resume_data(m_resume_entry); read_resume_data(m_resume_entry);
} }
} }
m_storage->async_check_fastresume(&m_resume_entry m_storage->async_check_fastresume(&m_resume_entry
, bind(&torrent::on_resume_data_checked , bind(&torrent::on_resume_data_checked
, shared_from_this(), _1, _2)); , shared_from_this(), _1, _2));
@ -560,7 +560,7 @@ namespace libtorrent
if (lazy_entry const* banned_peers_entry = m_resume_entry.dict_find_list("banned_peers")) if (lazy_entry const* banned_peers_entry = m_resume_entry.dict_find_list("banned_peers"))
{ {
peer_id id(0); peer_id id(0);
for (int i = 0; i < banned_peers_entry->list_size(); ++i) for (int i = 0; i < banned_peers_entry->list_size(); ++i)
{ {
lazy_entry const* e = banned_peers_entry->list_at(i); lazy_entry const* e = banned_peers_entry->list_at(i);
@ -578,7 +578,7 @@ namespace libtorrent
} }
bool fastresume_rejected = !j.str.empty(); bool fastresume_rejected = !j.str.empty();
if (fastresume_rejected && m_ses.m_alerts.should_post<fastresume_rejected_alert>()) if (fastresume_rejected && m_ses.m_alerts.should_post<fastresume_rejected_alert>())
{ {
m_ses.m_alerts.post_alert(fastresume_rejected_alert(get_handle(), j.str)); m_ses.m_alerts.post_alert(fastresume_rejected_alert(get_handle(), j.str));
@ -725,7 +725,7 @@ namespace libtorrent
&torrent::on_piece_checked &torrent::on_piece_checked
, shared_from_this(), _1, _2)); , shared_from_this(), _1, _2));
} }
void torrent::on_piece_checked(int ret, disk_io_job const& j) void torrent::on_piece_checked(int ret, disk_io_job const& j)
{ {
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
@ -790,7 +790,7 @@ namespace libtorrent
void torrent::on_tracker_announce() void torrent::on_tracker_announce()
{ {
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
if (m_abort) return; if (m_abort) return;
announce_with_tracker(); announce_with_tracker();
} }
@ -931,7 +931,7 @@ namespace libtorrent
TORRENT_ASSERT(m_currently_trying_tracker >= 0); TORRENT_ASSERT(m_currently_trying_tracker >= 0);
TORRENT_ASSERT(m_currently_trying_tracker < int(m_trackers.size())); TORRENT_ASSERT(m_currently_trying_tracker < int(m_trackers.size()));
tracker_request req; tracker_request req;
req.info_hash = m_torrent_file->info_hash(); req.info_hash = m_torrent_file->info_hash();
req.kind = tracker_request::scrape_request; req.kind = tracker_request::scrape_request;
@ -951,25 +951,25 @@ namespace libtorrent
if (m_ses.m_alerts.should_post<tracker_warning_alert>()) if (m_ses.m_alerts.should_post<tracker_warning_alert>())
m_ses.m_alerts.post_alert(tracker_warning_alert(get_handle(), req.url, msg)); m_ses.m_alerts.post_alert(tracker_warning_alert(get_handle(), req.url, msg));
} }
void torrent::tracker_scrape_response(tracker_request const& req void torrent::tracker_scrape_response(tracker_request const& req
, int complete, int incomplete, int downloaded) , int complete, int incomplete, int downloaded)
{ {
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_ASSERT(req.kind == tracker_request::scrape_request); TORRENT_ASSERT(req.kind == tracker_request::scrape_request);
if (complete >= 0) m_complete = complete; if (complete >= 0) m_complete = complete;
if (incomplete >= 0) m_incomplete = incomplete; if (incomplete >= 0) m_incomplete = incomplete;
if (m_ses.m_alerts.should_post<scrape_reply_alert>()) if (m_ses.m_alerts.should_post<scrape_reply_alert>())
{ {
m_ses.m_alerts.post_alert(scrape_reply_alert( m_ses.m_alerts.post_alert(scrape_reply_alert(
get_handle(), m_incomplete, m_complete, req.url)); get_handle(), m_incomplete, m_complete, req.url));
} }
} }
void torrent::tracker_response( void torrent::tracker_response(
tracker_request const& r tracker_request const& r
, std::vector<peer_entry>& peer_list , std::vector<peer_entry>& peer_list
@ -1081,7 +1081,7 @@ namespace libtorrent
return; return;
} }
m_policy.peer_from_tracker(*host, pid, peer_info::tracker, 0); m_policy.peer_from_tracker(*host, pid, peer_info::tracker, 0);
} }
@ -1143,7 +1143,7 @@ namespace libtorrent
size_type wanted_done = size_type(num_have() - m_picker->num_have_filtered()) size_type wanted_done = size_type(num_have() - m_picker->num_have_filtered())
* piece_size; * piece_size;
TORRENT_ASSERT(wanted_done >= 0); TORRENT_ASSERT(wanted_done >= 0);
size_type total_done size_type total_done
= size_type(num_have()) * piece_size; = size_type(num_have()) * piece_size;
TORRENT_ASSERT(num_have() < m_torrent_file->num_pieces()); TORRENT_ASSERT(num_have() < m_torrent_file->num_pieces());
@ -1272,9 +1272,9 @@ namespace libtorrent
// Thist happens when a piece has been downloaded completely // Thist happens when a piece has been downloaded completely
// but not yet verified against the hash // but not yet verified against the hash
std::cerr << "num_have: " << num_have() << std::endl; std::cerr << "num_have: " << num_have() << std::endl;
std::cerr << "unfinished:" << std::endl; std::cerr << "unfinished:" << std::endl;
for (std::vector<piece_picker::downloading_piece>::const_iterator i = for (std::vector<piece_picker::downloading_piece>::const_iterator i =
dl_queue.begin(); i != dl_queue.end(); ++i) dl_queue.begin(); i != dl_queue.end(); ++i)
{ {
@ -1285,7 +1285,7 @@ namespace libtorrent
} }
std::cerr << std::endl; std::cerr << std::endl;
} }
std::cerr << "downloading pieces:" << std::endl; std::cerr << "downloading pieces:" << std::endl;
for (std::map<piece_block, int>::iterator i = downloading_piece.begin(); for (std::map<piece_block, int>::iterator i = downloading_piece.begin();
@ -1610,10 +1610,10 @@ namespace libtorrent
bind(&torrent::on_files_released, shared_from_this(), _1, _2)); bind(&torrent::on_files_released, shared_from_this(), _1, _2));
m_storage->abort_disk_io(); m_storage->abort_disk_io();
} }
if (m_state == torrent_status::checking_files) if (m_state == torrent_status::checking_files)
m_ses.done_checking(shared_from_this()); m_ses.done_checking(shared_from_this());
m_owning_storage = 0; m_owning_storage = 0;
m_host_resolver.cancel(); m_host_resolver.cancel();
} }
@ -1667,7 +1667,7 @@ namespace libtorrent
void torrent::on_file_renamed(int ret, disk_io_job const& j) void torrent::on_file_renamed(int ret, disk_io_job const& j)
{ {
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
{ {
if (ret == 0) if (ret == 0)
{ {
@ -1803,7 +1803,7 @@ namespace libtorrent
// the bitmask need to have exactly one bit for every file // the bitmask need to have exactly one bit for every file
// in the torrent // in the torrent
TORRENT_ASSERT(int(files.size()) == m_torrent_file->num_files()); TORRENT_ASSERT(int(files.size()) == m_torrent_file->num_files());
if (m_torrent_file->num_pieces() == 0) return; if (m_torrent_file->num_pieces() == 0) return;
std::copy(files.begin(), files.end(), m_file_priority.begin()); std::copy(files.begin(), files.end(), m_file_priority.begin());
@ -1819,7 +1819,7 @@ namespace libtorrent
m_file_priority[index] = prio; m_file_priority[index] = prio;
update_piece_priorities(); update_piece_priorities();
} }
int torrent::file_priority(int index) const int torrent::file_priority(int index) const
{ {
TORRENT_ASSERT(index < m_torrent_file->num_files()); TORRENT_ASSERT(index < m_torrent_file->num_files());
@ -1941,7 +1941,7 @@ namespace libtorrent
// this call is only valid on torrents with metadata // this call is only valid on torrents with metadata
TORRENT_ASSERT(valid_metadata()); TORRENT_ASSERT(valid_metadata());
if (is_seed()) return false; if (is_seed()) return false;
TORRENT_ASSERT(m_picker.get()); TORRENT_ASSERT(m_picker.get());
TORRENT_ASSERT(index >= 0); TORRENT_ASSERT(index >= 0);
TORRENT_ASSERT(index < m_torrent_file->num_pieces()); TORRENT_ASSERT(index < m_torrent_file->num_pieces());
@ -1976,7 +1976,7 @@ namespace libtorrent
// the bitmask need to have exactly one bit for every file // the bitmask need to have exactly one bit for every file
// in the torrent // in the torrent
TORRENT_ASSERT((int)bitmask.size() == m_torrent_file->num_files()); TORRENT_ASSERT((int)bitmask.size() == m_torrent_file->num_files());
size_type position = 0; size_type position = 0;
if (m_torrent_file->num_pieces()) if (m_torrent_file->num_pieces())
@ -1991,7 +1991,7 @@ namespace libtorrent
position += m_torrent_file->files().at(i).size; position += m_torrent_file->files().at(i).size;
// is the file selected for download? // is the file selected for download?
if (!bitmask[i]) if (!bitmask[i])
{ {
// mark all pieces of the file as downloadable // mark all pieces of the file as downloadable
int start_piece = int(start / piece_length); int start_piece = int(start / piece_length);
int last_piece = int(position / piece_length); int last_piece = int(position / piece_length);
@ -2024,7 +2024,7 @@ namespace libtorrent
c.send_choke(); c.send_choke();
--m_num_uploads; --m_num_uploads;
} }
bool torrent::unchoke_peer(peer_connection& c) bool torrent::unchoke_peer(peer_connection& c)
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
@ -2137,7 +2137,7 @@ namespace libtorrent
remove_url_seed(url); remove_url_seed(url);
return; return;
} }
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
if (protocol != "http" && protocol != "https") if (protocol != "http" && protocol != "https")
#else #else
@ -2316,10 +2316,10 @@ namespace libtorrent
m_ses.m_alerts.post_alert(peer_blocked_alert(a.address())); m_ses.m_alerts.post_alert(peer_blocked_alert(a.address()));
return; return;
} }
boost::shared_ptr<socket_type> s(new (std::nothrow) socket_type(m_ses.m_io_service)); boost::shared_ptr<socket_type> s(new (std::nothrow) socket_type(m_ses.m_io_service));
if (!s) return; if (!s) return;
bool ret = instantiate_connection(m_ses.m_io_service, m_ses.web_seed_proxy(), *s); bool ret = instantiate_connection(m_ses.m_io_service, m_ses.web_seed_proxy(), *s);
(void)ret; (void)ret;
TORRENT_ASSERT(ret); TORRENT_ASSERT(ret);
@ -2335,7 +2335,7 @@ namespace libtorrent
boost::intrusive_ptr<peer_connection> c(new (std::nothrow) web_peer_connection( boost::intrusive_ptr<peer_connection> c(new (std::nothrow) web_peer_connection(
m_ses, shared_from_this(), s, a, url, 0)); m_ses, shared_from_this(), s, a, url, 0));
if (!c) return; if (!c) return;
#ifdef TORRENT_DEBUG #ifdef TORRENT_DEBUG
c->m_in_constructor = false; c->m_in_constructor = false;
#endif #endif
@ -2386,7 +2386,7 @@ namespace libtorrent
return (a >> 24) | ((a & 0xff0000) >> 8) | ((a & 0xff00) << 8) | (a << 24); return (a >> 24) | ((a & 0xff0000) >> 8) | ((a & 0xff00) << 8) | (a << 24);
} }
} }
void torrent::resolve_peer_country(boost::intrusive_ptr<peer_connection> const& p) const void torrent::resolve_peer_country(boost::intrusive_ptr<peer_connection> const& p) const
{ {
if (m_resolving_country if (m_resolving_country
@ -2424,7 +2424,7 @@ namespace libtorrent
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
INVARIANT_CHECK; INVARIANT_CHECK;
m_resolving_country = false; m_resolving_country = false;
if (m_abort) return; if (m_abort) return;
@ -2496,7 +2496,7 @@ namespace libtorrent
{ {
// country is an ISO 3166 country code // country is an ISO 3166 country code
int country = i->endpoint().address().to_v4().to_ulong() & 0xffff; int country = i->endpoint().address().to_v4().to_ulong() & 0xffff;
// look up the country code in the map // look up the country code in the map
const int size = sizeof(country_map)/sizeof(country_map[0]); const int size = sizeof(country_map)/sizeof(country_map[0]);
country_entry tmp = {country, ""}; country_entry tmp = {country, ""};
@ -2513,7 +2513,7 @@ namespace libtorrent
#endif #endif
return; return;
} }
p->set_country(i->name); p->set_country(i->name);
} }
} }
@ -2550,14 +2550,13 @@ namespace libtorrent
} }
int auto_managed_ = rd.dict_find_int_value("auto_managed", -1); int auto_managed_ = rd.dict_find_int_value("auto_managed", -1);
if (auto_managed_ != -1) auto_managed(auto_managed_); if (auto_managed_ != -1) m_auto_managed = auto_managed_;
int sequential_ = rd.dict_find_int_value("sequential_download", -1); int sequential_ = rd.dict_find_int_value("sequential_download", -1);
if (sequential_ != -1) set_sequential_download(sequential_); if (sequential_ != -1) set_sequential_download(sequential_);
int paused_ = rd.dict_find_int_value("paused", -1); int paused_ = rd.dict_find_int_value("paused", -1);
if (paused_ == 1) pause(); if (paused_ != -1) m_paused = paused_;
else if (paused_ == 0) resume();
lazy_entry const* trackers = rd.dict_find_list("trackers"); lazy_entry const* trackers = rd.dict_find_list("trackers");
if (trackers) if (trackers)
@ -2605,7 +2604,7 @@ namespace libtorrent
} }
} }
} }
void torrent::write_resume_data(entry& ret) const void torrent::write_resume_data(entry& ret) const
{ {
ret["file-format"] = "libtorrent resume file"; ret["file-format"] = "libtorrent resume file";
@ -2628,7 +2627,7 @@ namespace libtorrent
ret["num_downloaders"] = downloaders; ret["num_downloaders"] = downloaders;
ret["sequential_download"] = m_sequential_download; ret["sequential_download"] = m_sequential_download;
const sha1_hash& info_hash = torrent_file().info_hash(); const sha1_hash& info_hash = torrent_file().info_hash();
ret["info-hash"] = std::string((char*)info_hash.begin(), (char*)info_hash.end()); ret["info-hash"] = std::string((char*)info_hash.begin(), (char*)info_hash.end());
@ -2729,7 +2728,7 @@ namespace libtorrent
entry::list_type& peer_list = ret["peers"].list(); entry::list_type& peer_list = ret["peers"].list();
entry::list_type& banned_peer_list = ret["banned_peers"].list(); entry::list_type& banned_peer_list = ret["banned_peers"].list();
int max_failcount = m_ses.m_settings.max_failcount; int max_failcount = m_ses.m_settings.max_failcount;
for (policy::const_iterator i = m_policy.begin_peer() for (policy::const_iterator i = m_policy.begin_peer()
@ -2822,7 +2821,7 @@ namespace libtorrent
v.push_back(peer_info()); v.push_back(peer_info());
peer_info& p = v.back(); peer_info& p = v.back();
peer->get_peer_info(p); peer->get_peer_info(p);
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
if (resolving_countries()) if (resolving_countries())
@ -2900,9 +2899,9 @@ namespace libtorrent
pi.piece_index = i->index; pi.piece_index = i->index;
queue.push_back(pi); queue.push_back(pi);
} }
} }
bool torrent::connect_to_peer(policy::peer* peerinfo) bool torrent::connect_to_peer(policy::peer* peerinfo)
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
@ -3027,7 +3026,7 @@ namespace libtorrent
p->disconnect("torrent is not ready to accept peers"); p->disconnect("torrent is not ready to accept peers");
return false; return false;
} }
if (m_ses.m_connections.find(p) == m_ses.m_connections.end()) if (m_ses.m_connections.find(p) == m_ses.m_connections.end())
{ {
p->disconnect("peer is not properly constructed"); p->disconnect("peer is not properly constructed");
@ -3156,7 +3155,7 @@ namespace libtorrent
double lhs_rate = double(lhs_transferred) / (lhs_time_connected + 1); double lhs_rate = double(lhs_transferred) / (lhs_time_connected + 1);
double rhs_rate = double(rhs_transferred) / (rhs_time_connected + 1); double rhs_rate = double(rhs_transferred) / (rhs_time_connected + 1);
return lhs_rate < rhs_rate; return lhs_rate < rhs_rate;
} }
@ -3238,7 +3237,7 @@ namespace libtorrent
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_ASSERT(amount > 0); TORRENT_ASSERT(amount > 0);
m_bandwidth_limit[channel].expire(amount); m_bandwidth_limit[channel].expire(amount);
queue_t tmp; queue_t tmp;
@ -3332,11 +3331,11 @@ namespace libtorrent
} }
// this is called when we were finished, but some files were // this is called when we were finished, but some files were
// marked for downloading, and we are no longer finished // marked for downloading, and we are no longer finished
void torrent::resume_download() void torrent::resume_download()
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
TORRENT_ASSERT(!is_finished()); TORRENT_ASSERT(!is_finished());
set_state(torrent_status::downloading); set_state(torrent_status::downloading);
set_queue_position((std::numeric_limits<int>::max)()); set_queue_position((std::numeric_limits<int>::max)());
@ -3417,7 +3416,7 @@ namespace libtorrent
void torrent::files_checked() void torrent::files_checked()
{ {
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex); session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
TORRENT_ASSERT(m_torrent_file->is_valid()); TORRENT_ASSERT(m_torrent_file->is_valid());
INVARIANT_CHECK; INVARIANT_CHECK;
@ -3433,7 +3432,7 @@ namespace libtorrent
m_ses.m_alerts.post_alert(torrent_checked_alert( m_ses.m_alerts.post_alert(torrent_checked_alert(
get_handle())); get_handle()));
} }
if (!is_seed()) if (!is_seed())
{ {
// if we just finished checking and we're not a seed, we are // if we just finished checking and we're not a seed, we are
@ -3677,7 +3676,7 @@ namespace libtorrent
} }
} }
} }
// This check is very expensive. // This check is very expensive.
TORRENT_ASSERT(!valid_metadata() || m_block_size > 0); TORRENT_ASSERT(!valid_metadata() || m_block_size > 0);
TORRENT_ASSERT(!valid_metadata() || (m_torrent_file->piece_length() % m_block_size) == 0); TORRENT_ASSERT(!valid_metadata() || (m_torrent_file->piece_length() % m_block_size) == 0);
@ -3728,7 +3727,7 @@ namespace libtorrent
{ {
torrent* t = i->second.get(); torrent* t = i->second.get();
if (t == this) continue; if (t == this) continue;
if (t->m_sequence_number >= p if (t->m_sequence_number >= p
&& t->m_sequence_number < m_sequence_number && t->m_sequence_number < m_sequence_number
&& t->m_sequence_number != -1) && t->m_sequence_number != -1)
++t->m_sequence_number; ++t->m_sequence_number;
@ -3947,11 +3946,11 @@ namespace libtorrent
return ret; return ret;
} }
// this is an async operation triggered by the client // this is an async operation triggered by the client
void torrent::save_resume_data() void torrent::save_resume_data()
{ {
INVARIANT_CHECK; INVARIANT_CHECK;
if (m_owning_storage.get()) if (m_owning_storage.get())
{ {
TORRENT_ASSERT(m_storage); TORRENT_ASSERT(m_storage);
@ -4222,7 +4221,7 @@ namespace libtorrent
std::for_each(not_connected_web_seeds.begin(), not_connected_web_seeds.end() std::for_each(not_connected_web_seeds.begin(), not_connected_web_seeds.end()
, bind(&torrent::connect_to_url_seed, this, _1)); , bind(&torrent::connect_to_url_seed, this, _1));
} }
for (peer_iterator i = m_connections.begin(); for (peer_iterator i = m_connections.begin();
i != m_connections.end();) i != m_connections.end();)
{ {
@ -4355,7 +4354,7 @@ namespace libtorrent
void torrent::file_progress(std::vector<size_type>& fp) const void torrent::file_progress(std::vector<size_type>& fp) const
{ {
TORRENT_ASSERT(valid_metadata()); TORRENT_ASSERT(valid_metadata());
fp.resize(m_torrent_file->num_files(), 0); fp.resize(m_torrent_file->num_files(), 0);
if (is_seed()) if (is_seed())
@ -4364,7 +4363,7 @@ namespace libtorrent
fp[i] = m_torrent_file->files().at(i).size; fp[i] = m_torrent_file->files().at(i).size;
return; return;
} }
TORRENT_ASSERT(has_picker()); TORRENT_ASSERT(has_picker());
for (int i = 0; i < m_torrent_file->num_files(); ++i) for (int i = 0; i < m_torrent_file->num_files(); ++i)
@ -4484,7 +4483,7 @@ namespace libtorrent
} }
} }
} }
void torrent::set_state(torrent_status::state_t s) void torrent::set_state(torrent_status::state_t s)
{ {
#ifdef TORRENT_DEBUG #ifdef TORRENT_DEBUG
@ -4616,7 +4615,7 @@ namespace libtorrent
st.total_wanted -= m_torrent_file->piece_size(last_piece_index); st.total_wanted -= m_torrent_file->piece_size(last_piece_index);
--num_filtered_pieces; --num_filtered_pieces;
} }
st.total_wanted -= size_type(num_filtered_pieces) * m_torrent_file->piece_length(); st.total_wanted -= size_type(num_filtered_pieces) * m_torrent_file->piece_length();
} }
@ -4740,4 +4739,3 @@ namespace libtorrent
#endif #endif
} }