From 74c8054e8d7131e719fe7da1159bf4097cae01d7 Mon Sep 17 00:00:00 2001 From: Alden Torres Date: Thu, 11 Aug 2016 20:32:14 -0400 Subject: [PATCH] created session_params and refactor (#993) created session_params and new session constructor --- include/libtorrent/aux_/session_impl.hpp | 14 +++ include/libtorrent/kademlia/dht_storage.hpp | 8 +- include/libtorrent/kademlia/dht_tracker.hpp | 6 +- include/libtorrent/session.hpp | 80 ++++++++++++--- include/libtorrent/settings_pack.hpp | 8 +- src/session.cpp | 92 +++++++++-------- src/session_impl.cpp | 17 +-- test/Jamfile | 13 ++- test/Makefile.am | 4 +- test/test_dht_storage.cpp | 1 - test/test_session_params.cpp | 108 ++++++++++++++++++++ 11 files changed, 256 insertions(+), 95 deletions(-) create mode 100644 test/test_session_params.cpp diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index 4943d5a94..2d8419878 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -86,6 +86,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/kademlia/dht_observer.hpp" #include "libtorrent/resolver.hpp" #include "libtorrent/invariant_check.hpp" +#include "libtorrent/extensions.hpp" #if TORRENT_COMPLETE_TYPES_REQUIRED #include "libtorrent/peer_connection.hpp" @@ -215,6 +216,19 @@ namespace libtorrent void init_peer_class_filter(bool unlimited_local); #ifndef TORRENT_DISABLE_EXTENSIONS + using ext_function_t + = boost::function(torrent_handle const&, void*)>; + + struct session_plugin_wrapper : plugin + { + explicit session_plugin_wrapper(ext_function_t const& f) : m_f(f) {} + explicit session_plugin_wrapper(session_plugin_wrapper const& p) : m_f(p.m_f) {} + + boost::shared_ptr new_torrent(torrent_handle const& t, void* user) override + { return m_f(t, user); } + ext_function_t m_f; + }; + void add_extension(boost::function( torrent_handle const&, void*)> ext); void add_ses_extension(boost::shared_ptr ext); diff --git a/include/libtorrent/kademlia/dht_storage.hpp b/include/libtorrent/kademlia/dht_storage.hpp index bdaa672af..decfd4cf2 100644 --- a/include/libtorrent/kademlia/dht_storage.hpp +++ b/include/libtorrent/kademlia/dht_storage.hpp @@ -33,11 +33,7 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef TORRENT_DHT_STORAGE_HPP #define TORRENT_DHT_STORAGE_HPP -#include "libtorrent/aux_/disable_warnings_push.hpp" - -#include - -#include "libtorrent/aux_/disable_warnings_pop.hpp" +#include #include #include @@ -224,7 +220,7 @@ namespace dht }; using dht_storage_constructor_type - = boost::function(dht_settings const& settings)>; + = std::function(dht_settings const& settings)>; TORRENT_EXPORT std::unique_ptr dht_default_storage_constructor(dht_settings const& settings); diff --git a/include/libtorrent/kademlia/dht_tracker.hpp b/include/libtorrent/kademlia/dht_tracker.hpp index dadb875a6..0e26826f0 100644 --- a/include/libtorrent/kademlia/dht_tracker.hpp +++ b/include/libtorrent/kademlia/dht_tracker.hpp @@ -35,11 +35,7 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef TORRENT_DHT_TRACKER #define TORRENT_DHT_TRACKER -#include -#include -#include #include -#include #include #include "libtorrent/kademlia/node.hpp" @@ -70,7 +66,7 @@ namespace libtorrent { namespace dht : udp_socket_interface , boost::enable_shared_from_this { - typedef boost::function, error_code&, int)> send_fun_t; dht_tracker(dht_observer* observer diff --git a/include/libtorrent/session.hpp b/include/libtorrent/session.hpp index 786dc572f..cf2e680dd 100644 --- a/include/libtorrent/session.hpp +++ b/include/libtorrent/session.hpp @@ -33,33 +33,25 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef TORRENT_SESSION_HPP_INCLUDED #define TORRENT_SESSION_HPP_INCLUDED -#include -#include #include #include "libtorrent/config.hpp" #include "libtorrent/build_config.hpp" #include "libtorrent/io_service.hpp" - -#include "libtorrent/storage.hpp" #include "libtorrent/settings_pack.hpp" #include "libtorrent/session_handle.hpp" +#include "libtorrent/session_settings.hpp" +#include "libtorrent/kademlia/dht_storage.hpp" #ifndef TORRENT_NO_DEPRECATE -#include "libtorrent/session_settings.hpp" #include "libtorrent/fingerprint.hpp" #include // for snprintf #endif -#ifdef TORRENT_USE_OPENSSL -// this is a nasty openssl macro -#ifdef set_key -#undef set_key -#endif -#endif - namespace libtorrent { + struct plugin; + // The default values of the session settings are set for a regular // bittorrent client running on a desktop system. There are functions that // can set the session settings to pre set settings for other environments. @@ -131,6 +123,34 @@ namespace libtorrent boost::shared_ptr m_impl; }; + // The session_params is a parameters pack for configuring the session + // before it's started. + struct TORRENT_EXPORT session_params + { + // This constructor can be used to start with the default plugins + // (ut_metadata, ut_pex and smart_ban). The default values in the + // settings is to start the default features like upnp, nat-pmp, + // and dht for example. + session_params(settings_pack sp = settings_pack()); + // This constructor helps to configure the set of initial plugins + // to be added to the session before it's started. + session_params(settings_pack sp + , std::vector> exts); + + session_params(session_params const&) = default; + session_params(session_params&&) = default; + session_params& operator=(session_params const&) = default; + session_params& operator=(session_params&&) = default; + + settings_pack settings; + + std::vector> extensions; + + libtorrent::dht_settings dht_settings; + + dht::dht_storage_constructor_type dht_storage_constructor; + }; + // The session holds all state that spans multiple torrents. Among other // things it runs the network loop and manages all torrents. Once it's // created, the session object will spawn the main thread that will do all @@ -147,6 +167,37 @@ namespace libtorrent { public: + // Constructs the session objects which acts as the container of torrents. + // In order to avoid a race condition between starting the session and + // configuring it, you can pass in a session_params object. Its settings + // will take effect before the session starts up. + session(session_params params = session_params()) + : session_handle(nullptr) + { + TORRENT_CFG(); + start(std::move(params), nullptr); + } + + // Overload of the constructor that takes an external io_service to run + // the session object on. This is primarily useful for tests that may want + // to run multiple sessions on a single io_service, or low resource + // systems where additional threads are expensive and sharing an + // io_service with other events is fine. + // + // .. warning:: + // The session object does not cleanly terminate with an external + // ``io_service``. The ``io_service::run()`` call _must_ have returned + // before it's safe to destruct the session. Which means you *MUST* + // call session::abort() and save the session_proxy first, then + // destruct the session object, then sync with the io_service, then + // destruct the session_proxy object. + session(session_params params, io_service& ios) + : session_handle(nullptr) + { + TORRENT_CFG(); + start(std::move(params), &ios); + } + // Constructs the session objects which acts as the container of torrents. // It provides configuration options across torrents (such as rate limits, // disk cache, ip filter etc.). In order to avoid a race condition between @@ -158,7 +209,7 @@ namespace libtorrent // nat-pmp) and default plugins (ut_metadata, ut_pex and smart_ban). The // default is to start those features. If you do not want them to start, // pass 0 as the flags parameter. - session(settings_pack pack = settings_pack() + session(settings_pack pack , int flags = start_default_features | add_default_plugins) : session_handle(nullptr) { @@ -281,7 +332,8 @@ namespace libtorrent private: - void start(int flags, settings_pack pack, io_service* ios); + void start(session_params params, io_service* ios); + void start(int flags, settings_pack sp, io_service* ios); // data shared between the main thread // and the working thread diff --git a/include/libtorrent/settings_pack.hpp b/include/libtorrent/settings_pack.hpp index 1ad29f5a1..40d391c6e 100644 --- a/include/libtorrent/settings_pack.hpp +++ b/include/libtorrent/settings_pack.hpp @@ -1332,7 +1332,7 @@ namespace libtorrent // ``utp_syn_resends`` is the number of SYN packets that are sent (and // timed out) before giving up and closing the socket. // ``utp_num_resends`` is the number of times a packet is sent (and - // lossed or timed out) before giving up and closing the connection. + // lost or timed out) before giving up and closing the connection. // ``utp_connect_timeout`` is the number of milliseconds of timeout // for the initial SYN packet for uTP connections. For each timed out // packet (in a row), the timeout is doubled. ``utp_loss_multiplier`` @@ -1686,9 +1686,9 @@ namespace libtorrent }; private: - std::vector > m_strings; - std::vector > m_ints; - std::vector > m_bools; + std::vector> m_strings; + std::vector> m_ints; + std::vector> m_bools; }; } diff --git a/src/session.cpp b/src/session.cpp index 6fb9edfae..10a069d58 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -31,51 +31,18 @@ POSSIBILITY OF SUCH DAMAGE. */ #include "libtorrent/config.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include "libtorrent/extensions/ut_pex.hpp" #include "libtorrent/extensions/ut_metadata.hpp" #include "libtorrent/extensions/smart_ban.hpp" -#include "libtorrent/peer_id.hpp" -#include "libtorrent/torrent_info.hpp" -#include "libtorrent/tracker_manager.hpp" -#include "libtorrent/bencode.hpp" -#include "libtorrent/hasher.hpp" -#include "libtorrent/entry.hpp" #include "libtorrent/session.hpp" -#include "libtorrent/session_handle.hpp" -#include "libtorrent/fingerprint.hpp" -#include "libtorrent/entry.hpp" -#include "libtorrent/alert_types.hpp" -#include "libtorrent/invariant_check.hpp" -#include "libtorrent/file.hpp" -#include "libtorrent/bt_peer_connection.hpp" -#include "libtorrent/ip_filter.hpp" -#include "libtorrent/socket.hpp" #include "libtorrent/aux_/session_impl.hpp" -#include "libtorrent/kademlia/dht_tracker.hpp" -#include "libtorrent/natpmp.hpp" -#include "libtorrent/upnp.hpp" -#include "libtorrent/magnet_uri.hpp" -#include "libtorrent/lazy_entry.hpp" #include "libtorrent/aux_/session_call.hpp" -using boost::shared_ptr; using libtorrent::aux::session_impl; namespace libtorrent { - TORRENT_EXPORT void min_memory_usage(settings_pack& set) + void min_memory_usage(settings_pack& set) { #ifndef TORRENT_NO_DEPRECATE // receive data directly into disk buffers @@ -164,7 +131,7 @@ namespace libtorrent set.set_bool(settings_pack::coalesce_writes, false); } - TORRENT_EXPORT void high_performance_seed(settings_pack& set) + void high_performance_seed(settings_pack& set) { // don't throttle TCP, assume there is // plenty of bandwidth @@ -322,7 +289,7 @@ namespace libtorrent // configurations this will give a link error void TORRENT_EXPORT TORRENT_CFG() {} - void session::start(int flags, settings_pack pack, io_service* ios) + void session::start(session_params params, io_service* ios) { bool const internal_executor = ios == nullptr; @@ -337,17 +304,16 @@ namespace libtorrent *static_cast(this) = session_handle(m_impl.get()); #ifndef TORRENT_DISABLE_EXTENSIONS - if (flags & add_default_plugins) + for (auto const& ext : params.extensions) { - add_extension(create_ut_pex_plugin); - add_extension(create_ut_metadata_plugin); - add_extension(create_smart_ban_plugin); + m_impl->add_ses_extension(ext); } -#else - TORRENT_UNUSED(flags); #endif - m_impl->start_session(std::move(pack)); + set_dht_settings(params.dht_settings); + set_dht_storage(params.dht_storage_constructor); + + m_impl->start_session(std::move(params.settings)); if (internal_executor) { @@ -357,6 +323,32 @@ namespace libtorrent } } + namespace + { + std::vector> default_plugins( + bool empty = false) + { +#ifndef TORRENT_DISABLE_EXTENSIONS + if (empty) return {}; + using wrapper = session_impl::session_plugin_wrapper; + return { + boost::make_shared(wrapper(create_ut_pex_plugin)), + boost::make_shared(wrapper(create_ut_metadata_plugin)), + boost::make_shared(wrapper(create_smart_ban_plugin)) + }; +#else + TORRENT_UNUSED(empty); + return {}; +#endif + } + } + + void session::start(int flags, settings_pack sp, io_service* ios) + { + start({std::move(sp), + default_plugins((flags & add_default_plugins) == 0)}, ios); + } + session::~session() { aux::dump_call_profile(); @@ -413,5 +405,17 @@ namespace libtorrent if (m_thread && m_thread.unique()) m_thread->join(); } -} + session_params::session_params(settings_pack sp) + : session_params(sp, default_plugins()) + {} + + session_params::session_params(settings_pack sp + , std::vector> exts) + : settings(std::move(sp)) + , extensions(std::move(exts)) +#ifndef TORRENT_DISABLE_DHT + , dht_storage_constructor(dht::dht_default_storage_constructor) +#endif + {} +} diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 38e8b7741..5c22f2834 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -91,7 +91,6 @@ const rlim_t rlim_infinity = RLIM_INFINITY; #include "libtorrent/instantiate_connection.hpp" #include "libtorrent/peer_info.hpp" #include "libtorrent/build_config.hpp" -#include "libtorrent/extensions.hpp" #include "libtorrent/random.hpp" #include "libtorrent/magnet_uri.hpp" #include "libtorrent/aux_/session_settings.hpp" @@ -772,25 +771,13 @@ namespace aux { #ifndef TORRENT_DISABLE_EXTENSIONS - typedef boost::function(torrent_handle const&, void*)> ext_function_t; - - struct session_plugin_wrapper : plugin - { - explicit session_plugin_wrapper(ext_function_t const& f) : m_f(f) {} - - boost::shared_ptr new_torrent(torrent_handle const& t, void* user) override - { return m_f(t, user); } - ext_function_t m_f; - }; - void session_impl::add_extension(ext_function_t ext) { TORRENT_ASSERT(is_single_thread()); TORRENT_ASSERT_VAL(ext, ext); - boost::shared_ptr p(new session_plugin_wrapper(ext)); - - add_ses_extension(p); + add_ses_extension(boost::make_shared( + session_plugin_wrapper(ext))); } void session_impl::add_ses_extension(boost::shared_ptr ext) diff --git a/test/Jamfile b/test/Jamfile index 1e7253d7d..2e92095c7 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -160,6 +160,7 @@ test-suite libtorrent : [ run test_magnet.cpp ] [ run test_storage.cpp ] [ run test_session.cpp ] + [ run test_session_params.cpp ] [ run test_read_piece.cpp ] [ run test_file.cpp ] @@ -225,16 +226,18 @@ alias win-tests : test_tracker test_checking test_piece_picker + test_ffs + test_session_params ; explicit win-tests ; alias arm-tests : - test_sha1_hash - test_bitfield - test_crc32 - test_ffs - ; + test_sha1_hash + test_bitfield + test_crc32 + test_ffs + ; explicit arm-tests ; diff --git a/test/Makefile.am b/test/Makefile.am index ebb256614..7843043c7 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -44,7 +44,8 @@ test_programs = \ test_file_progress \ test_linked_list \ test_direct_dht \ - test_ffs + test_ffs \ + test_session_params if ENABLE_TESTS check_PROGRAMS = $(test_programs) @@ -227,6 +228,7 @@ test_file_progress_SOURCES = test_file_progress.cpp test_linked_list_SOURCES = test_linked_list.cpp test_direct_dht_SOURCES = test_direct_dht.cpp test_ffs_SOURCES = test_ffs.cpp +test_session_params_SOURCES = test_session_params.cpp LDADD = libtest.la $(top_builddir)/src/libtorrent-rasterbar.la diff --git a/test/test_dht_storage.cpp b/test/test_dht_storage.cpp index 745debcac..d925768f0 100644 --- a/test/test_dht_storage.cpp +++ b/test/test_dht_storage.cpp @@ -366,4 +366,3 @@ TORRENT_TEST(update_node_ids) } #endif - diff --git a/test/test_session_params.cpp b/test/test_session_params.cpp new file mode 100644 index 000000000..a8aaa0797 --- /dev/null +++ b/test/test_session_params.cpp @@ -0,0 +1,108 @@ +/* + +Copyright (c) 2016, Alden Torres +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/config.hpp" +#include "libtorrent/session.hpp" +#include "libtorrent/extensions.hpp" + +#include "test.hpp" + +using namespace libtorrent; +using namespace libtorrent::dht; +namespace lt = libtorrent; + +namespace +{ +#ifndef TORRENT_DISABLE_DHT + bool g_storage_constructor_invoked = false; + + std::unique_ptr dht_custom_storage_constructor( + dht_settings const& settings) + { + g_storage_constructor_invoked = true; + return dht_default_storage_constructor(settings); + } +#endif + +#ifndef TORRENT_DISABLE_EXTENSIONS + bool g_plugin_added_invoked = false; + + struct custom_plugin : plugin + { + void added(session_handle h) override + { + TORRENT_UNUSED(h); + g_plugin_added_invoked = true; + } + }; +#endif +} + +TORRENT_TEST(default_plugins) +{ + session_params p1; +#ifndef TORRENT_DISABLE_EXTENSIONS + TEST_EQUAL(int(p1.extensions.size()), 3); +#else + TEST_EQUAL(int(p1.extensions.size()), 0); +#endif + + std::vector> exts; + session_params p2(settings_pack(), exts); + TEST_EQUAL(int(p2.extensions.size()), 0); +} + +#ifndef TORRENT_DISABLE_DHT +TORRENT_TEST(custom_dht_storage) +{ + g_storage_constructor_invoked = false; + session_params params; + params.dht_storage_constructor = dht_custom_storage_constructor; + lt::session ses(params); + + + TEST_CHECK(ses.is_dht_running() == true); + TEST_EQUAL(g_storage_constructor_invoked, true); +} +#endif + +#ifndef TORRENT_DISABLE_EXTENSIONS +TORRENT_TEST(add_plugin) +{ + g_plugin_added_invoked = false; + session_params params; + params.extensions.push_back(boost::make_shared()); + lt::session ses(params); + + TEST_EQUAL(g_plugin_added_invoked, true); +} +#endif