From 4ddbe44a0db100adbc570ffd2eb01e3abfa7fe0b Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Mon, 25 Jun 2012 03:31:11 +0000 Subject: [PATCH] fix bug in the udp socket observer use for DHT and add debug facilily for the observers --- include/libtorrent/udp_socket.hpp | 3 ++ src/session_impl.cpp | 12 ++------ src/udp_socket.cpp | 48 ++++++++++++++++++++++--------- 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/include/libtorrent/udp_socket.hpp b/include/libtorrent/udp_socket.hpp index 7579e8fcb..24dcd7fb8 100644 --- a/include/libtorrent/udp_socket.hpp +++ b/include/libtorrent/udp_socket.hpp @@ -174,6 +174,9 @@ namespace libtorrent void unwrap(error_code const& e, char const* buf, int size); #if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS + bool m_observers_locked; + + // TODO: move this debug facility into a base class. It's used in a lot of places #if defined BOOST_HAS_PTHREADS mutable pthread_t m_thread; #endif diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 19345b632..5af059867 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -1749,11 +1749,7 @@ namespace aux { stop_upnp(); stop_natpmp(); #ifndef TORRENT_DISABLE_DHT - if (m_dht) - { - m_dht->stop(); - m_dht = 0; - } + stop_dht(); m_dht_announce_timer.cancel(ec); #endif m_timer.cancel(ec); @@ -5341,11 +5337,7 @@ namespace aux { { INVARIANT_CHECK; - if (m_dht) - { - m_dht->stop(); - m_dht = 0; - } + stop_dht(); m_dht = new dht::dht_tracker(*this, m_udp_socket, m_dht_settings, &startup_state); for (std::list::iterator i = m_dht_router_nodes.begin() diff --git a/src/udp_socket.cpp b/src/udp_socket.cpp index 4cebfd921..3ec391488 100644 --- a/src/udp_socket.cpp +++ b/src/udp_socket.cpp @@ -75,6 +75,7 @@ udp_socket::udp_socket(asio::io_service& ios , m_outstanding_ops(0) { #if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS + m_observers_locked = false; m_magic = 0x1337; m_started = false; m_outstanding_when_aborted = -1; @@ -95,6 +96,7 @@ udp_socket::~udp_socket() #endif TORRENT_ASSERT_VAL(m_v4_outstanding == 0, m_v4_outstanding); TORRENT_ASSERT(m_magic == 0x1337); + TORRENT_ASSERT(m_observers_locked == false); #if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS m_magic = 0; #endif @@ -226,6 +228,9 @@ void udp_socket::on_read(udp::socket* s) void udp_socket::call_handler(error_code const& ec, udp::endpoint const& ep, char const* buf, int size) { +#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS + m_observers_locked = true; +#endif for (std::vector::iterator i = m_observers.begin() , end(m_observers.end()); i != end; ++i) { @@ -236,10 +241,16 @@ void udp_socket::call_handler(error_code const& ec, udp::endpoint const& ep, cha } TORRENT_CATCH (std::exception&) {} } +#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS + m_observers_locked = false; +#endif } void udp_socket::call_handler(error_code const& ec, const char* host, char const* buf, int size) { +#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS + m_observers_locked = true; +#endif for (std::vector::iterator i = m_observers.begin() , end(m_observers.end()); i != end; ++i) { @@ -250,23 +261,16 @@ void udp_socket::call_handler(error_code const& ec, const char* host, char const } TORRENT_CATCH (std::exception&) {} } -} - -void udp_socket::subscribe(udp_socket_observer* o) -{ - TORRENT_ASSERT(std::find(m_observers.begin(), m_observers.end(), o) == m_observers.end()); - m_observers.push_back(o); -} - -void udp_socket::unsubscribe(udp_socket_observer* o) -{ - std::vector::iterator i = std::find(m_observers.begin(), m_observers.end(), o); - if (i == m_observers.end()) return; - m_observers.erase(i); +#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS + m_observers_locked = false; +#endif } void udp_socket::call_drained_handler() { +#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS + m_observers_locked = true; +#endif for (std::vector::iterator i = m_observers.begin() , end(m_observers.end()); i != end; ++i) { @@ -274,6 +278,24 @@ void udp_socket::call_drained_handler() (*i)->socket_drained(); } TORRENT_CATCH (std::exception&) {} } +#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS + m_observers_locked = false; +#endif +} + +void udp_socket::subscribe(udp_socket_observer* o) +{ + TORRENT_ASSERT(m_observers_locked == false); + TORRENT_ASSERT(std::find(m_observers.begin(), m_observers.end(), o) == m_observers.end()); + m_observers.push_back(o); +} + +void udp_socket::unsubscribe(udp_socket_observer* o) +{ + TORRENT_ASSERT(m_observers_locked == false); + std::vector::iterator i = std::find(m_observers.begin(), m_observers.end(), o); + if (i == m_observers.end()) return; + m_observers.erase(i); } void udp_socket::on_read_impl(udp::socket* s, udp::endpoint const& ep