diff --git a/include/libtorrent/debug.hpp b/include/libtorrent/debug.hpp index 39b14a605..96c2e749a 100644 --- a/include/libtorrent/debug.hpp +++ b/include/libtorrent/debug.hpp @@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE. #if defined TORRENT_ASIO_DEBUGGING #include "libtorrent/assert.hpp" +#include "libtorrent/thread.hpp" #include #include @@ -52,9 +53,12 @@ namespace libtorrent }; extern std::map _async_ops; + extern int _async_ops_nthreads; + extern mutex _async_ops_mutex; inline void add_outstanding_async(char const* name) { + mutex::scoped_lock l(_async_ops_mutex); async_t& a = _async_ops[name]; if (a.stack.empty()) { @@ -76,18 +80,32 @@ namespace libtorrent inline void complete_async(char const* name) { + mutex::scoped_lock l(_async_ops_mutex); async_t& a = _async_ops[name]; TORRENT_ASSERT(a.refs > 0); --a.refs; } + inline void async_inc_threads() + { + mutex::scoped_lock l(_async_ops_mutex); + ++_async_ops_nthreads; + } + + inline void async_dec_threads() + { + mutex::scoped_lock l(_async_ops_mutex); + --_async_ops_nthreads; + } + inline int log_async() { + mutex::scoped_lock l(_async_ops_mutex); int ret = 0; for (std::map::iterator i = _async_ops.begin() , end(_async_ops.end()); i != end; ++i) { - if (i->second.refs <= 0) continue; + if (i->second.refs <= _async_ops_nthreads - 1) continue; ret += i->second.refs; printf("%s: (%d)\n%s\n", i->first.c_str(), i->second.refs, i->second.stack.c_str()); } diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 1f018ab80..41ec44ba9 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -172,6 +172,8 @@ namespace libtorrent { #if defined TORRENT_ASIO_DEBUGGING std::map _async_ops; + int _async_ops_nthreads = 0; + mutex _async_ops_mutex; #endif namespace detail @@ -847,6 +849,7 @@ namespace aux { // constructor which is called from the main thread #if defined TORRENT_ASIO_DEBUGGING + async_inc_threads(); add_outstanding_async("session_impl::on_tick"); #endif error_code ec; @@ -1207,7 +1210,9 @@ namespace aux { , end(m_listen_sockets.end()); i != end; ++i) { i->sock->close(ec); + TORRENT_ASSERT(!ec); } + m_listen_sockets.clear(); #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) (*m_logger) << time_now_string() << " aborting all torrents (" << m_torrents.size() << ")\n"; @@ -1851,6 +1856,7 @@ namespace aux { void session_impl::async_accept(boost::shared_ptr const& listener) { + TORRENT_ASSERT(!m_abort); shared_ptr c(new socket_type(m_io_service)); c->instantiate(m_io_service); #if defined TORRENT_ASIO_DEBUGGING @@ -4010,6 +4016,7 @@ namespace aux { #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) (*m_logger) << time_now_string() << " waiting for main thread\n"; #endif + #if defined TORRENT_ASIO_DEBUGGING int counter = 0; while (log_async()) @@ -4018,7 +4025,9 @@ namespace aux { ++counter; printf("\n==== Waiting to shut down: %d ==== \n\n", counter); } + async_dec_threads(); #endif + if (m_thread) m_thread->join(); TORRENT_ASSERT(m_torrents.empty()); diff --git a/test/test_transfer.cpp b/test/test_transfer.cpp index 9c0d59ac1..c96f9965b 100644 --- a/test/test_transfer.cpp +++ b/test/test_transfer.cpp @@ -49,6 +49,10 @@ POSSIBILITY OF SUCH DAMAGE. using namespace libtorrent; using boost::tuples::ignore; +int const alert_mask = alert::all_categories +& ~alert::progress_notification +& ~alert::stats_notification; + // test the maximum transfer rate void test_rate() { @@ -59,9 +63,6 @@ void test_rate() remove_all("./tmp1_transfer_moved", ec); remove_all("./tmp2_transfer_moved", ec); - int alert_mask = alert::all_categories - & ~alert::progress_notification - & ~alert::stats_notification; session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48575, 49000), "0.0.0.0", 0, alert_mask); session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49575, 50000), "0.0.0.0", 0, alert_mask); @@ -243,8 +244,8 @@ void test_transfer(int proxy_type, bool test_disk_full = false, bool test_allowe remove_all("./tmp1_transfer_moved", ec); remove_all("./tmp2_transfer_moved", ec); - session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48075, 49000), "0.0.0.0", 0); - session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49075, 50000), "0.0.0.0", 0); + session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48075, 49000), "0.0.0.0", 0, alert_mask); + session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49075, 50000), "0.0.0.0", 0, alert_mask); int proxy_port = (rand() % 30000) + 10000; if (proxy_type) @@ -275,6 +276,7 @@ void test_transfer(int proxy_type, bool test_disk_full = false, bool test_allowe // using a reconnect time > 0 will just add // to the time it will take to complete the test sett.min_reconnect_time = 0; + sett.stop_tracker_timeout = 1; sett.announce_to_all_trackers = true; sett.announce_to_all_tiers = true; // make sure we announce to both http and udp trackers @@ -315,6 +317,9 @@ void test_transfer(int proxy_type, bool test_disk_full = false, bool test_allowe addp.paused = false; addp.auto_managed = false; + wait_for_listen(ses1, "ses1"); + wait_for_listen(ses2, "ses1"); + // test using piece sizes smaller than 16kB boost::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, 0 , true, false, true, "_transfer", 8 * 1024, &t, false, test_disk_full?&addp:0); @@ -328,12 +333,6 @@ void test_transfer(int proxy_type, bool test_disk_full = false, bool test_allowe std::copy(priorities.begin(), priorities.end(), std::ostream_iterator(std::cerr, ", ")); std::cerr << std::endl; - ses1.set_alert_mask(alert::all_categories - & ~alert::progress_notification - & ~alert::stats_notification); - ses2.set_alert_mask(alert::all_categories - & ~alert::progress_notification - & ~alert::stats_notification); // ses1.set_alert_dispatch(&print_alert); // sett = ses2.settings();