From 49aba26f5c39436df80ab599dee1b51d9fa24ed9 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Mon, 12 Aug 2013 00:51:49 +0000 Subject: [PATCH] merged shutdown fix from libtorrent_aio --- include/libtorrent/bencode.hpp | 6 +++--- include/libtorrent/http_connection.hpp | 2 +- include/libtorrent/torrent.hpp | 2 +- src/http_connection.cpp | 9 ++++++--- src/torrent.cpp | 24 +++++++++++++++++++++++- 5 files changed, 34 insertions(+), 9 deletions(-) diff --git a/include/libtorrent/bencode.hpp b/include/libtorrent/bencode.hpp index 705f4030f..f9efc715b 100644 --- a/include/libtorrent/bencode.hpp +++ b/include/libtorrent/bencode.hpp @@ -420,11 +420,11 @@ namespace libtorrent // // If ``bdecode()`` encounters invalid encoded data in the range given to it // it will throw libtorrent_exception. - TORRENT_EXPORT template int bencode(OutIt out, const entry& e) + template TORRENT_EXPORT int bencode(OutIt out, const entry& e) { return detail::bencode_recursive(out, e); } - TORRENT_EXPORT template entry bdecode(InIt start, InIt end) + template TORRENT_EXPORT entry bdecode(InIt start, InIt end) { entry e; bool err = false; @@ -435,7 +435,7 @@ namespace libtorrent if (err) return entry(); return e; } - TORRENT_EXPORT template entry bdecode(InIt start, InIt end, int& len) + template TORRENT_EXPORT entry bdecode(InIt start, InIt end, int& len) { entry e; bool err = false; diff --git a/include/libtorrent/http_connection.hpp b/include/libtorrent/http_connection.hpp index 5b54dfcdd..328a30a2f 100644 --- a/include/libtorrent/http_connection.hpp +++ b/include/libtorrent/http_connection.hpp @@ -115,7 +115,7 @@ struct TORRENT_EXTRA_EXPORT http_connection #endif ); - void close(); + void close(bool force = false); socket_type const& socket() const { return m_sock; } diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 4b60baaf0..2df71a252 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -933,7 +933,7 @@ namespace libtorrent // if this pointer is 0, the torrent is in // a state where the metadata hasn't been - // received yet. + // received yet, or during shutdown. // the piece_manager keeps the torrent object // alive by holding a shared_ptr to it and // the torrent keeps the piece manager alive diff --git a/src/http_connection.cpp b/src/http_connection.cpp index d420074ac..53d22d8e7 100644 --- a/src/http_connection.cpp +++ b/src/http_connection.cpp @@ -422,7 +422,7 @@ void http_connection::on_timeout(boost::weak_ptr p else { c->callback(asio::error::timed_out); - c->close(); + c->close(true); } return; } @@ -438,7 +438,7 @@ void http_connection::on_timeout(boost::weak_ptr p c->m_timer.async_wait(boost::bind(&http_connection::on_timeout, p, _1)); } -void http_connection::close() +void http_connection::close(bool force) { if (m_abort) return; @@ -447,7 +447,10 @@ void http_connection::close() m_resolver.cancel(); m_limiter_timer.cancel(ec); - async_shutdown(m_sock, shared_from_this()); + if (force) + m_sock.close(ec); + else + async_shutdown(m_sock, shared_from_this()); m_hostname.clear(); m_port.clear(); diff --git a/src/torrent.cpp b/src/torrent.cpp index 19185f3fa..2a919b0a9 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -3624,6 +3624,7 @@ namespace libtorrent } else { + TORRENT_ASSERT(m_abort); if (alerts().should_post()) alerts().post_alert(cache_flushed_alert(get_handle())); } @@ -6553,6 +6554,14 @@ namespace libtorrent TORRENT_ASSERT(m_ses.is_network_thread()); INVARIANT_CHECK; + if (m_abort) + { + if (alerts().should_post()) + alerts().post_alert(storage_moved_failed_alert(get_handle(), boost::asio::error::operation_aborted)); + return; + } + + // storage may be NULL during shutdown if (m_owning_storage.get()) { #if TORRENT_USE_UNC_PATHS @@ -7016,6 +7025,7 @@ namespace libtorrent disconnect_all(errors::torrent_removed); stop_announcing(); + // storage may be NULL during shutdown if (m_owning_storage.get()) { TORRENT_ASSERT(m_storage); @@ -7215,7 +7225,8 @@ namespace libtorrent return; } - if (flags & torrent_handle::flush_disk_cache) + // storage may be NULL during shutdown + if ((flags & torrent_handle::flush_disk_cache) && m_storage) m_storage->async_release_files(); m_storage->async_save_resume_data( @@ -7238,6 +7249,13 @@ namespace libtorrent void torrent::flush_cache() { TORRENT_ASSERT(m_ses.is_network_thread()); + + // storage may be NULL during shutdown + if (!m_owning_storage) + { + TORRENT_ASSERT(m_abort); + return; + } m_storage->async_release_files( boost::bind(&torrent::on_cache_flushed, shared_from_this(), _1, _2)); } @@ -7986,6 +8004,10 @@ namespace libtorrent { TORRENT_ASSERT(m_ses.is_network_thread()); if (!ready_for_connections()) return; + + if (m_abort) return; + TORRENT_ASSERT(m_storage); + // rotate the cached pieces // add blocks_per_piece / 2 in order to round to closest whole piece