improved handling of out-of-memory conditions in disk I/O thread

This commit is contained in:
Arvid Norberg 2009-05-23 18:39:55 +00:00
parent e197f5cb85
commit e322b318ae
3 changed files with 22 additions and 7 deletions

View File

@ -66,6 +66,7 @@ release 0.14.4
per second
* optimized memory usage when checking files fails
* fixed bug when checking a torrent twice
* improved handling of out-of-memory conditions in disk I/O thread
release 0.14.3

View File

@ -304,7 +304,7 @@ namespace libtorrent
int flush_contiguous_blocks(disk_io_thread::cache_t::iterator e
, mutex_t::scoped_lock& l);
void flush_range(cache_t::iterator i, int start, int end, mutex_t::scoped_lock& l);
void cache_block(disk_io_job& j, mutex_t::scoped_lock& l);
int cache_block(disk_io_job& j, mutex_t::scoped_lock& l);
// read cache operations
int clear_oldest_read_piece(cache_t::iterator ignore

View File

@ -677,7 +677,8 @@ namespace libtorrent
#endif
}
void disk_io_thread::cache_block(disk_io_job& j, mutex_t::scoped_lock& l)
// returns -1 on failure
int disk_io_thread::cache_block(disk_io_job& j, mutex_t::scoped_lock& l)
{
INVARIANT_CHECK;
TORRENT_ASSERT(find_cached_piece(m_pieces, j, l) == m_pieces.end());
@ -694,13 +695,15 @@ namespace libtorrent
p.storage = j.storage;
p.last_use = time_now();
p.num_blocks = 1;
p.blocks.reset(new char*[blocks_in_piece]);
p.blocks.reset(new (std::nothrow) char*[blocks_in_piece]);
if (!p.blocks) return -1;
std::memset(&p.blocks[0], 0, blocks_in_piece * sizeof(char*));
int block = j.offset / m_block_size;
// std::cerr << " adding cache entry for p: " << j.piece << " block: " << block << " cached_blocks: " << m_cache_stats.cache_size << std::endl;
p.blocks[block] = j.buffer;
++m_cache_stats.cache_size;
m_pieces.push_back(p);
return 0;
}
enum read_options_t
@ -747,7 +750,7 @@ namespace libtorrent
file::iovec_t* iov = 0;
int iov_counter = 0;
if (m_settings.coalesce_reads) buf.reset(new (std::nothrow) char[buffer_size]);
else iov = TORRENT_ALLOCA(file::iovec_t, end_block - start_block);
if (!buf) iov = TORRENT_ALLOCA(file::iovec_t, end_block - start_block);
int ret = 0;
if (buf)
@ -854,7 +857,8 @@ namespace libtorrent
p.storage = j.storage;
p.last_use = time_now();
p.num_blocks = 0;
p.blocks.reset(new char*[blocks_in_piece]);
p.blocks.reset(new (std::nothrow) char*[blocks_in_piece]);
if (!p.blocks) return -1;
std::memset(&p.blocks[0], 0, blocks_in_piece * sizeof(char*));
int ret = read_into_piece(p, 0, ignore_cache_size, l);
@ -885,7 +889,8 @@ namespace libtorrent
p.storage = j.storage;
p.last_use = time_now();
p.num_blocks = 0;
p.blocks.reset(new char*[blocks_in_piece]);
p.blocks.reset(new (std::nothrow) char*[blocks_in_piece]);
if (!p.blocks) return -1;
std::memset(&p.blocks[0], 0, blocks_in_piece * sizeof(char*));
int ret = read_into_piece(p, start_block, 0, l);
@ -1482,7 +1487,16 @@ namespace libtorrent
}
else
{
cache_block(j, l);
if (cache_block(j, l) < 0)
{
file::iovec_t iov = {j.buffer, j.buffer_size};
ret = j.storage->write_impl(&iov, j.piece, j.offset, 1);
if (ret < 0)
{
test_error(j);
break;
}
}
}
// we've now inserted the buffer
// in the cache, we should not