diff --git a/include/libtorrent/storage.hpp b/include/libtorrent/storage.hpp index 8cdab5476..e52196c76 100755 --- a/include/libtorrent/storage.hpp +++ b/include/libtorrent/storage.hpp @@ -201,7 +201,8 @@ namespace libtorrent void async_read( peer_request const& r - , boost::function const& handler); + , boost::function const& handler + , char* buffer = 0); void async_write( peer_request const& r diff --git a/src/disk_io_thread.cpp b/src/disk_io_thread.cpp index 6bc357506..e07a884cf 100644 --- a/src/disk_io_thread.cpp +++ b/src/disk_io_thread.cpp @@ -179,29 +179,35 @@ namespace libtorrent int ret = 0; + bool free_buffer = true; try { // std::cerr << "DISK THREAD: executing job: " << j.action << std::endl; switch (j.action) { case disk_io_job::read: - l.lock(); - j.buffer = (char*)m_pool.ordered_malloc(); - l.unlock(); if (j.buffer == 0) { - ret = -1; - j.str = "out of memory"; + l.lock(); + j.buffer = (char*)m_pool.ordered_malloc(); + l.unlock(); + assert(j.buffer_size <= m_block_size); + if (j.buffer == 0) + { + ret = -1; + j.str = "out of memory"; + break; + } } else { - assert(j.buffer_size <= m_block_size); - ret = j.storage->read_impl(j.buffer, j.piece, j.offset - , j.buffer_size); - - // simulates slow drives - // usleep(300); + free_buffer = false; } + ret = j.storage->read_impl(j.buffer, j.piece, j.offset + , j.buffer_size); + + // simulates slow drives + // usleep(300); break; case disk_io_job::write: assert(j.buffer); @@ -240,7 +246,7 @@ namespace libtorrent try { if (handler) handler(ret, j); } catch (std::exception&) {} - if (j.buffer) + if (j.buffer && free_buffer) { l.lock(); m_pool.ordered_free(j.buffer); diff --git a/src/http_connection.cpp b/src/http_connection.cpp index 788fc3aff..2b306ca6d 100644 --- a/src/http_connection.cpp +++ b/src/http_connection.cpp @@ -42,6 +42,8 @@ using boost::bind; namespace libtorrent { + enum { max_bottled_buffer = 1024 * 1024 }; + void http_connection::get(std::string const& url, time_duration timeout , bool handle_redirect) { @@ -311,8 +313,8 @@ void http_connection::on_read(asio::error_code const& e } if (int(m_recvbuffer.size()) == m_read_pos) - m_recvbuffer.resize((std::min)(m_read_pos + 2048, 1024*500)); - if (m_read_pos == 1024 * 500) + m_recvbuffer.resize((std::min)(m_read_pos + 2048, int(max_bottled_buffer))); + if (m_read_pos == max_bottled_buffer) { close(); if (m_bottled && m_called) return; diff --git a/src/storage.cpp b/src/storage.cpp index 62d75f38f..e1ddd20ae 100755 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -1083,7 +1083,8 @@ namespace libtorrent void piece_manager::async_read( peer_request const& r - , boost::function const& handler) + , boost::function const& handler + , char* buffer) { disk_io_job j; j.storage = this; @@ -1091,7 +1092,10 @@ namespace libtorrent j.piece = r.piece; j.offset = r.start; j.buffer_size = r.length; - assert(r.length <= 16 * 1024); + j.buffer = buffer; + // if a buffer is not specified, only one block can be read + // since that is the size of the pool allocator's buffers + assert(r.length <= 16 * 1024 || buffer != 0); m_io_thread.add_job(j, handler); }