diff --git a/CMakeLists.txt b/CMakeLists.txt index 53ebe0d72..ad9678a5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,6 +97,7 @@ set(kademlia_sources node_id routing_table traversal_algorithm + logging ) set(includes include) diff --git a/Jamfile b/Jamfile index 51650c267..f6ff0740d 100755 --- a/Jamfile +++ b/Jamfile @@ -562,6 +562,7 @@ KADEMLIA_SOURCES = node_id routing_table traversal_algorithm + logging ; local usage-requirements = diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index e3284d8f8..f93255fb4 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -1214,13 +1214,9 @@ namespace libtorrent #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING struct tracker_logger : request_callback { - tracker_logger(session_impl& ses): m_ses(ses) {} + tracker_logger(session_impl& ses); void tracker_warning(tracker_request const& req - , std::string const& str) - { - debug_log("*** tracker warning: %s", str.c_str()); - } - + , std::string const& str); void tracker_response(tracker_request const& , libtorrent::address const& tracker_ip , std::list
const& ip_list @@ -1231,56 +1227,13 @@ namespace libtorrent , int incomplete , int downloaded , address const& external_ip - , std::string const& tracker_id) - { - std::string s; - s = "TRACKER RESPONSE:\n"; - char tmp[200]; - snprintf(tmp, 200, "interval: %d\nmin_interval: %d\npeers:\n", interval, min_interval); - s += tmp; - for (std::vector::const_iterator i = peers.begin(); - i != peers.end(); ++i) - { - char pid[41]; - to_hex((const char*)&i->pid[0], 20, pid); - if (i->pid.is_all_zeros()) pid[0] = 0; - - snprintf(tmp, 200, " %-16s %-5d %s\n", i->ip.c_str(), i->port, pid); - s += tmp; - } - snprintf(tmp, 200, "external ip: %s\n", print_address(external_ip).c_str()); - s += tmp; - debug_log("%s", s.c_str()); - } - + , std::string const& tracker_id); void tracker_request_timed_out( - tracker_request const&) - { - debug_log("*** tracker timed out"); - } - + tracker_request const&); void tracker_request_error(tracker_request const& r , int response_code, error_code const& ec, const std::string& str - , int retry_interval) - { - debug_log("*** tracker error: %d: %s %s" - , response_code, ec.message().c_str(), str.c_str()); - } - - void debug_log(const char* fmt, ...) const - { - if (!m_ses.m_logger) return; - - va_list v; - va_start(v, fmt); - - char usr[1024]; - vsnprintf(usr, sizeof(usr), fmt, v); - va_end(v); - char buf[1280]; - snprintf(buf, sizeof(buf), "%s: %s\n", time_now_string(), usr); - (*m_ses.m_logger) << buf; - } + , int retry_interval); + void debug_log(const char* fmt, ...) const; session_impl& m_ses; }; #endif diff --git a/include/libtorrent/kademlia/logging.hpp b/include/libtorrent/kademlia/logging.hpp index d5d6c09df..ef0f8da6d 100644 --- a/include/libtorrent/kademlia/logging.hpp +++ b/include/libtorrent/kademlia/logging.hpp @@ -87,21 +87,8 @@ private: class log_event { public: - log_event(log& log) - : log_(log) - { - if (log_.enabled()) - log_ << time_now_string() << " [" << log.id() << "] "; - } - - ~log_event() - { - if (log_.enabled()) - { - log_ << "\n"; - log_.flush(); - } - } + log_event(log& log); + ~log_event(); template log_event& operator<<(T const& x) diff --git a/include/libtorrent/natpmp.hpp b/include/libtorrent/natpmp.hpp index 0b852e8d8..c5df51148 100644 --- a/include/libtorrent/natpmp.hpp +++ b/include/libtorrent/natpmp.hpp @@ -53,9 +53,8 @@ namespace libtorrent typedef boost::function portmap_callback_t; typedef boost::function log_callback_t; -// TODO: 3 should this really be a public symbol? -// also, make this a shared_ptr instead -class TORRENT_EXPORT natpmp : public intrusive_ptr_base +// TODO: 2 make this a shared_ptr instead +class natpmp : public intrusive_ptr_base { public: natpmp(io_service& ios, address const& listen_interface diff --git a/include/libtorrent/ptime.hpp b/include/libtorrent/ptime.hpp index eccc54135..140ef2046 100644 --- a/include/libtorrent/ptime.hpp +++ b/include/libtorrent/ptime.hpp @@ -126,8 +126,8 @@ namespace libtorrent TORRENT_EXPORT ptime min_time(); TORRENT_EXPORT ptime max_time(); - TORRENT_EXPORT char const* time_now_string(); - TORRENT_EXPORT std::string log_time(); + char const* time_now_string(); + std::string log_time(); TORRENT_EXPORT ptime const& time_now(); } diff --git a/include/libtorrent/session.hpp b/include/libtorrent/session.hpp index cbf904e27..e1acbb24a 100644 --- a/include/libtorrent/session.hpp +++ b/include/libtorrent/session.hpp @@ -80,8 +80,6 @@ namespace libtorrent struct ip_filter; class port_filter; class connection_queue; - class natpmp; - class upnp; class alert; TORRENT_EXPORT session_settings min_memory_usage(); @@ -95,20 +93,6 @@ namespace libtorrent namespace aux { - // workaround for microsofts - // hardware exceptions that makes - // it hard to debug stuff - // TODO: 3 make this an implementation detail -#ifdef _MSC_VER - struct TORRENT_EXPORT eh_initializer - { - eh_initializer(); - static void straight_to_debugger(unsigned int, _EXCEPTION_POINTERS*) - { throw; } - }; -#else - struct eh_initializer {}; -#endif struct session_impl; } @@ -131,7 +115,7 @@ namespace libtorrent // Once it's created, the session object will spawn the main thread that will do all the work. // The main thread will be idle as long it doesn't have any torrents to participate in. - class TORRENT_EXPORT session: public boost::noncopyable, aux::eh_initializer + class TORRENT_EXPORT session: public boost::noncopyable { public: @@ -483,8 +467,8 @@ namespace libtorrent // starts/stops UPnP, NATPMP or LSD port mappers // they are stopped by default void start_lsd(); - natpmp* start_natpmp(); - upnp* start_upnp(); + void start_natpmp(); + void start_upnp(); void stop_lsd(); void stop_natpmp(); diff --git a/include/libtorrent/time.hpp b/include/libtorrent/time.hpp index c521c732d..845ec4671 100644 --- a/include/libtorrent/time.hpp +++ b/include/libtorrent/time.hpp @@ -41,9 +41,8 @@ POSSIBILITY OF SUCH DAMAGE. namespace libtorrent { - // TODO: 3 do these two really need to be exposed to users? - TORRENT_EXPORT char const* time_now_string(); - TORRENT_EXPORT std::string log_time(); + char const* time_now_string(); + std::string log_time(); TORRENT_EXPORT ptime time_now_hires(); TORRENT_EXPORT ptime min_time(); @@ -63,52 +62,15 @@ namespace libtorrent #elif defined TORRENT_USE_QUERY_PERFORMANCE_TIMER - namespace aux - { - // TODO: 3 move these to time.cpp - TORRENT_EXPORT boost::int64_t performance_counter_to_microseconds(boost::int64_t pc); - TORRENT_EXPORT boost::int64_t microseconds_to_performance_counter(boost::int64_t ms); - } - - inline int total_seconds(time_duration td) - { - return int(aux::performance_counter_to_microseconds(td.diff) - / 1000000); - } - inline int total_milliseconds(time_duration td) - { - return int(aux::performance_counter_to_microseconds(td.diff) - / 1000); - } - inline boost::int64_t total_microseconds(time_duration td) - { - return aux::performance_counter_to_microseconds(td.diff); - } - - inline time_duration microsec(boost::int64_t s) - { - return time_duration(aux::microseconds_to_performance_counter(s)); - } - inline time_duration milliseconds(boost::int64_t s) - { - return time_duration(aux::microseconds_to_performance_counter( - s * 1000)); - } - inline time_duration seconds(boost::int64_t s) - { - return time_duration(aux::microseconds_to_performance_counter( - s * 1000000)); - } - inline time_duration minutes(boost::int64_t s) - { - return time_duration(aux::microseconds_to_performance_counter( - s * 1000000 * 60)); - } - inline time_duration hours(boost::int64_t s) - { - return time_duration(aux::microseconds_to_performance_counter( - s * 1000000 * 60 * 60)); - } + TORRENT_EXPORT time_duration microsec(boost::int64_t s); + TORRENT_EXPORT time_duration milliseconds(boost::int64_t s); + TORRENT_EXPORT time_duration seconds(boost::int64_t s); + TORRENT_EXPORT time_duration minutes(boost::int64_t s); + TORRENT_EXPORT time_duration hours(boost::int64_t s); + + TORRENT_EXPORT int total_seconds(time_duration td); + TORRENT_EXPORT int total_milliseconds(time_duration td); + TORRENT_EXPORT boost::int64_t total_microseconds(time_duration td); #elif TORRENT_USE_CLOCK_GETTIME || TORRENT_USE_SYSTEM_TIME || TORRENT_USE_ABSOLUTE_TIME diff --git a/include/libtorrent/upnp.hpp b/include/libtorrent/upnp.hpp index 7e98b1e31..cb14a0be7 100644 --- a/include/libtorrent/upnp.hpp +++ b/include/libtorrent/upnp.hpp @@ -99,9 +99,8 @@ namespace libtorrent typedef boost::function portmap_callback_t; typedef boost::function log_callback_t; -// TODO: 3 should this really be a public symbol? -// also, make this a shared_ptr instead -class TORRENT_EXPORT upnp : public intrusive_ptr_base +// TODO: 2 make this a shared_ptr instead +class upnp : public intrusive_ptr_base { public: upnp(io_service& ios, connection_queue& cc diff --git a/src/Makefile.am b/src/Makefile.am index cbd2a606f..2296713e1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,6 +9,7 @@ KADEMLIA_SOURCES = \ kademlia/refresh.cpp \ kademlia/routing_table.cpp \ kademlia/rpc_manager.cpp \ + kademlia/logging.cpp \ kademlia/traversal_algorithm.cpp endif diff --git a/src/kademlia/logging.cpp b/src/kademlia/logging.cpp new file mode 100644 index 000000000..0300bebc3 --- /dev/null +++ b/src/kademlia/logging.cpp @@ -0,0 +1,54 @@ +/* + +Copyright (c) 2006-2012, Arvid Norberg & Daniel Wallin +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the distribution. + * Neither the name of the author nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +*/ + +#include "libtorrent/kademlia/logging.hpp" + +namespace libtorrent { namespace dht +{ + log_event::log_event(log& log) + : log_(log) + { + if (log_.enabled()) + log_ << time_now_string() << " [" << log.id() << "] "; + } + + log_event::~log_event() + { + if (log_.enabled()) + { + log_ << "\n"; + log_.flush(); + } + } + +}} + diff --git a/src/session.cpp b/src/session.cpp index 13a6d6992..72d010283 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -86,15 +86,6 @@ void stop_malloc_debug(); namespace libtorrent { -#ifdef _MSC_VER - namespace aux - { - eh_initializer::eh_initializer() - { - ::_set_se_translator(straight_to_debugger); - } - } -#endif TORRENT_EXPORT void TORRENT_LINK_TEST_NAME() {} @@ -401,9 +392,21 @@ namespace libtorrent // configurations this will give a link error void TORRENT_EXPORT TORRENT_CFG() {} +#if defined _MSC_VER && defined TORRENT_DEBUG + static void straight_to_debugger(unsigned int, _EXCEPTION_POINTERS*) + { throw; } +#endif + void session::init(std::pair listen_range, char const* listen_interface , fingerprint const& id, boost::uint32_t alert_mask) { +#if defined _MSC_VER && defined TORRENT_DEBUG + // workaround for microsofts + // hardware exceptions that makes + // it hard to debug stuff + ::_set_se_translator(straight_to_debugger); +#endif + m_impl.reset(new session_impl(listen_range, id, listen_interface, alert_mask)); #ifdef TORRENT_MEMDEBUG @@ -1118,16 +1121,14 @@ namespace libtorrent TORRENT_ASYNC_CALL(start_lsd); } - natpmp* session::start_natpmp() + void session::start_natpmp() { - TORRENT_SYNC_CALL_RET(natpmp*, start_natpmp); - return r; + TORRENT_ASYNC_CALL(start_natpmp); } - upnp* session::start_upnp() + void session::start_upnp() { - TORRENT_SYNC_CALL_RET(upnp*, start_upnp); - return r; + TORRENT_ASYNC_CALL(start_upnp); } void session::stop_lsd() diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 74c0bdf14..db38e850e 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -4793,13 +4793,23 @@ retry: } } +#if defined _MSC_VER && defined TORRENT_DEBUG + static void straight_to_debugger(unsigned int, _EXCEPTION_POINTERS*) + { throw; } +#endif + void session_impl::main_thread() { +#if defined _MSC_VER && defined TORRENT_DEBUG + // workaround for microsofts + // hardware exceptions that makes + // it hard to debug stuff + ::_set_se_translator(straight_to_debugger); +#endif #if (defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS) && defined BOOST_HAS_PTHREADS m_network_thread = pthread_self(); #endif TORRENT_ASSERT(is_network_thread()); - eh_initializer(); // initialize async operations init(); @@ -6381,5 +6391,74 @@ retry: } #endif +#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING + tracker_logger::tracker_logger(session_impl& ses): m_ses(ses) {} + void tracker_logger::tracker_warning(tracker_request const& req + , std::string const& str) + { + debug_log("*** tracker warning: %s", str.c_str()); + } + + void tracker_logger::tracker_response(tracker_request const& + , libtorrent::address const& tracker_ip + , std::list
const& ip_list + , std::vector& peers + , int interval + , int min_interval + , int complete + , int incomplete + , int downloaded + , address const& external_ip + , std::string const& tracker_id) + { + std::string s; + s = "TRACKER RESPONSE:\n"; + char tmp[200]; + snprintf(tmp, 200, "interval: %d\nmin_interval: %d\npeers:\n", interval, min_interval); + s += tmp; + for (std::vector::const_iterator i = peers.begin(); + i != peers.end(); ++i) + { + char pid[41]; + to_hex((const char*)&i->pid[0], 20, pid); + if (i->pid.is_all_zeros()) pid[0] = 0; + + snprintf(tmp, 200, " %-16s %-5d %s\n", i->ip.c_str(), i->port, pid); + s += tmp; + } + snprintf(tmp, 200, "external ip: %s\n", print_address(external_ip).c_str()); + s += tmp; + debug_log("%s", s.c_str()); + } + + void tracker_logger::tracker_request_timed_out( + tracker_request const&) + { + debug_log("*** tracker timed out"); + } + + void tracker_logger::tracker_request_error(tracker_request const& r + , int response_code, error_code const& ec, const std::string& str + , int retry_interval) + { + debug_log("*** tracker error: %d: %s %s" + , response_code, ec.message().c_str(), str.c_str()); + } + + void tracker_logger::debug_log(const char* fmt, ...) const + { + if (!m_ses.m_logger) return; + + va_list v; + va_start(v, fmt); + + char usr[1024]; + vsnprintf(usr, sizeof(usr), fmt, v); + va_end(v); + char buf[1280]; + snprintf(buf, sizeof(buf), "%s: %s\n", time_now_string(), usr); + (*m_ses.m_logger) << buf; + } +#endif }} diff --git a/src/time.cpp b/src/time.cpp index 149e4c13c..53d9374d8 100644 --- a/src/time.cpp +++ b/src/time.cpp @@ -153,35 +153,32 @@ namespace libtorrent namespace libtorrent { - namespace aux + boost::int64_t performance_counter_to_microseconds(boost::int64_t pc) { - boost::int64_t performance_counter_to_microseconds(boost::int64_t pc) - { - static LARGE_INTEGER performace_counter_frequency = {0,0}; - if (performace_counter_frequency.QuadPart == 0) - QueryPerformanceFrequency(&performace_counter_frequency); + static LARGE_INTEGER performace_counter_frequency = {0,0}; + if (performace_counter_frequency.QuadPart == 0) + QueryPerformanceFrequency(&performace_counter_frequency); #ifdef TORRENT_DEBUG - // make sure we don't overflow - boost::int64_t ret = (pc * 1000 / performace_counter_frequency.QuadPart) * 1000; - TORRENT_ASSERT((pc >= 0 && pc >= ret) || (pc < 0 && pc < ret)); + // make sure we don't overflow + boost::int64_t ret = (pc * 1000 / performace_counter_frequency.QuadPart) * 1000; + TORRENT_ASSERT((pc >= 0 && pc >= ret) || (pc < 0 && pc < ret)); #endif - return ((pc * 1000 + performace_counter_frequency.QuadPart / 2) / performace_counter_frequency.QuadPart) * 1000; - } + return ((pc * 1000 + performace_counter_frequency.QuadPart / 2) / performace_counter_frequency.QuadPart) * 1000; + } - boost::int64_t microseconds_to_performance_counter(boost::int64_t ms) - { - static LARGE_INTEGER performace_counter_frequency = {0,0}; - if (performace_counter_frequency.QuadPart == 0) - QueryPerformanceFrequency(&performace_counter_frequency); + boost::int64_t microseconds_to_performance_counter(boost::int64_t ms) + { + static LARGE_INTEGER performace_counter_frequency = {0,0}; + if (performace_counter_frequency.QuadPart == 0) + QueryPerformanceFrequency(&performace_counter_frequency); #ifdef TORRENT_DEBUG - // make sure we don't overflow - boost::int64_t ret = (ms / 1000) * performace_counter_frequency.QuadPart / 1000; - TORRENT_ASSERT((ms >= 0 && ms <= ret) - || (ms < 0 && ms > ret)); + // make sure we don't overflow + boost::int64_t ret = (ms / 1000) * performace_counter_frequency.QuadPart / 1000; + TORRENT_ASSERT((ms >= 0 && ms <= ret) + || (ms < 0 && ms > ret)); #endif - return (ms / 1000) * performace_counter_frequency.QuadPart / 1000; - } + return (ms / 1000) * performace_counter_frequency.QuadPart / 1000; } ptime time_now_hires() @@ -190,6 +187,46 @@ namespace libtorrent QueryPerformanceCounter(&now); return ptime(now.QuadPart); } + + int total_seconds(time_duration td) + { + return int(performance_counter_to_microseconds(td.diff) + / 1000000); + } + int total_milliseconds(time_duration td) + { + return int(performance_counter_to_microseconds(td.diff) + / 1000); + } + boost::int64_t total_microseconds(time_duration td) + { + return performance_counter_to_microseconds(td.diff); + } + + time_duration microsec(boost::int64_t s) + { + return time_duration(aux::microseconds_to_performance_counter(s)); + } + time_duration milliseconds(boost::int64_t s) + { + return time_duration(aux::microseconds_to_performance_counter( + s * 1000)); + } + time_duration seconds(boost::int64_t s) + { + return time_duration(aux::microseconds_to_performance_counter( + s * 1000000)); + } + time_duration minutes(boost::int64_t s) + { + return time_duration(aux::microseconds_to_performance_counter( + s * 1000000 * 60)); + } + time_duration hours(boost::int64_t s) + { + return time_duration(aux::microseconds_to_performance_counter( + s * 1000000 * 60 * 60)); + } } #elif defined TORRENT_USE_CLOCK_GETTIME