diff --git a/include/libtorrent/block_cache.hpp b/include/libtorrent/block_cache.hpp index d0b734cb1..409e13bfc 100644 --- a/include/libtorrent/block_cache.hpp +++ b/include/libtorrent/block_cache.hpp @@ -345,9 +345,6 @@ namespace libtorrent int pad_job(disk_io_job const* j, int blocks_in_piece , int read_ahead) const; - int allocate_iovec(file::iovec_t* iov, int iov_len); - void free_iovec(file::iovec_t* iov, int iov_len); - void reclaim_block(block_cache_reference const& ref); // returns a range of all pieces. This migh be a very diff --git a/include/libtorrent/disk_buffer_pool.hpp b/include/libtorrent/disk_buffer_pool.hpp index b0a34bc7e..e9a0206f7 100644 --- a/include/libtorrent/disk_buffer_pool.hpp +++ b/include/libtorrent/disk_buffer_pool.hpp @@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/config.hpp" #include "libtorrent/thread.hpp" #include "libtorrent/io_service_fwd.hpp" +#include "libtorrent/file.hpp" // for iovec_t #include #include #include @@ -73,13 +74,18 @@ namespace libtorrent // tries to allocate a disk buffer. If the cache is full, this function will // return NULL and call the disk_observer once a buffer becomes available - char* async_allocate_buffer(char const* category, boost::function const& handler); + char* async_allocate_buffer(char const* category + , boost::function const& handler); char* allocate_buffer(char const* category); - char* allocate_buffer(bool& exceeded, boost::shared_ptr o, char const* category); + char* allocate_buffer(bool& exceeded, boost::shared_ptr o + , char const* category); void free_buffer(char* buf); void free_multiple_buffers(char** bufvec, int numbufs); + int allocate_iovec(file::iovec_t* iov, int iov_len); + void free_iovec(file::iovec_t* iov, int iov_len); + int block_size() const { return m_block_size; } void release_memory(); diff --git a/src/block_cache.cpp b/src/block_cache.cpp index 03a4262a8..1ec574ee5 100644 --- a/src/block_cache.cpp +++ b/src/block_cache.cpp @@ -1109,33 +1109,6 @@ int block_cache::pad_job(disk_io_job const* j, int blocks_in_piece return end - start; } -// this function allocates buffers and -// fills in the iovec array with the buffers -int block_cache::allocate_iovec(file::iovec_t* iov, int iov_len) -{ - for (int i = 0; i < iov_len; ++i) - { - iov[i].iov_base = allocate_buffer("pending read"); - iov[i].iov_len = block_size(); - if (iov[i].iov_base == NULL) - { - // uh oh. We failed to allocate the buffer! - // we need to roll back and free all the buffers - // we've already allocated - for (int j = 0; j < i; ++j) - free_buffer((char*)iov[j].iov_base); - return -1; - } - } - return 0; -} - -void block_cache::free_iovec(file::iovec_t* iov, int iov_len) -{ - for (int i = 0; i < iov_len; ++i) - free_buffer((char*)iov[i].iov_base); -} - void block_cache::insert_blocks(cached_piece_entry* pe, int block, file::iovec_t *iov , int iov_len, disk_io_job* j, int flags) { diff --git a/src/disk_buffer_pool.cpp b/src/disk_buffer_pool.cpp index d448dc575..18662301b 100644 --- a/src/disk_buffer_pool.cpp +++ b/src/disk_buffer_pool.cpp @@ -302,6 +302,37 @@ namespace libtorrent return ret; } +// this function allocates buffers and +// fills in the iovec array with the buffers + int disk_buffer_pool::allocate_iovec(file::iovec_t* iov, int iov_len) + { + mutex::scoped_lock l(m_pool_mutex); + for (int i = 0; i < iov_len; ++i) + { + iov[i].iov_base = allocate_buffer_impl(l, "pending read"); + iov[i].iov_len = block_size(); + if (iov[i].iov_base == NULL) + { + // uh oh. We failed to allocate the buffer! + // we need to roll back and free all the buffers + // we've already allocated + for (int j = 0; j < i; ++j) + free_buffer_impl((char*)iov[j].iov_base, l); + return -1; + } + } + return 0; + } + + void disk_buffer_pool::free_iovec(file::iovec_t* iov, int iov_len) + { + // TODO: perhaps we should sort the buffers here? + mutex::scoped_lock l(m_pool_mutex); + for (int i = 0; i < iov_len; ++i) + free_buffer_impl((char*)iov[i].iov_base, l); + check_buffer_level(l); + } + char* disk_buffer_pool::allocate_buffer_impl(mutex::scoped_lock& l, char const* category) { TORRENT_ASSERT(m_settings_set); @@ -311,7 +342,8 @@ namespace libtorrent #if TORRENT_HAVE_MMAP if (m_cache_pool) { - if (m_free_list.size() <= (m_max_use - m_low_watermark) / 2 && !m_exceeded_max_size) + if (m_free_list.size() <= (m_max_use - m_low_watermark) + / 2 && !m_exceeded_max_size) { m_exceeded_max_size = true; m_trigger_cache_trim(); @@ -368,7 +400,8 @@ namespace libtorrent #endif ++m_in_use; - if (m_in_use >= m_low_watermark + (m_max_use - m_low_watermark) / 2 && !m_exceeded_max_size) + if (m_in_use >= m_low_watermark + (m_max_use - m_low_watermark) + / 2 && !m_exceeded_max_size) { m_exceeded_max_size = true; m_trigger_cache_trim(); @@ -409,7 +442,6 @@ namespace libtorrent { mutex::scoped_lock l(m_pool_mutex); free_buffer_impl(buf, l); - check_buffer_level(l); }