fixed incorrect asserts in storage (that were triggered by torrent with zero-size files). Fixed bug in resource distribution algorithm. Made an attempt to avoid an assert in msvc standard library caused by passing a non-printable character to isdigit().

This commit is contained in:
Arvid Norberg 2006-08-10 19:18:11 +00:00
parent 4f2d147e07
commit 87eb377b17
5 changed files with 68 additions and 40 deletions

View File

@ -1,3 +1,7 @@
* fixed problem with the resource distribution algorithm
(controlling e.g upload/download rates)
* fixed incorrect asserts in storage related to torrents with
zero-sized files.
* added support for trackerless torrents (with kademlia DHT). * added support for trackerless torrents (with kademlia DHT).
* support for torrents with the private flag set. * support for torrents with the private flag set.
* support for torrents containing bootstrap nodes for the * support for torrents containing bootstrap nodes for the

View File

@ -256,7 +256,7 @@ namespace libtorrent
// ---------------------------------------------- // ----------------------------------------------
// string // string
default: default:
if (isdigit(*in)) if (isdigit((unsigned char)*in))
{ {
std::string len_s = read_until(in, end, ':'); std::string len_s = read_until(in, end, ':');
assert(*in == ':'); assert(*in == ':');

View File

@ -158,6 +158,7 @@ namespace libtorrent
, It end , It end
, resource_request T::* res) , resource_request T::* res)
{ {
assert(resources >= 0);
#ifndef NDEBUG #ifndef NDEBUG
allocate_resources_contract_check<It, T> contract_check( allocate_resources_contract_check<It, T> contract_check(
resources resources
@ -197,7 +198,9 @@ namespace libtorrent
resources = std::max(resources, sum_min); resources = std::max(resources, sum_min);
int resources_to_distribute = std::min(resources, sum_max) - sum_min; int resources_to_distribute = std::min(resources, sum_max) - sum_min;
assert(resources_to_distribute >= 0); assert(resources_to_distribute >= 0);
#ifndef NDEBUG
int prev_resources_to_distribute = resources_to_distribute;
#endif
while (resources_to_distribute > 0) while (resources_to_distribute > 0)
{ {
size_type total_used = 0; size_type total_used = 0;
@ -215,11 +218,17 @@ namespace libtorrent
size_type kNumer = resources_to_distribute; size_type kNumer = resources_to_distribute;
size_type kDenom = total_used; size_type kDenom = total_used;
assert(kNumer >= 0);
assert(kDenom >= 0);
assert(kNumer <= std::numeric_limits<int>::max());
assert(total_used < std::numeric_limits<int>::max());
if (kNumer * max_used <= kDenom) if (kNumer * max_used <= kDenom)
{ {
kNumer = 1; kNumer = 1;
kDenom = max_used; kDenom = max_used;
assert(kDenom >= 0);
assert(kDenom <= std::numeric_limits<int>::max());
} }
for (It i = start; i != end && resources_to_distribute > 0; ++i) for (It i = start; i != end && resources_to_distribute > 0; ++i)
@ -241,6 +250,10 @@ namespace libtorrent
} }
assert(resources_to_distribute >= 0); assert(resources_to_distribute >= 0);
assert(resources_to_distribute < prev_resources_to_distribute);
#ifndef NDEBUG
prev_resources_to_distribute = resources_to_distribute;
#endif
} }
} }

View File

@ -684,32 +684,37 @@ namespace libtorrent
if (file_offset + read_bytes > file_iter->size) if (file_offset + read_bytes > file_iter->size)
read_bytes = static_cast<int>(file_iter->size - file_offset); read_bytes = static_cast<int>(file_iter->size - file_offset);
if (read_bytes > 0)
{
#ifndef NDEBUG #ifndef NDEBUG
assert(int(slices.size()) > counter); assert(int(slices.size()) > counter);
size_type slice_size = slices[counter].size; size_type slice_size = slices[counter].size;
assert(slice_size == read_bytes); assert(slice_size == read_bytes);
assert(m_pimpl->info.file_at(slices[counter].file_index).path assert(m_pimpl->info.file_at(slices[counter].file_index).path
== file_iter->path); == file_iter->path);
#endif #endif
size_type actual_read = in->read(buf + buf_pos, read_bytes); size_type actual_read = in->read(buf + buf_pos, read_bytes);
if (read_bytes != actual_read) if (read_bytes != actual_read)
{ {
// the file was not big enough // the file was not big enough
throw file_error("slot has no storage"); throw file_error("slot has no storage");
}
left_to_read -= read_bytes;
buf_pos += read_bytes;
assert(buf_pos >= 0);
file_offset += read_bytes;
} }
left_to_read -= read_bytes;
buf_pos += read_bytes;
assert(buf_pos >= 0);
file_offset += read_bytes;
if (left_to_read > 0) if (left_to_read > 0)
{ {
++file_iter; ++file_iter;
#ifndef NDEBUG #ifndef NDEBUG
++counter; // empty files are not returned by map_block, so if
// this file was empty, don't increment the slice counter
if (read_bytes > 0) ++counter;
#endif #endif
path path = m_pimpl->save_path / file_iter->path; path path = m_pimpl->save_path / file_iter->path;
@ -799,32 +804,35 @@ namespace libtorrent
write_bytes = static_cast<int>(file_iter->size - file_offset); write_bytes = static_cast<int>(file_iter->size - file_offset);
} }
assert(int(slices.size()) > counter); if (write_bytes > 0)
assert(slices[counter].size == write_bytes);
assert(m_pimpl->info.file_at(slices[counter].file_index).path
== file_iter->path);
assert(buf_pos >= 0);
assert(write_bytes >= 0);
size_type written = out->write(buf + buf_pos, write_bytes);
if (written != write_bytes)
{ {
std::stringstream s; assert(int(slices.size()) > counter);
s << "no storage for slot " << slot; assert(slices[counter].size == write_bytes);
throw file_error(s.str()); assert(m_pimpl->info.file_at(slices[counter].file_index).path
} == file_iter->path);
left_to_write -= write_bytes; assert(buf_pos >= 0);
buf_pos += write_bytes; assert(write_bytes >= 0);
assert(buf_pos >= 0); size_type written = out->write(buf + buf_pos, write_bytes);
file_offset += write_bytes;
assert(file_offset <= file_iter->size); if (written != write_bytes)
{
std::stringstream s;
s << "no storage for slot " << slot;
throw file_error(s.str());
}
left_to_write -= write_bytes;
buf_pos += write_bytes;
assert(buf_pos >= 0);
file_offset += write_bytes;
assert(file_offset <= file_iter->size);
}
if (left_to_write > 0) if (left_to_write > 0)
{ {
#ifndef NDEBUG #ifndef NDEBUG
++counter; if (write_bytes > 0) ++counter;
#endif #endif
++file_iter; ++file_iter;

View File

@ -19,7 +19,10 @@ int test_main()
torrent_info info; torrent_info info;
info.set_piece_size(piece_size); info.set_piece_size(piece_size);
info.add_file("temp_storage/test1.tmp", 17); info.add_file("temp_storage/test1.tmp", 17);
info.add_file("temp_storage/test2.tmp", 613); info.add_file("temp_storage/test2.tmp", 612);
info.add_file("temp_storage/test3.tmp", 0);
info.add_file("temp_storage/test4.tmp", 0);
info.add_file("temp_storage/test5.tmp", 1);
char piece0[piece_size] = char piece0[piece_size] =
{ 6, 6, 6, 6, 6, 6, 6, 6 { 6, 6, 6, 6, 6, 6, 6, 6
@ -41,7 +44,7 @@ int test_main()
create_directory(initial_path() / "temp_storage"); create_directory(initial_path() / "temp_storage");
int num_pieces = (613 + 17 + piece_size - 1) / piece_size; int num_pieces = (1 + 612 + 17 + piece_size - 1) / piece_size;
TEST_CHECK(info.num_pieces() == num_pieces); TEST_CHECK(info.num_pieces() == num_pieces);
char piece[piece_size]; char piece[piece_size];