factor out handler allocator and reuse it for posting deferred peer removals on torrents

This commit is contained in:
arvidn 2017-11-10 09:50:45 +01:00 committed by Arvid Norberg
parent b88c193742
commit 254f813626
5 changed files with 48 additions and 35 deletions

View File

@ -83,7 +83,9 @@ namespace libtorrent { namespace aux {
Handler h, handler_storage<Size>& s, error_handler_interface& eh) Handler h, handler_storage<Size>& s, error_handler_interface& eh)
: handler(std::move(h)) : handler(std::move(h))
, storage(s) , storage(s)
#ifndef BOOST_NO_EXCEPTIONS
, error_handler(eh) , error_handler(eh)
#endif
{} {}
template <class... A> template <class... A>
@ -142,9 +144,20 @@ namespace libtorrent { namespace aux {
Handler handler; Handler handler;
handler_storage<Size>& storage; handler_storage<Size>& storage;
#ifndef BOOST_NO_EXCEPTIONS
error_handler_interface& error_handler; error_handler_interface& error_handler;
#endif
}; };
template <class Handler, size_t Size>
aux::allocating_handler<Handler, Size>
make_handler(Handler const& handler
, handler_storage<Size>& storage
, error_handler_interface& err_handler)
{
return aux::allocating_handler<Handler, Size>(
handler, storage, err_handler);
}
} }
} }

View File

@ -1168,24 +1168,6 @@ namespace aux {
// outstanding requests need to increase at the same pace to keep up. // outstanding requests need to increase at the same pace to keep up.
bool m_slow_start:1; bool m_slow_start:1;
template <class Handler>
aux::allocating_handler<Handler, TORRENT_READ_HANDLER_MAX_SIZE>
make_read_handler(Handler const& handler)
{
return aux::allocating_handler<Handler, TORRENT_READ_HANDLER_MAX_SIZE>(
handler, m_read_handler_storage, *this
);
}
template <class Handler>
aux::allocating_handler<Handler, TORRENT_WRITE_HANDLER_MAX_SIZE>
make_write_handler(Handler const& handler)
{
return aux::allocating_handler<Handler, TORRENT_WRITE_HANDLER_MAX_SIZE>(
handler, m_write_handler_storage, *this
);
}
#if TORRENT_USE_ASSERTS #if TORRENT_USE_ASSERTS
public: public:
bool m_in_constructor = true; bool m_in_constructor = true;

View File

@ -72,6 +72,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/units.hpp" #include "libtorrent/units.hpp"
#include "libtorrent/aux_/vector.hpp" #include "libtorrent/aux_/vector.hpp"
#include "libtorrent/aux_/deferred_handler.hpp" #include "libtorrent/aux_/deferred_handler.hpp"
#include "libtorrent/aux_/allocating_handler.hpp"
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
// there is no forward declaration header for asio // there is no forward declaration header for asio
@ -322,6 +323,7 @@ namespace libtorrent {
, private torrent_hot_members , private torrent_hot_members
, public request_callback , public request_callback
, public peer_class_set , public peer_class_set
, public aux::error_handler_interface
, public std::enable_shared_from_this<torrent> , public std::enable_shared_from_this<torrent>
{ {
public: public:
@ -652,7 +654,7 @@ namespace libtorrent {
// this will remove the peer and make sure all // this will remove the peer and make sure all
// the pieces it had have their reference counter // the pieces it had have their reference counter
// decreased in the piece_picker // decreased in the piece_picker
void remove_peer(peer_connection* p); void remove_peer(std::shared_ptr<peer_connection> p);
// cancel requests to this block from any peer we're // cancel requests to this block from any peer we're
// connected to on this torrent // connected to on this torrent
@ -1149,6 +1151,9 @@ namespace libtorrent {
private: private:
void on_exception(std::exception const& e) override;
void on_error(error_code const& ec) override;
// trigger deferred disconnection of peers // trigger deferred disconnection of peers
void on_remove_peers(); void on_remove_peers();
@ -1418,8 +1423,9 @@ namespace libtorrent {
queue_position_t m_sequence_number; queue_position_t m_sequence_number;
// used to post a message to defer disconnecting peers // used to post a message to defer disconnecting peers
std::vector<peer_connection*> m_peers_to_disconnect; std::vector<std::shared_ptr<peer_connection>> m_peers_to_disconnect;
aux::deferred_handler m_deferred_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 // for torrents who have a bandwidth limit, this is != 0
// and refers to a peer_class in the session. // and refers to a peer_class in the session.

View File

@ -4329,7 +4329,7 @@ namespace libtorrent {
#if TORRENT_USE_INVARIANT_CHECKS #if TORRENT_USE_INVARIANT_CHECKS
check_invariant(); check_invariant();
#endif #endif
t->remove_peer(this); t->remove_peer(self());
// we need to do this here to maintain accurate accounting of number of // we need to do this here to maintain accurate accounting of number of
// unchoke slots. Ideally the updating of choked state and the // unchoke slots. Ideally the updating of choked state and the
@ -5590,8 +5590,9 @@ namespace libtorrent {
m_socket_is_writing = true; m_socket_is_writing = true;
#endif #endif
m_socket->async_write_some(vec, make_write_handler(std::bind( m_socket->async_write_some(vec, make_handler(std::bind(
&peer_connection::on_send_data, self(), _1, _2))); &peer_connection::on_send_data, self(), _1, _2)
, m_write_handler_storage, *this));
m_channel_state[upload_channel] |= peer_info::bw_network; m_channel_state[upload_channel] |= peer_info::bw_network;
m_last_sent = aux::time_now(); m_last_sent = aux::time_now();
@ -5675,8 +5676,9 @@ namespace libtorrent {
// utp sockets aren't thread safe... // utp sockets aren't thread safe...
ADD_OUTSTANDING_ASYNC("peer_connection::on_receive_data"); ADD_OUTSTANDING_ASYNC("peer_connection::on_receive_data");
m_socket->async_read_some( m_socket->async_read_some(
boost::asio::mutable_buffers_1(vec.data(), vec.size()), make_read_handler( boost::asio::mutable_buffers_1(vec.data(), vec.size()), make_handler(
std::bind(&peer_connection::on_receive_data, self(), _1, _2))); std::bind(&peer_connection::on_receive_data, self(), _1, _2)
, m_read_handler_storage, *this));
} }
piece_block_progress peer_connection::downloading_piece_progress() const piece_block_progress peer_connection::downloading_piece_progress() const

View File

@ -5422,6 +5422,16 @@ namespace libtorrent {
#endif #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) void torrent::remove_connection(peer_connection const* p)
{ {
TORRENT_ASSERT(m_iterating_connections == 0); TORRENT_ASSERT(m_iterating_connections == 0);
@ -5430,9 +5440,9 @@ namespace libtorrent {
m_connections.erase(i); m_connections.erase(i);
} }
void torrent::remove_peer(peer_connection* p) void torrent::remove_peer(std::shared_ptr<peer_connection> p)
{ {
TORRENT_ASSERT(p != nullptr); TORRENT_ASSERT(p);
TORRENT_ASSERT(is_single_thread()); TORRENT_ASSERT(is_single_thread());
TORRENT_ASSERT(std::count(m_peers_to_disconnect.begin() TORRENT_ASSERT(std::count(m_peers_to_disconnect.begin()
, m_peers_to_disconnect.end(), p) == 0); , m_peers_to_disconnect.end(), p) == 0);
@ -5452,18 +5462,18 @@ namespace libtorrent {
{ {
std::weak_ptr<torrent> weak_t = shared_from_this(); std::weak_ptr<torrent> weak_t = shared_from_this();
m_peers_to_disconnect.push_back(p); 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<torrent> t = weak_t.lock(); std::shared_ptr<torrent> t = weak_t.lock();
if (t) t->on_remove_peers(); if (t) t->on_remove_peers();
}); }, m_deferred_handler_storage, *this));
} }
else else
{ {
// if the peer was inserted in m_connections but instructed to // if the peer was inserted in m_connections but instructed to
// be removed from this torrent, just remove it from it, see // be removed from this torrent, just remove it from it, see
// attach_peer logic. // attach_peer logic.
remove_connection(p); remove_connection(p.get());
} }
torrent_peer* pp = p->peer_info_struct(); torrent_peer* pp = p->peer_info_struct();
@ -5530,15 +5540,15 @@ namespace libtorrent {
TORRENT_ASSERT(is_single_thread()); TORRENT_ASSERT(is_single_thread());
INVARIANT_CHECK; INVARIANT_CHECK;
std::vector<peer_connection*> peers; std::vector<std::shared_ptr<peer_connection>> peers;
m_peers_to_disconnect.swap(peers); m_peers_to_disconnect.swap(peers);
for (auto p : peers) for (auto p : peers)
{ {
TORRENT_ASSERT(p != nullptr); TORRENT_ASSERT(p);
TORRENT_ASSERT(p->associated_torrent().lock().get() == this); TORRENT_ASSERT(p->associated_torrent().lock().get() == this);
remove_connection(p); remove_connection(p.get());
m_ses.close_connection(p); m_ses.close_connection(p.get());
} }
if (m_graceful_pause_mode && m_connections.empty()) 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 // 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 // it wasn't really attached to the torrent, but we do need
// to let peer_list know we're removing it // to let peer_list know we're removing it
remove_peer(p); remove_peer(p->self());
return false; return false;
} }
} }