forked from premiere/premiere-libtorrent
fixed handling of unaligned block requests
This commit is contained in:
parent
524151c040
commit
3e7bd46706
|
@ -743,6 +743,7 @@ namespace libtorrent
|
|||
{
|
||||
INVARIANT_CHECK;
|
||||
TORRENT_ASSERT(find_cached_piece(m_pieces, j, l) == m_pieces.end());
|
||||
TORRENT_ASSERT((j.offset & (m_block_size-1)) == 0);
|
||||
cached_piece_entry p;
|
||||
|
||||
#ifdef TORRENT_DISK_STATS
|
||||
|
@ -1088,25 +1089,35 @@ namespace libtorrent
|
|||
int block_offset = j.offset & (m_block_size-1);
|
||||
int buffer_offset = 0;
|
||||
int size = j.buffer_size;
|
||||
if (p->blocks[block] == 0)
|
||||
int min_blocks_to_read = block_offset > 0 ? 2 : 1;
|
||||
TORRENT_ASSERT(size <= m_block_size);
|
||||
int start_block = block;
|
||||
if (p->blocks[start_block] != 0 && min_blocks_to_read > 1)
|
||||
++start_block;
|
||||
// if block_offset > 0, we need to read two blocks, and then
|
||||
// copy parts of both, because it's not aligned to the block
|
||||
// boundaries
|
||||
if (p->blocks[start_block] == 0)
|
||||
{
|
||||
int piece_size = j.storage->info()->piece_size(j.piece);
|
||||
int blocks_in_piece = (piece_size + m_block_size - 1) / m_block_size;
|
||||
int end_block = block;
|
||||
int end_block = start_block;
|
||||
while (end_block < blocks_in_piece && p->blocks[end_block] == 0) ++end_block;
|
||||
|
||||
int blocks_to_read = end_block - block;
|
||||
blocks_to_read = (std::min)(blocks_to_read, (std::max)((m_settings.cache_size
|
||||
+ m_cache_stats.read_cache_size - in_use())/2, 3));
|
||||
blocks_to_read = (std::min)(blocks_to_read, m_settings.read_cache_line_size);
|
||||
blocks_to_read = (std::max)(blocks_to_read, min_blocks_to_read);
|
||||
if (in_use() + blocks_to_read > m_settings.cache_size)
|
||||
if (flush_cache_blocks(l, in_use() + blocks_to_read - m_settings.cache_size
|
||||
, p, dont_flush_write_blocks) == 0)
|
||||
return -2;
|
||||
|
||||
size = read_into_piece(*p, block, 0, blocks_to_read, l);
|
||||
int ret = read_into_piece(*p, block, 0, blocks_to_read, l);
|
||||
hit = false;
|
||||
if (size < 0) return size;
|
||||
if (ret < 0) return ret;
|
||||
if (ret < size + block_offset) return -2;
|
||||
TORRENT_ASSERT(p->blocks[block]);
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
using namespace libtorrent;
|
||||
using namespace boost::filesystem;
|
||||
|
||||
const int piece_size = 16 * 1024;
|
||||
const int piece_size = 16 * 1024 * 16;
|
||||
const int block_size = 16 * 1024;
|
||||
|
||||
const int half = piece_size / 2;
|
||||
|
||||
|
@ -92,6 +93,19 @@ void on_check_files(int ret, disk_io_job const& j, bool* done)
|
|||
}
|
||||
}
|
||||
|
||||
void on_read(int ret, disk_io_job const& j, bool* done)
|
||||
{
|
||||
std::cerr << "on_read ret: " << ret;
|
||||
*done = true;
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
std::cerr << j.error.message() << std::endl;
|
||||
std::cerr << j.error_file << std::endl;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void on_move_storage(int ret, disk_io_job const& j, std::string path)
|
||||
{
|
||||
std::cerr << "on_move_storage ret: " << ret << " path: " << j.str << std::endl;
|
||||
|
@ -206,6 +220,18 @@ void run_storage_tests(boost::intrusive_ptr<torrent_info> info
|
|||
ios.run_one(ec);
|
||||
}
|
||||
|
||||
done = false;
|
||||
peer_request r;
|
||||
r.piece = 0;
|
||||
r.start = 10;
|
||||
r.length = 16 * 1024;
|
||||
pm->async_read(r, boost::bind(&on_read, _1, _2, &done));
|
||||
while (!done)
|
||||
{
|
||||
ios.reset();
|
||||
ios.run_one(ec);
|
||||
}
|
||||
|
||||
// test rename_file
|
||||
remove(test_path / "part0");
|
||||
TEST_CHECK(exists(test_path / "temp_storage/test1.tmp"));
|
||||
|
@ -246,15 +272,14 @@ void run_storage_tests(boost::intrusive_ptr<torrent_info> info
|
|||
TEST_CHECK(!exists(test_path / "temp_storage2/temp_storage"));
|
||||
TEST_CHECK(!exists(test_path / "temp_storage2/part0"));
|
||||
|
||||
peer_request r;
|
||||
r.piece = 0;
|
||||
r.start = 0;
|
||||
r.length = piece_size;
|
||||
pm->async_read(r, bind(&on_read_piece, _1, _2, piece0, piece_size));
|
||||
r.length = block_size;
|
||||
pm->async_read(r, bind(&on_read_piece, _1, _2, piece0, block_size));
|
||||
r.piece = 1;
|
||||
pm->async_read(r, bind(&on_read_piece, _1, _2, piece1, piece_size));
|
||||
pm->async_read(r, bind(&on_read_piece, _1, _2, piece1, block_size));
|
||||
r.piece = 2;
|
||||
pm->async_read(r, bind(&on_read_piece, _1, _2, piece2, piece_size));
|
||||
pm->async_read(r, bind(&on_read_piece, _1, _2, piece2, block_size));
|
||||
pm->async_release_files(none);
|
||||
|
||||
pm->async_rename_file(0, "temp_storage/test1.tmp", none);
|
||||
|
|
Loading…
Reference in New Issue