improve error handling during session shutdown

This commit is contained in:
arvidn 2017-12-28 01:15:20 +01:00 committed by Arvid Norberg
parent 3c5c224051
commit 5f0c9a0c1d
5 changed files with 28 additions and 15 deletions

View File

@ -52,6 +52,7 @@ POSSIBILITY OF SUCH DAMAGE.
#endif
#if __GNUC__ >= 7
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#pragma GCC diagnostic ignored "-Wnoexcept-type"
#endif
#endif

View File

@ -277,6 +277,13 @@ namespace aux {
void init_peer_class_filter(bool unlimited_local);
void call_abort()
{
auto ptr = shared_from_this();
m_io_service.dispatch(make_handler([ptr] { ptr->abort(); }
, m_abort_handler_storage, *this));
}
#ifndef TORRENT_DISABLE_EXTENSIONS
using ext_function_t
= std::function<std::shared_ptr<torrent_plugin>(torrent_handle const&, void*)>;
@ -603,8 +610,8 @@ namespace aux {
alert_manager& alerts() override { return m_alerts; }
disk_interface& disk_thread() override { return m_disk_thread; }
void abort();
void abort_stage2();
void abort() noexcept;
void abort_stage2() noexcept;
torrent_handle find_torrent_handle(sha1_hash const& info_hash);
@ -790,6 +797,8 @@ namespace aux {
counters m_stats_counters;
// this is a pool allocator for torrent_peer objects
// torrents and the disk cache (implicitly by holding references to the
// torrents) depend on this outliving them.
torrent_peer_allocator m_peer_allocator;
// this vector is used to store the block_info
@ -1180,6 +1189,13 @@ namespace aux {
deadline_timer m_timer;
aux::handler_storage<TORRENT_READ_HANDLER_MAX_SIZE> m_tick_handler_storage;
// abort may not fail and cannot allocate memory
#ifdef _M_AMD64
aux::handler_storage<88> m_abort_handler_storage;
#else
aux::handler_storage<56> m_abort_handler_storage;
#endif
// torrents are announced on the local network in a
// round-robin fashion. All torrents are cycled through
// within the LSD announce interval (which defaults to

View File

@ -403,13 +403,11 @@ namespace {
session::~session()
{
aux::dump_call_profile();
TORRENT_ASSERT(m_impl);
std::shared_ptr<aux::session_impl> ptr = m_impl;
// capture the shared_ptr in the dispatched function
// to keep the session_impl alive
m_impl->get_io_service().dispatch([=] { ptr->abort(); });
m_impl->call_abort();
if (m_thread && m_thread.unique())
{
@ -424,7 +422,7 @@ namespace {
{
// stop calling the alert notify function now, to avoid it thinking the
// session is still alive
m_impl->alerts().set_notify_function(std::function<void()>());
m_impl->alerts().set_notify_function({});
return session_proxy(m_io_service, m_thread, m_impl);
}

View File

@ -174,7 +174,7 @@ using namespace std::placeholders;
#ifdef BOOST_NO_EXCEPTIONS
namespace boost {
void throw_exception(std::exception const& e) { ::abort(); }
void throw_exception(std::exception const& e) { std::abort(); }
}
#endif
@ -807,7 +807,7 @@ namespace aux {
}
}
void session_impl::abort()
void session_impl::abort() noexcept
{
TORRENT_ASSERT(is_single_thread());
@ -818,7 +818,7 @@ namespace aux {
// at this point we cannot call the notify function anymore, since the
// session will become invalid.
m_alerts.set_notify_function(std::function<void()>());
m_alerts.set_notify_function({});
// this will cancel requests that are not critical for shutting down
// cleanly. i.e. essentially tracker hostname lookups that we're not
@ -914,11 +914,12 @@ namespace aux {
// shutdown_stage2 from there.
if (m_undead_peers.empty())
{
m_io_service.post(std::bind(&session_impl::abort_stage2, this));
m_io_service.post(make_handler([this] { abort_stage2(); }
, m_abort_handler_storage, *this));
}
}
void session_impl::abort_stage2()
void session_impl::abort_stage2() noexcept
{
m_download_rate.close();
m_upload_rate.close();
@ -4123,8 +4124,6 @@ namespace {
// if we don't have any connection attempt quota, return
if (max_connections <= 0) return;
INVARIANT_CHECK;
int steps_since_last_connect = 0;
int const num_torrents = int(want_peers_finished.size() + want_peers_download.size());
for (;;)

View File

@ -8399,7 +8399,7 @@ namespace libtorrent {
}
catch (...) { handle_exception(); }
void torrent::on_torrent_aborted() try
void torrent::on_torrent_aborted()
{
TORRENT_ASSERT(is_single_thread());
@ -8407,7 +8407,6 @@ namespace libtorrent {
// release the disk io handle
m_storage.reset();
}
catch (...) { handle_exception(); }
bool torrent::is_paused() const
{