diff --git a/libtorrent/include/libtorrent/udp_socket.hpp b/libtorrent/include/libtorrent/udp_socket.hpp index dc257f806..dab9941e5 100644 --- a/libtorrent/include/libtorrent/udp_socket.hpp +++ b/libtorrent/include/libtorrent/udp_socket.hpp @@ -65,7 +65,13 @@ namespace libtorrent proxy_settings const& get_proxy_settings() { return m_proxy_settings; } #ifdef TORRENT_DEBUG - ~udp_socket() { m_magic = 0; } + ~udp_socket() + { + TORRENT_ASSERT(m_magic == 0x1337); + TORRENT_ASSERT(m_outstanding == 0); + TORRENT_ASSERT(!m_callback); + m_magic = 0; + } #endif private: diff --git a/libtorrent/include/libtorrent/version.hpp b/libtorrent/include/libtorrent/version.hpp index 8a02b90ec..ac6cadf3a 100644 --- a/libtorrent/include/libtorrent/version.hpp +++ b/libtorrent/include/libtorrent/version.hpp @@ -36,6 +36,6 @@ POSSIBILITY OF SUCH DAMAGE. #define LIBTORRENT_VERSION_MAJOR 0 #define LIBTORRENT_VERSION_MINOR 14 -#define LIBTORRENT_VERSION "0.14.1.0" +#define LIBTORRENT_VERSION "0.14.2.0" #endif diff --git a/libtorrent/src/storage.cpp b/libtorrent/src/storage.cpp index fc491c98f..82402629f 100755 --- a/libtorrent/src/storage.cpp +++ b/libtorrent/src/storage.cpp @@ -1942,6 +1942,8 @@ namespace libtorrent // is finished int piece_manager::check_files(int& current_slot, int& have_piece, std::string& error) { + if (m_state == state_none) return check_no_fastresume(error); + TORRENT_ASSERT(int(m_piece_to_slot.size()) == m_files.num_pieces()); current_slot = m_current_slot; diff --git a/libtorrent/src/torrent_info.cpp b/libtorrent/src/torrent_info.cpp index 5f5b8fd76..bcfa67a35 100755 --- a/libtorrent/src/torrent_info.cpp +++ b/libtorrent/src/torrent_info.cpp @@ -497,20 +497,23 @@ namespace libtorrent } } - // shuffle each tier - std::vector::iterator start = m_urls.begin(); - std::vector::iterator stop; - int current_tier = m_urls.front().tier; - for (stop = m_urls.begin(); stop != m_urls.end(); ++stop) + if (!m_urls.empty()) { - if (stop->tier != current_tier) + // shuffle each tier + std::vector::iterator start = m_urls.begin(); + std::vector::iterator stop; + int current_tier = m_urls.front().tier; + for (stop = m_urls.begin(); stop != m_urls.end(); ++stop) { - std::random_shuffle(start, stop); - start = stop; - current_tier = stop->tier; + if (stop->tier != current_tier) + { + std::random_shuffle(start, stop); + start = stop; + current_tier = stop->tier; + } } + std::random_shuffle(start, stop); } - std::random_shuffle(start, stop); } diff --git a/libtorrent/src/udp_socket.cpp b/libtorrent/src/udp_socket.cpp index e66adf1b5..8ffbe2ed8 100644 --- a/libtorrent/src/udp_socket.cpp +++ b/libtorrent/src/udp_socket.cpp @@ -45,6 +45,7 @@ udp_socket::udp_socket(asio::io_service& ios, udp_socket::callback_t const& c void udp_socket::send(udp::endpoint const& ep, char const* p, int len, error_code& ec) { CHECK_MAGIC; + TORRENT_ASSERT(m_ipv4_sock.is_open()); if (m_tunnel_packets) { // send udp packets through SOCKS5 server @@ -72,8 +73,8 @@ void udp_socket::on_read(udp::socket* s, error_code const& e, std::size_t bytes_ { // "this" may be destructed in the callback // that's why we need to unlock - l.unlock(); callback_t tmp = m_callback; + l.unlock(); m_callback.clear(); } return; @@ -84,6 +85,7 @@ void udp_socket::on_read(udp::socket* s, error_code const& e, std::size_t bytes_ if (e) { + l.unlock(); #ifndef BOOST_NO_EXCEPTIONS try { #endif @@ -94,6 +96,7 @@ void udp_socket::on_read(udp::socket* s, error_code const& e, std::size_t bytes_ #ifndef BOOST_NO_EXCEPTIONS } catch(std::exception&) {} #endif + l.lock(); // don't stop listening on recoverable errors if (e != asio::error::host_unreachable @@ -122,9 +125,16 @@ void udp_socket::on_read(udp::socket* s, error_code const& e, std::size_t bytes_ #endif if (m_tunnel_packets && m_v4_ep == m_proxy_addr) + { + l.unlock(); unwrap(e, m_v4_buf, bytes_transferred); + } else + { + l.unlock(); m_callback(e, m_v4_ep, m_v4_buf, bytes_transferred); + } + l.lock(); #ifndef BOOST_NO_EXCEPTIONS } catch(std::exception&) {} @@ -139,13 +149,20 @@ void udp_socket::on_read(udp::socket* s, error_code const& e, std::size_t bytes_ #endif if (m_tunnel_packets && m_v6_ep == m_proxy_addr) + { + l.unlock(); unwrap(e, m_v6_buf, bytes_transferred); + } else + { + l.unlock(); m_callback(e, m_v6_ep, m_v6_buf, bytes_transferred); + } #ifndef BOOST_NO_EXCEPTIONS } catch(std::exception&) {} #endif + l.lock(); s->async_receive_from(asio::buffer(m_v6_buf, sizeof(m_v6_buf)) , m_v6_ep, boost::bind(&udp_socket::on_read, this, s, _1, _2)); } @@ -215,6 +232,7 @@ void udp_socket::unwrap(error_code const& e, char const* buf, int size) void udp_socket::close() { + mutex_t::scoped_lock l(m_mutex); TORRENT_ASSERT(m_magic == 0x1337); error_code ec; @@ -232,6 +250,7 @@ void udp_socket::close() // "this" may be destructed in the callback callback_t tmp = m_callback; m_callback.clear(); + l.unlock(); } }