From 254f81362635c291a69c87a964f9100a2a52e9d6 Mon Sep 17 00:00:00 2001 From: arvidn Date: Fri, 10 Nov 2017 09:50:45 +0100 Subject: [PATCH] factor out handler allocator and reuse it for posting deferred peer removals on torrents --- .../libtorrent/aux_/allocating_handler.hpp | 13 ++++++++ include/libtorrent/peer_connection.hpp | 18 ----------- include/libtorrent/torrent.hpp | 10 +++++-- src/peer_connection.cpp | 12 ++++---- src/torrent.cpp | 30 ++++++++++++------- 5 files changed, 48 insertions(+), 35 deletions(-) diff --git a/include/libtorrent/aux_/allocating_handler.hpp b/include/libtorrent/aux_/allocating_handler.hpp index bf8ba1d7f..abbba3c77 100644 --- a/include/libtorrent/aux_/allocating_handler.hpp +++ b/include/libtorrent/aux_/allocating_handler.hpp @@ -83,7 +83,9 @@ namespace libtorrent { namespace aux { Handler h, handler_storage& s, error_handler_interface& eh) : handler(std::move(h)) , storage(s) +#ifndef BOOST_NO_EXCEPTIONS , error_handler(eh) +#endif {} template @@ -142,9 +144,20 @@ namespace libtorrent { namespace aux { Handler handler; handler_storage& storage; +#ifndef BOOST_NO_EXCEPTIONS error_handler_interface& error_handler; +#endif }; + template + aux::allocating_handler + make_handler(Handler const& handler + , handler_storage& storage + , error_handler_interface& err_handler) + { + return aux::allocating_handler( + handler, storage, err_handler); + } } } diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index 8926b448f..ce68941d5 100644 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -1168,24 +1168,6 @@ namespace aux { // outstanding requests need to increase at the same pace to keep up. bool m_slow_start:1; - template - aux::allocating_handler - make_read_handler(Handler const& handler) - { - return aux::allocating_handler( - handler, m_read_handler_storage, *this - ); - } - - template - aux::allocating_handler - make_write_handler(Handler const& handler) - { - return aux::allocating_handler( - handler, m_write_handler_storage, *this - ); - } - #if TORRENT_USE_ASSERTS public: bool m_in_constructor = true; diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index c907b843f..4c21dd4d7 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -72,6 +72,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/units.hpp" #include "libtorrent/aux_/vector.hpp" #include "libtorrent/aux_/deferred_handler.hpp" +#include "libtorrent/aux_/allocating_handler.hpp" #ifdef TORRENT_USE_OPENSSL // there is no forward declaration header for asio @@ -322,6 +323,7 @@ namespace libtorrent { , private torrent_hot_members , public request_callback , public peer_class_set + , public aux::error_handler_interface , public std::enable_shared_from_this { public: @@ -652,7 +654,7 @@ namespace libtorrent { // this will remove the peer and make sure all // the pieces it had have their reference counter // decreased in the piece_picker - void remove_peer(peer_connection* p); + void remove_peer(std::shared_ptr p); // cancel requests to this block from any peer we're // connected to on this torrent @@ -1149,6 +1151,9 @@ namespace libtorrent { private: + void on_exception(std::exception const& e) override; + void on_error(error_code const& ec) override; + // trigger deferred disconnection of peers void on_remove_peers(); @@ -1418,8 +1423,9 @@ namespace libtorrent { queue_position_t m_sequence_number; // used to post a message to defer disconnecting peers - std::vector m_peers_to_disconnect; + std::vector> m_peers_to_disconnect; aux::deferred_handler m_deferred_disconnect; + aux::handler_storage<24> m_deferred_handler_storage; // for torrents who have a bandwidth limit, this is != 0 // and refers to a peer_class in the session. diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 59cab1fdc..bd9c1dde6 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -4329,7 +4329,7 @@ namespace libtorrent { #if TORRENT_USE_INVARIANT_CHECKS check_invariant(); #endif - t->remove_peer(this); + t->remove_peer(self()); // we need to do this here to maintain accurate accounting of number of // unchoke slots. Ideally the updating of choked state and the @@ -5590,8 +5590,9 @@ namespace libtorrent { m_socket_is_writing = true; #endif - m_socket->async_write_some(vec, make_write_handler(std::bind( - &peer_connection::on_send_data, self(), _1, _2))); + m_socket->async_write_some(vec, make_handler(std::bind( + &peer_connection::on_send_data, self(), _1, _2) + , m_write_handler_storage, *this)); m_channel_state[upload_channel] |= peer_info::bw_network; m_last_sent = aux::time_now(); @@ -5675,8 +5676,9 @@ namespace libtorrent { // utp sockets aren't thread safe... ADD_OUTSTANDING_ASYNC("peer_connection::on_receive_data"); m_socket->async_read_some( - boost::asio::mutable_buffers_1(vec.data(), vec.size()), make_read_handler( - std::bind(&peer_connection::on_receive_data, self(), _1, _2))); + boost::asio::mutable_buffers_1(vec.data(), vec.size()), make_handler( + std::bind(&peer_connection::on_receive_data, self(), _1, _2) + , m_read_handler_storage, *this)); } piece_block_progress peer_connection::downloading_piece_progress() const diff --git a/src/torrent.cpp b/src/torrent.cpp index e309b17f4..93d2bc549 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -5422,6 +5422,16 @@ namespace libtorrent { #endif + void torrent::on_exception(std::exception const&) + { + set_error(errors::no_memory, torrent_status::error_file_none); + } + + void torrent::on_error(error_code const& ec) + { + set_error(ec, torrent_status::error_file_none); + } + void torrent::remove_connection(peer_connection const* p) { TORRENT_ASSERT(m_iterating_connections == 0); @@ -5430,9 +5440,9 @@ namespace libtorrent { m_connections.erase(i); } - void torrent::remove_peer(peer_connection* p) + void torrent::remove_peer(std::shared_ptr p) { - TORRENT_ASSERT(p != nullptr); + TORRENT_ASSERT(p); TORRENT_ASSERT(is_single_thread()); TORRENT_ASSERT(std::count(m_peers_to_disconnect.begin() , m_peers_to_disconnect.end(), p) == 0); @@ -5452,18 +5462,18 @@ namespace libtorrent { { std::weak_ptr weak_t = shared_from_this(); m_peers_to_disconnect.push_back(p); - m_deferred_disconnect.post(m_ses.get_io_service(), [=]() + m_deferred_disconnect.post(m_ses.get_io_service(), aux::make_handler([=]() { std::shared_ptr t = weak_t.lock(); if (t) t->on_remove_peers(); - }); + }, m_deferred_handler_storage, *this)); } else { // if the peer was inserted in m_connections but instructed to // be removed from this torrent, just remove it from it, see // attach_peer logic. - remove_connection(p); + remove_connection(p.get()); } torrent_peer* pp = p->peer_info_struct(); @@ -5530,15 +5540,15 @@ namespace libtorrent { TORRENT_ASSERT(is_single_thread()); INVARIANT_CHECK; - std::vector peers; + std::vector> peers; m_peers_to_disconnect.swap(peers); for (auto p : peers) { - TORRENT_ASSERT(p != nullptr); + TORRENT_ASSERT(p); TORRENT_ASSERT(p->associated_torrent().lock().get() == this); - remove_connection(p); - m_ses.close_connection(p); + remove_connection(p.get()); + m_ses.close_connection(p.get()); } if (m_graceful_pause_mode && m_connections.empty()) @@ -6977,7 +6987,7 @@ namespace libtorrent { // we have to do this here because from the peer's point of view // it wasn't really attached to the torrent, but we do need // to let peer_list know we're removing it - remove_peer(p); + remove_peer(p->self()); return false; } }