From a5a9006014ba07a0c1b4629013c5ae7b233eb633 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sat, 7 Apr 2012 00:35:25 +0000 Subject: [PATCH] merged fixes from RC_0_16 into trunk --- ChangeLog | 1 + include/libtorrent/disk_io_thread.hpp | 12 ++++++++++-- include/libtorrent/web_peer_connection.hpp | 2 ++ src/disk_io_thread.cpp | 12 +++++++----- src/torrent.cpp | 2 ++ src/web_peer_connection.cpp | 18 ++++++++++++++---- 6 files changed, 36 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9756d8bff..c772690d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -113,6 +113,7 @@ 0.15.11 release + * fixed web seed bug, sometimes causing infinite loops * fixed race condition when setting session_settings immediately after creating session * give up immediately when failing to open a listen socket (report the actual error) * restored ABI compatibility with 0.15.9 diff --git a/include/libtorrent/disk_io_thread.hpp b/include/libtorrent/disk_io_thread.hpp index d2ff26c12..2e98db2b2 100644 --- a/include/libtorrent/disk_io_thread.hpp +++ b/include/libtorrent/disk_io_thread.hpp @@ -328,10 +328,18 @@ namespace libtorrent int copy_from_piece(cached_piece_entry& p, bool& hit , disk_io_job const& j, mutex::scoped_lock& l); + struct ignore_t + { + ignore_t(): piece(-1), storage(0) {} + ignore_t(int idx, piece_manager* st): piece(idx), storage(st) {} + int piece; + piece_manager* storage; + }; + // write cache operations enum options_t { dont_flush_write_blocks = 1, ignore_cache_size = 2 }; int flush_cache_blocks(mutex::scoped_lock& l - , int blocks, int ignore = -1, int options = 0); + , int blocks, ignore_t ignore = ignore_t(), int options = 0); void flush_expired_pieces(); int flush_contiguous_blocks(cached_piece_entry& p , mutex::scoped_lock& l, int lower_limit = 0, bool avoid_readback = false); @@ -342,7 +350,7 @@ namespace libtorrent , mutex::scoped_lock& l); // read cache operations - int clear_oldest_read_piece(int num_blocks, int ignore + int clear_oldest_read_piece(int num_blocks, ignore_t ignore , mutex::scoped_lock& l); int read_into_piece(cached_piece_entry& p, int start_block , int options, int num_blocks, mutex::scoped_lock& l); diff --git a/include/libtorrent/web_peer_connection.hpp b/include/libtorrent/web_peer_connection.hpp index 3ff731802..4bf98f19f 100644 --- a/include/libtorrent/web_peer_connection.hpp +++ b/include/libtorrent/web_peer_connection.hpp @@ -122,6 +122,8 @@ namespace libtorrent // this is used for intermediate storage of pieces // that are received in more than one HTTP response + // TODO: if we make this be a disk_buffer_holder instead + // we would save a copy sometimes std::vector m_piece; // the number of bytes received in the current HTTP diff --git a/src/disk_io_thread.cpp b/src/disk_io_thread.cpp index d13a48bee..fa3367f87 100644 --- a/src/disk_io_thread.cpp +++ b/src/disk_io_thread.cpp @@ -338,7 +338,7 @@ namespace libtorrent // returns the number of blocks that were freed int disk_io_thread::clear_oldest_read_piece( - int num_blocks, int ignore, mutex::scoped_lock& l) + int num_blocks, ignore_t ignore, mutex::scoped_lock& l) { INVARIANT_CHECK; @@ -346,7 +346,7 @@ namespace libtorrent if (idx.empty()) return 0; cache_lru_index_t::iterator i = idx.begin(); - if (i->piece == ignore) + if (i->piece == ignore.piece && i->storage == ignore.storage) { ++i; if (i == idx.end()) return 0; @@ -480,7 +480,7 @@ namespace libtorrent // flushes 'blocks' blocks from the cache int disk_io_thread::flush_cache_blocks(mutex::scoped_lock& l - , int blocks, int ignore, int options) + , int blocks, ignore_t ignore, int options) { // first look if there are any read cache entries that can // be cleared @@ -893,7 +893,8 @@ namespace libtorrent if (in_use() + blocks_to_read > m_settings.cache_size) { int clear = in_use() + blocks_to_read - m_settings.cache_size; - if (flush_cache_blocks(l, clear, j.piece, dont_flush_write_blocks) < clear) + if (flush_cache_blocks(l, clear, ignore_t(j.piece, j.storage.get()) + , dont_flush_write_blocks) < clear) return -2; } @@ -1187,7 +1188,8 @@ namespace libtorrent if (in_use() + blocks_to_read > m_settings.cache_size) { int clear = in_use() + blocks_to_read - m_settings.cache_size; - if (flush_cache_blocks(l, clear, p.piece, dont_flush_write_blocks) < clear) + if (flush_cache_blocks(l, clear, ignore_t(p.piece, p.storage.get()) + , dont_flush_write_blocks) < clear) return -2; } diff --git a/src/torrent.cpp b/src/torrent.cpp index 83c0bc276..ce952f4a4 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -1470,6 +1470,8 @@ namespace libtorrent // add cert to cert_store X509_STORE_add_cert(cert_store, certificate); + X509_free(certificate); + // and lastly, replace the default cert store with ours SSL_CTX_set_cert_store(ssl_ctx, cert_store); #if 0 diff --git a/src/web_peer_connection.cpp b/src/web_peer_connection.cpp index afb2c59ad..decbb1950 100644 --- a/src/web_peer_connection.cpp +++ b/src/web_peer_connection.cpp @@ -55,6 +55,11 @@ using libtorrent::aux::session_impl; namespace libtorrent { + enum + { + request_size_overhead = 5000 + }; + web_peer_connection::web_peer_connection( session_impl& ses , boost::weak_ptr t @@ -299,7 +304,7 @@ namespace libtorrent if (associated_torrent().expired()) return false; TORRENT_ASSERT(m_block_pos >= front_request.length); m_block_pos -= front_request.length; - cut_receive_buffer(m_body_start, t->block_size() + 5000); + cut_receive_buffer(m_body_start, t->block_size() + request_size_overhead); m_body_start = 0; recv_buffer = receive_buffer(); // TORRENT_ASSERT(m_received_body <= range_end - range_start); @@ -615,7 +620,7 @@ namespace libtorrent TORRENT_ASSERT(chunk_size != 0 || chunk_start.left() <= header_size || chunk_start.begin[header_size] == 'H'); // cut out the chunk header from the receive buffer TORRENT_ASSERT(m_body_start + m_chunk_pos < INT_MAX); - cut_receive_buffer(header_size, t->block_size() + 5000, int(m_body_start + m_chunk_pos)); + cut_receive_buffer(header_size, t->block_size() + request_size_overhead, int(m_body_start + m_chunk_pos)); recv_buffer = receive_buffer(); recv_buffer.begin += m_body_start; m_chunk_pos += chunk_size; @@ -712,6 +717,7 @@ namespace libtorrent if (copy_size > m_chunk_pos && m_chunk_pos > 0) copy_size = m_chunk_pos; if (copy_size > 0) { + TORRENT_ASSERT(m_piece.size() == m_received_in_piece); m_piece.resize(piece_size + copy_size); std::memcpy(&m_piece[0] + piece_size, recv_buffer.begin, copy_size); TORRENT_ASSERT(int(m_piece.size()) <= front_request.length); @@ -726,6 +732,7 @@ namespace libtorrent TORRENT_ASSERT(m_received_body <= range_end - range_start); TORRENT_ASSERT(int(m_piece.size()) <= front_request.length); incoming_piece_fragment(copy_size); + TORRENT_ASSERT(m_piece.size() == m_received_in_piece); } if (maybe_harvest_block()) @@ -750,7 +757,7 @@ namespace libtorrent m_received_body += r.length; TORRENT_ASSERT(receive_buffer().begin + m_body_start == recv_buffer.begin); TORRENT_ASSERT(m_received_body <= range_end - range_start); - cut_receive_buffer(m_body_start + r.length, t->block_size() + 5000); + cut_receive_buffer(m_body_start + r.length, t->block_size() + request_size_overhead); if (m_chunk_pos > 0) { TORRENT_ASSERT(m_chunk_pos >= r.length); @@ -774,11 +781,14 @@ namespace libtorrent TORRENT_ASSERT(copy_size >= 0); if (copy_size > 0) { + TORRENT_ASSERT(m_piece.size() == m_received_in_piece); m_piece.resize(piece_size + copy_size); std::memcpy(&m_piece[0] + piece_size, recv_buffer.begin, copy_size); recv_buffer.begin += copy_size; m_received_body += copy_size; m_body_start += copy_size; + incoming_piece_fragment(copy_size); + TORRENT_ASSERT(m_piece.size() == m_received_in_piece); } TORRENT_ASSERT(m_received_body == range_end - range_start); } @@ -797,7 +807,7 @@ namespace libtorrent TORRENT_ASSERT(receive_buffer().left() < size_to_cut + 1 || receive_buffer()[size_to_cut] == 'H'); - cut_receive_buffer(size_to_cut, t->block_size() + 5000); + cut_receive_buffer(size_to_cut, t->block_size() + request_size_overhead); if (m_chunk_pos > 0) { TORRENT_ASSERT(m_chunk_pos >= size_to_cut);