added another alert to cover all cases where the torrent has to be checked at start, and tell the user why. Fixed a problem with the resume data generation introduced in last storage check-in

This commit is contained in:
Arvid Norberg 2007-10-09 00:25:01 +00:00
parent 4d19f7ff0f
commit ffe2e75882
5 changed files with 59 additions and 23 deletions

View File

@ -187,7 +187,8 @@ namespace libtorrent
~piece_manager();
bool check_fastresume(aux::piece_checker_data& d
, std::vector<bool>& pieces, int& num_pieces, storage_mode_t storage_mode);
, std::vector<bool>& pieces, int& num_pieces, storage_mode_t storage_mode
, std::string& error_msg);
std::pair<bool, float> check_files(std::vector<bool>& pieces
, int& num_pieces, boost::recursive_mutex& mutex);
@ -236,7 +237,8 @@ namespace libtorrent
// slots to the piece that is stored (or
// partially stored) there. -2 is the index
// of unassigned pieces and -1 is unallocated
void export_piece_map(std::vector<int>& pieces) const;
void export_piece_map(std::vector<int>& pieces
, std::vector<bool> const& have) const;
bool compact_allocation() const
{ return m_storage_mode == storage_mode_compact; }

View File

@ -189,9 +189,11 @@ namespace detail
t->parse_resume_data(t->resume_data, t->torrent_ptr->torrent_file()
, error_msg);
// lock the session to add the new torrent
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
if (!error_msg.empty() && m_ses.m_alerts.should_post(alert::warning))
{
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
m_ses.m_alerts.post_alert(fastresume_rejected_alert(
t->torrent_ptr->get_handle()
, error_msg));
@ -202,8 +204,6 @@ namespace detail
#endif
}
// lock the session to add the new torrent
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
mutex::scoped_lock l2(m_mutex);
if (m_torrents.empty() || m_torrents.front() != t)

View File

@ -1078,25 +1078,37 @@ namespace libtorrent
return false;
}
void piece_manager::export_piece_map(
std::vector<int>& p) const
std::vector<int>& p, std::vector<bool> const& have) const
{
boost::recursive_mutex::scoped_lock lock(m_mutex);
INVARIANT_CHECK;
p.clear();
std::vector<int>::const_reverse_iterator last;
for (last = m_slot_to_piece.rbegin();
last != m_slot_to_piece.rend(); ++last)
if (m_storage_mode == storage_mode_compact)
{
if (*last != unallocated) break;
}
p.clear();
p.reserve(m_info->num_pieces());
std::vector<int>::const_reverse_iterator last;
for (last = m_slot_to_piece.rbegin();
last != m_slot_to_piece.rend(); ++last)
{
if (*last != unallocated) break;
}
for (std::vector<int>::const_iterator i =
m_slot_to_piece.begin();
i != last.base(); ++i)
for (std::vector<int>::const_iterator i =
m_slot_to_piece.begin();
i != last.base(); ++i)
{
p.push_back(*i);
}
}
else
{
p.push_back(*i);
p.reserve(m_info->num_pieces());
for (int i = 0; i < m_info->num_pieces(); ++i)
{
p.push_back(have[i] ? i : unassigned);
}
}
}
@ -1374,7 +1386,8 @@ namespace libtorrent
bool piece_manager::check_fastresume(
aux::piece_checker_data& data
, std::vector<bool>& pieces
, int& num_pieces, storage_mode_t storage_mode)
, int& num_pieces, storage_mode_t storage_mode
, std::string& error_msg)
{
boost::recursive_mutex::scoped_lock lock(m_mutex);
@ -1473,6 +1486,7 @@ namespace libtorrent
// we're resuming a compact allocated storage
m_state = state_expand_pieces;
m_current_slot = 0;
error_msg = "pieces needs to be reordered";
return false;
}
}
@ -1481,6 +1495,7 @@ namespace libtorrent
return false;
}
error_msg = "empty piece map";
m_state = state_full_check;
return false;
}

View File

@ -2215,10 +2215,22 @@ namespace libtorrent
bool done = true;
try
{
std::string error_msg;
TORRENT_ASSERT(m_storage);
TORRENT_ASSERT(m_owning_storage.get());
done = m_storage->check_fastresume(data, m_have_pieces, m_num_pieces
, m_storage_mode);
, m_storage_mode, error_msg);
if (!error_msg.empty() && m_ses.m_alerts.should_post(alert::warning))
{
m_ses.m_alerts.post_alert(fastresume_rejected_alert(
get_handle(), error_msg));
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
(*m_ses.m_logger) << "fastresume data for "
<< torrent_file().name() << " rejected: "
<< error_msg << "\n";
#endif
}
}
catch (std::exception& e)
{

View File

@ -661,7 +661,7 @@ namespace libtorrent
if (!t->valid_metadata()) return entry();
t->filesystem().export_piece_map(piece_index);
t->filesystem().export_piece_map(piece_index, t->pieces());
entry ret(entry::dictionary_t);
@ -673,10 +673,6 @@ namespace libtorrent
const sha1_hash& info_hash = t->torrent_file().info_hash();
ret["info-hash"] = std::string((char*)info_hash.begin(), (char*)info_hash.end());
ret["slots"] = entry(entry::list_t);
entry::list_type& slots = ret["slots"].list();
std::copy(piece_index.begin(), piece_index.end(), std::back_inserter(slots));
// blocks per piece
int num_blocks_per_piece =
static_cast<int>(t->torrent_file().piece_length()) / t->block_size();
@ -706,6 +702,13 @@ namespace libtorrent
// the unfinished piece's index
piece_struct["piece"] = i->index;
// if the unfinished piece is not in the exported piece map, it means
// we're in full or sparse storage mode, in which case we have
// to insert the unfinished piece where it's stored
if (std::find(piece_index.begin(), piece_index.end(), i->index)
== piece_index.end() && i->index < int(piece_index.size()))
piece_index[i->index] = i->index;
std::string bitmask;
const int num_bitmask_bytes
= (std::max)(num_blocks_per_piece / 8, 1);
@ -735,6 +738,10 @@ namespace libtorrent
up.push_back(piece_struct);
}
}
entry::list_type& slots = ret["slots"].list();
std::copy(piece_index.begin(), piece_index.end(), std::back_inserter(slots));
// write local peers
entry::list_type& peer_list = ret["peers"].list();