diff --git a/include/libtorrent/block_cache.hpp b/include/libtorrent/block_cache.hpp index 45fce7a5c..6e0d77631 100644 --- a/include/libtorrent/block_cache.hpp +++ b/include/libtorrent/block_cache.hpp @@ -440,7 +440,8 @@ namespace libtorrent // used to convert dirty blocks into non-dirty ones // i.e. from being part of the write cache to being part // of the read cache. it's used when flushing blocks to disk - void blocks_flushed(cached_piece_entry* pe, int const* flushed, int num_flushed); + // returns true if the piece entry was freed + bool blocks_flushed(cached_piece_entry* pe, int const* flushed, int num_flushed); // adds a block to the cache, marks it as dirty and // associates the job with it. When the block is diff --git a/include/libtorrent/disk_io_thread.hpp b/include/libtorrent/disk_io_thread.hpp index 4000924d2..aad057c00 100644 --- a/include/libtorrent/disk_io_thread.hpp +++ b/include/libtorrent/disk_io_thread.hpp @@ -477,7 +477,8 @@ namespace libtorrent , file::iovec_t* iov, int* flushing, int block_base_index = 0); void flush_iovec(cached_piece_entry* pe, file::iovec_t const* iov, int const* flushing , int num_blocks, storage_error& error); - void iovec_flushed(cached_piece_entry* pe + // returns true if the piece entry was freed + bool iovec_flushed(cached_piece_entry* pe , int* flushing, int num_blocks, int block_offset , storage_error const& error , jobqueue_t& completed_jobs); diff --git a/src/block_cache.cpp b/src/block_cache.cpp index 26b76e2d9..59ba2a1a8 100644 --- a/src/block_cache.cpp +++ b/src/block_cache.cpp @@ -793,7 +793,7 @@ cached_piece_entry* block_cache::add_dirty_block(disk_io_job* j) // (since these blocks now are part of the read cache) the refcounts of the // blocks are also decremented by this function. They are expected to have been // incremented by the caller. -void block_cache::blocks_flushed(cached_piece_entry* pe, int const* flushed, int num_flushed) +bool block_cache::blocks_flushed(cached_piece_entry* pe, int const* flushed, int num_flushed) { TORRENT_PIECE_ASSERT(pe->in_use, pe); @@ -817,7 +817,7 @@ void block_cache::blocks_flushed(cached_piece_entry* pe, int const* flushed, int pe->num_dirty -= num_flushed; update_cache_state(pe); - maybe_free_piece(pe); + return maybe_free_piece(pe); } std::pair block_cache::all_pieces() const diff --git a/src/disk_io_thread.cpp b/src/disk_io_thread.cpp index 2d4bbd704..a6189c26f 100644 --- a/src/disk_io_thread.cpp +++ b/src/disk_io_thread.cpp @@ -676,7 +676,7 @@ namespace libtorrent // It is necessary to call this function with the blocks produced by // build_iovec, to reset their state to not being flushed anymore // the cache needs to be locked when calling this function - void disk_io_thread::iovec_flushed(cached_piece_entry* pe + bool disk_io_thread::iovec_flushed(cached_piece_entry* pe , int* flushing, int num_blocks, int block_offset , storage_error const& error , jobqueue_t& completed_jobs) @@ -691,7 +691,8 @@ namespace libtorrent DLOG("%d ", flushing[i]); DLOG("]\n"); #endif - m_disk_cache.blocks_flushed(pe, flushing, num_blocks); + if (m_disk_cache.blocks_flushed(pe, flushing, num_blocks)) + return true; int block_size = m_disk_cache.block_size(); @@ -721,6 +722,8 @@ namespace libtorrent j = next; } } + + return false; } // issues write operations for blocks in the given @@ -756,9 +759,8 @@ namespace libtorrent TORRENT_PIECE_ASSERT(pe->piece_refcount > 0, pe); --pe->piece_refcount; - iovec_flushed(pe, flushing, iov_len, 0, error, completed_jobs); - - m_disk_cache.maybe_free_piece(pe); + if (!iovec_flushed(pe, flushing, iov_len, 0, error, completed_jobs)) + m_disk_cache.maybe_free_piece(pe); // if the cache is under high pressure, we need to evict // the blocks we just flushed to make room for more write pieces