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 per second
* optimized memory usage when checking files fails * optimized memory usage when checking files fails
* fixed bug when checking a torrent twice * fixed bug when checking a torrent twice
* improved handling of out-of-memory conditions in disk I/O thread
release 0.14.3 release 0.14.3

View File

@ -304,7 +304,7 @@ namespace libtorrent
int flush_contiguous_blocks(disk_io_thread::cache_t::iterator e int flush_contiguous_blocks(disk_io_thread::cache_t::iterator e
, mutex_t::scoped_lock& l); , mutex_t::scoped_lock& l);
void flush_range(cache_t::iterator i, int start, int end, 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 // read cache operations
int clear_oldest_read_piece(cache_t::iterator ignore int clear_oldest_read_piece(cache_t::iterator ignore

View File

@ -677,7 +677,8 @@ namespace libtorrent
#endif #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; INVARIANT_CHECK;
TORRENT_ASSERT(find_cached_piece(m_pieces, j, l) == m_pieces.end()); TORRENT_ASSERT(find_cached_piece(m_pieces, j, l) == m_pieces.end());
@ -694,13 +695,15 @@ namespace libtorrent
p.storage = j.storage; p.storage = j.storage;
p.last_use = time_now(); p.last_use = time_now();
p.num_blocks = 1; 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*)); std::memset(&p.blocks[0], 0, blocks_in_piece * sizeof(char*));
int block = j.offset / m_block_size; 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; // 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; p.blocks[block] = j.buffer;
++m_cache_stats.cache_size; ++m_cache_stats.cache_size;
m_pieces.push_back(p); m_pieces.push_back(p);
return 0;
} }
enum read_options_t enum read_options_t
@ -747,7 +750,7 @@ namespace libtorrent
file::iovec_t* iov = 0; file::iovec_t* iov = 0;
int iov_counter = 0; int iov_counter = 0;
if (m_settings.coalesce_reads) buf.reset(new (std::nothrow) char[buffer_size]); 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; int ret = 0;
if (buf) if (buf)
@ -854,7 +857,8 @@ namespace libtorrent
p.storage = j.storage; p.storage = j.storage;
p.last_use = time_now(); p.last_use = time_now();
p.num_blocks = 0; 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*)); std::memset(&p.blocks[0], 0, blocks_in_piece * sizeof(char*));
int ret = read_into_piece(p, 0, ignore_cache_size, l); int ret = read_into_piece(p, 0, ignore_cache_size, l);
@ -885,7 +889,8 @@ namespace libtorrent
p.storage = j.storage; p.storage = j.storage;
p.last_use = time_now(); p.last_use = time_now();
p.num_blocks = 0; 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*)); std::memset(&p.blocks[0], 0, blocks_in_piece * sizeof(char*));
int ret = read_into_piece(p, start_block, 0, l); int ret = read_into_piece(p, start_block, 0, l);
@ -1482,7 +1487,16 @@ namespace libtorrent
} }
else 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 // we've now inserted the buffer
// in the cache, we should not // in the cache, we should not