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:
parent
4f2d147e07
commit
87eb377b17
|
@ -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
|
||||||
|
|
|
@ -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 == ':');
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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];
|
||||||
|
|
Loading…
Reference in New Issue