factor out handler allocator and reuse it for posting deferred peer removals on torrents
This commit is contained in:
parent
b88c193742
commit
254f813626
|
@ -83,7 +83,9 @@ namespace libtorrent { namespace aux {
|
|||
Handler h, handler_storage<Size>& s, error_handler_interface& eh)
|
||||
: handler(std::move(h))
|
||||
, storage(s)
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
, error_handler(eh)
|
||||
#endif
|
||||
{}
|
||||
|
||||
template <class... A>
|
||||
|
@ -142,9 +144,20 @@ namespace libtorrent { namespace aux {
|
|||
|
||||
Handler handler;
|
||||
handler_storage<Size>& storage;
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1168,24 +1168,6 @@ namespace aux {
|
|||
// outstanding requests need to increase at the same pace to keep up.
|
||||
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
|
||||
public:
|
||||
bool m_in_constructor = true;
|
||||
|
|
|
@ -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<torrent>
|
||||
{
|
||||
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<peer_connection> 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<peer_connection*> m_peers_to_disconnect;
|
||||
std::vector<std::shared_ptr<peer_connection>> 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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<peer_connection> 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<torrent> 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<torrent> 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<peer_connection*> peers;
|
||||
std::vector<std::shared_ptr<peer_connection>> 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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue