forked from premiere/premiere-libtorrent
improve error handling during session shutdown
This commit is contained in:
parent
3c5c224051
commit
5f0c9a0c1d
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 (;;)
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue