forked from premiere/premiere-libtorrent
fixed fast resume data bug when using full allocation mode, and moved parts of resume data generation to the storage
This commit is contained in:
parent
58b23a79e7
commit
510966f2a5
|
@ -320,6 +320,12 @@ namespace libtorrent
|
|||
// when they are destructed.
|
||||
file_pool m_files;
|
||||
|
||||
// this is a list of half-open tcp connections
|
||||
// (only outgoing connections)
|
||||
// this has to be one of the last
|
||||
// members to be destructed
|
||||
connection_queue m_half_open;
|
||||
|
||||
// the bandwidth manager is responsible for
|
||||
// handing out bandwidth to connections that
|
||||
// asks for it, it can also throttle the
|
||||
|
@ -335,10 +341,6 @@ namespace libtorrent
|
|||
// peers.
|
||||
connection_map m_connections;
|
||||
|
||||
// this is a list of half-open tcp connections
|
||||
// (only outgoing connections)
|
||||
connection_queue m_half_open;
|
||||
|
||||
// filters incoming connections
|
||||
ip_filter m_ip_filter;
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@ namespace libtorrent
|
|||
torrent_info const& t
|
||||
, boost::filesystem::path p
|
||||
, std::vector<std::pair<size_type, std::time_t> > const& sizes
|
||||
, bool compact_mode
|
||||
, std::string* error = 0);
|
||||
|
||||
struct TORRENT_EXPORT file_allocation_failed: std::exception
|
||||
|
@ -104,8 +105,12 @@ namespace libtorrent
|
|||
|
||||
virtual bool move_storage(boost::filesystem::path save_path) = 0;
|
||||
|
||||
// verify storage dependent fast resume entries
|
||||
virtual bool verify_resume_data(entry& rd, std::string& error) = 0;
|
||||
|
||||
// write storage dependent fast resume entries
|
||||
virtual void write_resume_data(entry& rd) const = 0;
|
||||
|
||||
// moves (or copies) the content in src_slot to dst_slot
|
||||
virtual void move_slot(int src_slot, int dst_slot) = 0;
|
||||
|
||||
|
@ -153,6 +158,7 @@ namespace libtorrent
|
|||
|
||||
void release_files();
|
||||
|
||||
void write_resume_data(entry& rd) const;
|
||||
bool verify_resume_data(entry& rd, std::string& error);
|
||||
|
||||
bool is_allocating() const;
|
||||
|
|
|
@ -478,10 +478,10 @@ namespace libtorrent { namespace detail
|
|||
, char const* listen_interface)
|
||||
: m_strand(m_io_service)
|
||||
, m_files(40)
|
||||
, m_half_open(m_io_service)
|
||||
, m_dl_bandwidth_manager(m_io_service, peer_connection::download_channel)
|
||||
, m_ul_bandwidth_manager(m_io_service, peer_connection::upload_channel)
|
||||
, m_tracker_manager(m_settings, m_tracker_proxy)
|
||||
, m_half_open(m_io_service)
|
||||
, m_listen_port_range(listen_port_range)
|
||||
, m_listen_interface(address::from_string(listen_interface), listen_port_range.first)
|
||||
, m_external_listen_port(0)
|
||||
|
@ -2026,7 +2026,6 @@ namespace libtorrent { namespace detail
|
|||
}
|
||||
}
|
||||
|
||||
// verify file sizes
|
||||
if (!torrent_ptr->verify_resume_data(rd, error))
|
||||
return;
|
||||
|
||||
|
|
|
@ -270,10 +270,17 @@ namespace libtorrent
|
|||
return sizes;
|
||||
}
|
||||
|
||||
// matches the sizes and timestamps of the files passed in
|
||||
// in non-compact mode, actual file sizes and timestamps
|
||||
// are allowed to be bigger and more recent than the fast
|
||||
// resume data. This is because full allocation will not move
|
||||
// pieces, so any older version of the resume data will
|
||||
// still be a correct subset of the actual data on disk.
|
||||
bool match_filesizes(
|
||||
torrent_info const& t
|
||||
, path p
|
||||
, std::vector<std::pair<size_type, std::time_t> > const& sizes
|
||||
, bool compact_mode
|
||||
, std::string* error)
|
||||
{
|
||||
if ((int)sizes.size() != t.num_files())
|
||||
|
@ -293,6 +300,7 @@ namespace libtorrent
|
|||
try
|
||||
{
|
||||
path f = p / i->path;
|
||||
std::cerr << f.string() << " ";
|
||||
#if defined(_WIN32) && defined(UNICODE) && BOOST_VERSION < 103400
|
||||
size = file_size_win(f);
|
||||
time = last_write_time_win(f);
|
||||
|
@ -302,19 +310,23 @@ namespace libtorrent
|
|||
#endif
|
||||
}
|
||||
catch (std::exception&) {}
|
||||
if (size != s->first)
|
||||
if (size != s->first
|
||||
|| (!compact_mode && size < s->first))
|
||||
{
|
||||
if (error) *error = "filesize mismatch for file '"
|
||||
+ i->path.native_file_string()
|
||||
+ "', expected to be " + boost::lexical_cast<std::string>(s->first)
|
||||
+ "', size: " + boost::lexical_cast<std::string>(size)
|
||||
+ ", expected to be " + boost::lexical_cast<std::string>(s->first)
|
||||
+ " bytes";
|
||||
return false;
|
||||
}
|
||||
if (time != s->second)
|
||||
if (time != s->second
|
||||
|| (!compact_mode && time < s->second))
|
||||
{
|
||||
if (error) *error = "timestamp mismatch for file '"
|
||||
+ i->path.native_file_string()
|
||||
+ "', expected to have modification date "
|
||||
+ "', modification date: " + boost::lexical_cast<std::string>(time)
|
||||
+ ", expected to have modification date "
|
||||
+ boost::lexical_cast<std::string>(s->second);
|
||||
return false;
|
||||
}
|
||||
|
@ -379,6 +391,7 @@ namespace libtorrent
|
|||
void swap_slots(int slot1, int slot2);
|
||||
void swap_slots3(int slot1, int slot2, int slot3);
|
||||
bool verify_resume_data(entry& rd, std::string& error);
|
||||
void write_resume_data(entry& rd) const;
|
||||
|
||||
size_type read_impl(char* buf, int slot, int offset, int size, bool fill_zero);
|
||||
|
||||
|
@ -442,6 +455,23 @@ namespace libtorrent
|
|||
std::vector<char>().swap(m_scratch_buffer);
|
||||
}
|
||||
|
||||
void storage::write_resume_data(entry& rd) const
|
||||
{
|
||||
std::vector<std::pair<size_type, std::time_t> > file_sizes
|
||||
= get_filesizes(m_info, m_save_path);
|
||||
|
||||
rd["file sizes"] = entry::list_type();
|
||||
entry::list_type& fl = rd["file sizes"].list();
|
||||
for (std::vector<std::pair<size_type, std::time_t> >::iterator i
|
||||
= file_sizes.begin(), end(file_sizes.end()); i != end; ++i)
|
||||
{
|
||||
entry::list_type p;
|
||||
p.push_back(entry(i->first));
|
||||
p.push_back(entry(i->second));
|
||||
fl.push_back(entry(p));
|
||||
}
|
||||
}
|
||||
|
||||
bool storage::verify_resume_data(entry& rd, std::string& error)
|
||||
{
|
||||
std::vector<std::pair<size_type, std::time_t> > file_sizes;
|
||||
|
@ -455,6 +485,12 @@ namespace libtorrent
|
|||
, i->list().back().integer()));
|
||||
}
|
||||
|
||||
if (file_sizes.empty())
|
||||
{
|
||||
error = "the number of files in resume data is 0";
|
||||
return false;
|
||||
}
|
||||
|
||||
entry::list_type& slots = rd["slots"].list();
|
||||
bool seed = int(slots.size()) == m_info.num_pieces()
|
||||
&& std::find_if(slots.begin(), slots.end()
|
||||
|
@ -497,9 +533,8 @@ namespace libtorrent
|
|||
return true;
|
||||
}
|
||||
|
||||
if (full_allocation_mode) return true;
|
||||
|
||||
return match_filesizes(m_info, m_save_path, file_sizes, &error);
|
||||
return match_filesizes(m_info, m_save_path, file_sizes
|
||||
, !full_allocation_mode, &error);
|
||||
}
|
||||
|
||||
// returns true on success
|
||||
|
@ -1149,6 +1184,11 @@ namespace libtorrent
|
|||
{
|
||||
}
|
||||
|
||||
void piece_manager::write_resume_data(entry& rd) const
|
||||
{
|
||||
m_pimpl->m_storage->write_resume_data(rd);
|
||||
}
|
||||
|
||||
bool piece_manager::verify_resume_data(entry& rd, std::string& error)
|
||||
{
|
||||
return m_pimpl->m_storage->verify_resume_data(rd, error);
|
||||
|
|
|
@ -1702,9 +1702,11 @@ namespace libtorrent
|
|||
assert(peerinfo);
|
||||
assert(peerinfo->connection == 0);
|
||||
#ifndef NDEBUG
|
||||
// this asserts that we don't have duplicates in the policy's peer list
|
||||
peer_iterator i_ = m_connections.find(peerinfo->ip);
|
||||
assert(i_ == m_connections.end()
|
||||
|| (i_->second->is_disconnecting()));
|
||||
|| i_->second->is_disconnecting()
|
||||
|| dynamic_cast<bt_peer_connection*>(i_->second) == 0);
|
||||
#endif
|
||||
|
||||
assert(want_more_peers());
|
||||
|
|
|
@ -602,19 +602,7 @@ namespace libtorrent
|
|||
peer_list.push_back(peer);
|
||||
}
|
||||
|
||||
std::vector<std::pair<size_type, std::time_t> > file_sizes
|
||||
= get_filesizes(t->torrent_file(), t->save_path());
|
||||
|
||||
ret["file sizes"] = entry::list_type();
|
||||
entry::list_type& fl = ret["file sizes"].list();
|
||||
for (std::vector<std::pair<size_type, std::time_t> >::iterator i
|
||||
= file_sizes.begin(), end(file_sizes.end()); i != end; ++i)
|
||||
{
|
||||
entry::list_type p;
|
||||
p.push_back(entry(i->first));
|
||||
p.push_back(entry(i->second));
|
||||
fl.push_back(entry(p));
|
||||
}
|
||||
t->filesystem().write_resume_data(ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue