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 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue