From aae12250aeaa5635404ac40c39953c5682d33e9a Mon Sep 17 00:00:00 2001 From: arvidn Date: Thu, 28 Dec 2017 00:09:12 +0100 Subject: [PATCH] support forced shutdown/destruction of torrent objects --- include/libtorrent/peer_list.hpp | 2 ++ include/libtorrent/torrent.hpp | 1 + include/libtorrent/torrent_peer.hpp | 2 +- src/peer_list.cpp | 7 +++++++ src/session_impl.cpp | 8 +++++++- src/torrent.cpp | 12 ++++++++++++ 6 files changed, 30 insertions(+), 2 deletions(-) diff --git a/include/libtorrent/peer_list.hpp b/include/libtorrent/peer_list.hpp index 91a071838..9a7256730 100644 --- a/include/libtorrent/peer_list.hpp +++ b/include/libtorrent/peer_list.hpp @@ -103,6 +103,8 @@ namespace libtorrent { explicit peer_list(torrent_peer_allocator_interface& alloc); ~peer_list(); + void clear(); + // not copyable peer_list(peer_list const&) = delete; peer_list& operator=(peer_list const&) = delete; diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 01478e7be..5ad8d0950 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -448,6 +448,7 @@ namespace libtorrent { // the necessary actions then. void abort(); bool is_aborted() const { return m_abort; } + void panic(); void new_external_ip(); diff --git a/include/libtorrent/torrent_peer.hpp b/include/libtorrent/torrent_peer.hpp index 99cf9d12c..733b5d7b2 100644 --- a/include/libtorrent/torrent_peer.hpp +++ b/include/libtorrent/torrent_peer.hpp @@ -57,7 +57,7 @@ namespace libtorrent { #if TORRENT_USE_ASSERTS torrent_peer(torrent_peer const&) = default; torrent_peer& operator=(torrent_peer const&) = default; - ~torrent_peer() { in_use = false; } + ~torrent_peer() { TORRENT_ASSERT(in_use); in_use = false; } #endif std::int64_t total_download() const; diff --git a/src/peer_list.cpp b/src/peer_list.cpp index c78198a73..0c9ffc2e8 100644 --- a/src/peer_list.cpp +++ b/src/peer_list.cpp @@ -125,6 +125,13 @@ namespace libtorrent { thread_started(); } + void peer_list::clear() + { + for (auto const p : m_peers) + m_peer_allocator.free_peer_entry(p); + m_peers.clear(); + } + peer_list::~peer_list() { for (auto const p : m_peers) diff --git a/src/session_impl.cpp b/src/session_impl.cpp index c1c3e7bd9..74d230f46 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -6030,7 +6030,13 @@ namespace { // TORRENT_ASSERT(is_not_thread()); // TODO: asserts that no outstanding async operations are still in flight - TORRENT_ASSERT(m_torrents.empty()); + // this can happen if we end the io_service run loop with an exception + for (auto& t : m_torrents) + { + t.second->panic(); + t.second->abort(); + } + m_torrents.clear(); #if defined TORRENT_ASIO_DEBUGGING FILE* f = fopen("wakeups.log", "w+"); diff --git a/src/torrent.cpp b/src/torrent.cpp index 5404785ac..27989d1e4 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -4419,6 +4419,18 @@ namespace libtorrent { m_state_subscription = false; } + // this is called when we're destructing non-gracefully. i.e. we're _just_ + // destructing everything. + void torrent::panic() + { + m_storage.reset(); + // if there are any other peers allocated still, we need to clear them + // now. They can't be cleared later because the allocator will already + // have been destructed + if (m_peer_list) m_peer_list->clear(); + m_connections.clear(); + } + void torrent::set_super_seeding(bool on) { if (on == m_super_seeding) return;