diff --git a/.travis.yml b/.travis.yml index e41164d79..588951c87 100644 --- a/.travis.yml +++ b/.travis.yml @@ -220,7 +220,11 @@ script: # libtorrent is the name of the test suite target - cd test - 'if [ "$tests" == "1" ]; then - travis_retry bjam -j3 warnings-as-errors=on warnings=all crypto=$crypto debug-iterators=on picker-debugging=on asserts=on invariant-checks=full $toolset variant=$variant libtorrent test_natpmp enum_if -l300 && + travis_retry bjam -j3 warnings-as-errors=on warnings=all crypto=$crypto debug-iterators=on picker-debugging=on asserts=on invariant-checks=full $toolset variant=$variant -l300 && + travis_retry bjam -j3 warnings-as-errors=on warnings=all crypto=$crypto debug-iterators=on picker-debugging=on asserts=on invariant-checks=full $toolset variant=$variant test_natpmp enum_if -l300 && + if [[ $TRAVIS_OS_NAME != "osx" ]]; then + travis_retry bjam -j3 warnings-as-errors=on warnings=all crypto=$crypto debug-iterators=on picker-debugging=on asserts=on invariant-checks=full $toolset variant=$variant test_lsd -l300; + fi && if [ "$coverage" == "1" ]; then codecov --root .. --gcov-exec gcov-5; fi; diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index 7648c7c02..d52f8f672 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -476,7 +476,7 @@ namespace aux { port_filter const& get_port_filter() const override; void ban_ip(address addr) override; - void queue_tracker_request(tracker_request& req + void queue_tracker_request(tracker_request&& req , std::weak_ptr c) override; // ==== peer class operations ==== @@ -509,7 +509,9 @@ namespace aux { std::shared_ptr const& torrent_ptr, void* userdata); #endif - torrent_handle add_torrent(add_torrent_params, error_code& ec); + // the add_torrent_params object must be moved in + torrent_handle add_torrent(add_torrent_params&&, error_code& ec); + // second return value is true if the torrent was added and false if an // existing one was found. std::pair, bool> diff --git a/include/libtorrent/aux_/session_interface.hpp b/include/libtorrent/aux_/session_interface.hpp index 3c7f6815e..b7a70634f 100644 --- a/include/libtorrent/aux_/session_interface.hpp +++ b/include/libtorrent/aux_/session_interface.hpp @@ -233,8 +233,11 @@ namespace aux { virtual void apply_settings_pack(std::shared_ptr pack) = 0; virtual session_settings const& settings() const = 0; - virtual void queue_tracker_request(tracker_request& req + // the tracker request object must be moved in + virtual void queue_tracker_request(tracker_request&& req , std::weak_ptr c) = 0; + void queue_tracker_request(tracker_request const& req + , std::weak_ptr c) = delete; // peer-classes virtual void set_peer_classes(peer_class_set* s, address const& a, int st) = 0; diff --git a/include/libtorrent/kademlia/item.hpp b/include/libtorrent/kademlia/item.hpp index 06b47e440..718ad272c 100644 --- a/include/libtorrent/kademlia/item.hpp +++ b/include/libtorrent/kademlia/item.hpp @@ -74,7 +74,7 @@ TORRENT_EXPORT signature sign_mutable_item( class TORRENT_EXTRA_EXPORT item { public: - item() : m_seq(0), m_mutable(false) {} + item() {} item(public_key const& pk, span salt); explicit item(entry v); item(entry v @@ -117,8 +117,8 @@ private: std::string m_salt; public_key m_pk; signature m_sig; - sequence_number m_seq; - bool m_mutable; + sequence_number m_seq{0}; + bool m_mutable = false; }; } } // namespace libtorrent::dht diff --git a/include/libtorrent/kademlia/put_data.hpp b/include/libtorrent/kademlia/put_data.hpp index a21502a7f..61e198004 100644 --- a/include/libtorrent/kademlia/put_data.hpp +++ b/include/libtorrent/kademlia/put_data.hpp @@ -54,7 +54,8 @@ struct put_data: traversal_algorithm char const* name() const override; void start() override; - void set_data(item const& data) { m_data = data; } + void set_data(item&& data) { m_data = std::move(data); } + void set_data(item const& data) = delete; void set_targets(std::vector> const& targets); diff --git a/include/libtorrent/session_handle.hpp b/include/libtorrent/session_handle.hpp index 679ec13df..835934762 100644 --- a/include/libtorrent/session_handle.hpp +++ b/include/libtorrent/session_handle.hpp @@ -212,8 +212,10 @@ namespace libtorrent { // // all torrent_handles must be destructed before the session is destructed! #ifndef BOOST_NO_EXCEPTIONS + torrent_handle add_torrent(add_torrent_params&& params); torrent_handle add_torrent(add_torrent_params const& params); #endif + torrent_handle add_torrent(add_torrent_params&& params, error_code& ec); torrent_handle add_torrent(add_torrent_params const& params, error_code& ec); void async_add_torrent(add_torrent_params&& params); void async_add_torrent(add_torrent_params const& params); diff --git a/include/libtorrent/tracker_manager.hpp b/include/libtorrent/tracker_manager.hpp index e2192d3be..0b5a0f6be 100644 --- a/include/libtorrent/tracker_manager.hpp +++ b/include/libtorrent/tracker_manager.hpp @@ -357,9 +357,14 @@ namespace libtorrent { void queue_request( io_service& ios - , tracker_request r + , tracker_request&& r , std::weak_ptr c = std::weak_ptr()); + void queue_request( + io_service& ios + , tracker_request const& r + , std::weak_ptr c + = std::weak_ptr()) = delete; void abort_all_requests(bool all = false); void remove_request(http_tracker_connection const* c); diff --git a/src/kademlia/node.cpp b/src/kademlia/node.cpp index 2f82e96b7..5577d7906 100644 --- a/src/kademlia/node.cpp +++ b/src/kademlia/node.cpp @@ -516,15 +516,16 @@ void put(std::vector> const& nodes ta->start(); } -void put_data_cb(item i, bool auth +void put_data_cb(item const& i, bool auth , std::shared_ptr const& ta , std::function const& f) { // call data_callback only when we got authoritative data. if (auth) { - f(i); - ta->set_data(i); + item copy(i); + f(copy); + ta->set_data(std::move(copy)); } } @@ -543,7 +544,7 @@ void node::put_item(sha1_hash const& target, entry const& data, std::function(*this, std::bind(f, _2)); - put_ta->set_data(i); + put_ta->set_data(std::move(i)); auto ta = std::make_shared(*this, target , get_item::data_callback(), std::bind(&put, _1, put_ta)); diff --git a/src/session_handle.cpp b/src/session_handle.cpp index 47af91c63..f617efffa 100644 --- a/src/session_handle.cpp +++ b/src/session_handle.cpp @@ -360,37 +360,41 @@ namespace { #endif // TORRENT_ABI_VERSION #ifndef BOOST_NO_EXCEPTIONS - torrent_handle session_handle::add_torrent(add_torrent_params const& params) + torrent_handle session_handle::add_torrent(add_torrent_params&& params) { TORRENT_ASSERT_PRECOND(!params.save_path.empty()); #if TORRENT_ABI_VERSION == 1 - add_torrent_params p = params; - handle_backwards_compatible_resume_data(p); -#else - add_torrent_params const& p = params; + handle_backwards_compatible_resume_data(params); #endif error_code ec; auto ecr = std::ref(ec); - torrent_handle r = sync_call_ret(&session_impl::add_torrent, p, ecr); + torrent_handle r = sync_call_ret(&session_impl::add_torrent, std::move(params), ecr); if (ec) aux::throw_ex(ec); return r; } + + torrent_handle session_handle::add_torrent(add_torrent_params const& params) + { + return add_torrent(add_torrent_params(params)); + } #endif - torrent_handle session_handle::add_torrent(add_torrent_params const& params, error_code& ec) + torrent_handle session_handle::add_torrent(add_torrent_params&& params, error_code& ec) { TORRENT_ASSERT_PRECOND(!params.save_path.empty()); ec.clear(); #if TORRENT_ABI_VERSION == 1 - add_torrent_params p = params; - handle_backwards_compatible_resume_data(p); -#else - add_torrent_params const& p = params; + handle_backwards_compatible_resume_data(params); #endif auto ecr = std::ref(ec); - return sync_call_ret(&session_impl::add_torrent, p, ecr); + return sync_call_ret(&session_impl::add_torrent, std::move(params), ecr); + } + + torrent_handle session_handle::add_torrent(add_torrent_params const& params, error_code& ec) + { + return add_torrent(add_torrent_params(params), ec); } void session_handle::async_add_torrent(add_torrent_params const& params) diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 0d8c418e4..4d933788f 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -1035,7 +1035,7 @@ namespace aux { return ret; } - void session_impl::queue_tracker_request(tracker_request& req + void session_impl::queue_tracker_request(tracker_request&& req , std::weak_ptr c) { #if TORRENT_USE_I2P @@ -1062,7 +1062,7 @@ namespace aux { use_ssl ? ssl_listen_port(ls) : #endif listen_port(ls); - m_tracker_manager.queue_request(get_io_service(), req, c); + m_tracker_manager.queue_request(get_io_service(), std::move(req), c); } else { @@ -1071,7 +1071,8 @@ namespace aux { #ifdef TORRENT_USE_OPENSSL if ((ls->ssl == transport::ssl) != use_ssl) continue; #endif - req.listen_port = + tracker_request socket_req(req); + socket_req.listen_port = #ifdef TORRENT_USE_OPENSSL // SSL torrents use the SSL listen port use_ssl ? ssl_listen_port(ls.get()) : @@ -1080,9 +1081,9 @@ namespace aux { // we combine the per-torrent key with the per-interface key to make // them consistent and unique per torrent and interface - req.key ^= ls->tracker_key; - req.outgoing_socket = ls; - m_tracker_manager.queue_request(get_io_service(), req, c); + socket_req.key ^= ls->tracker_key; + socket_req.outgoing_socket = ls; + m_tracker_manager.queue_request(get_io_service(), std::move(socket_req), c); } } } @@ -4353,7 +4354,7 @@ namespace aux { if (e->on_unknown_torrent(info_hash, peer_connection_handle(pc->self()), p)) { error_code ec; - torrent_handle handle = add_torrent(p, ec); + torrent_handle handle = add_torrent(std::move(p), ec); return handle.native_handle(); } @@ -4735,7 +4736,7 @@ namespace aux { } #endif - torrent_handle session_impl::add_torrent(add_torrent_params params + torrent_handle session_impl::add_torrent(add_torrent_params&& params , error_code& ec) { // params is updated by add_torrent_impl() diff --git a/src/torrent.cpp b/src/torrent.cpp index b0869bed4..9029861a4 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -2919,12 +2919,12 @@ bool is_downloading_state(int const st) if (m_abort && m_ses.should_log()) { auto tl = std::make_shared(m_ses); - m_ses.queue_tracker_request(req, tl); + m_ses.queue_tracker_request(tracker_request(req), tl); } else #endif { - m_ses.queue_tracker_request(req, shared_from_this()); + m_ses.queue_tracker_request(tracker_request(req), shared_from_this()); } aep.updating = true; @@ -2979,7 +2979,7 @@ bool is_downloading_state(int const st) #endif req.key = tracker_key(); req.triggered_manually = user_triggered; - m_ses.queue_tracker_request(req, shared_from_this()); + m_ses.queue_tracker_request(std::move(req), shared_from_this()); } void torrent::tracker_warning(tracker_request const& req, std::string const& msg) diff --git a/src/tracker_manager.cpp b/src/tracker_manager.cpp index 1f519c9cb..415ecf6be 100644 --- a/src/tracker_manager.cpp +++ b/src/tracker_manager.cpp @@ -256,7 +256,7 @@ namespace libtorrent { void tracker_manager::queue_request( io_service& ios - , tracker_request req + , tracker_request&& req , std::weak_ptr c) { TORRENT_ASSERT(is_single_thread()); @@ -278,14 +278,14 @@ namespace libtorrent { if (protocol == "http") #endif { - auto con = std::make_shared(ios, *this, req, c); + auto con = std::make_shared(ios, *this, std::move(req), c); m_http_conns.push_back(con); con->start(); return; } else if (protocol == "udp") { - auto con = std::make_shared(ios, *this, req, c); + auto con = std::make_shared(ios, *this, std::move(req), c); m_udp_conns[con->transaction_id()] = con; con->start(); return; @@ -293,7 +293,7 @@ namespace libtorrent { // we need to post the error to avoid deadlock if (std::shared_ptr r = c.lock()) - ios.post(std::bind(&request_callback::tracker_request_error, r, req + ios.post(std::bind(&request_callback::tracker_request_error, r, std::move(req) , error_code(errors::unsupported_url_protocol) , "", seconds32(0))); } diff --git a/test/Jamfile b/test/Jamfile index b1bb8dfb1..f6765f480 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -101,128 +101,124 @@ explicit test_natpmp ; explicit enum_if ; explicit stage_enum_if ; -test-suite libtorrent : - [ run - test_primitives.cpp - test_io.cpp - test_create_torrent.cpp - test_packet_buffer.cpp - test_timestamp_history.cpp - test_bloom_filter.cpp - test_identify_client.cpp - test_merkle.cpp - test_resolve_links.cpp - test_heterogeneous_queue.cpp - test_ip_voter.cpp - test_sliding_average.cpp - test_socket_io.cpp -# test_random.cpp - test_part_file.cpp - test_peer_list.cpp - test_torrent_info.cpp - test_time.cpp - test_file_storage.cpp - test_peer_priority.cpp - test_threads.cpp - test_tailqueue.cpp - test_bandwidth_limiter.cpp - test_buffer.cpp - test_bencoding.cpp - test_bdecode.cpp - test_http_parser.cpp - test_xml.cpp - test_ip_filter.cpp - test_hasher.cpp - test_block_cache.cpp - test_peer_classes.cpp - test_settings_pack.cpp - test_fence.cpp - test_dos_blocker.cpp - test_stat_cache.cpp - test_enum_net.cpp - test_linked_list.cpp - test_stack_allocator.cpp - test_file_progress.cpp - test_generate_peer_id.cpp - test_alloca.cpp ] +run + test_primitives.cpp + test_io.cpp + test_create_torrent.cpp + test_packet_buffer.cpp + test_timestamp_history.cpp + test_bloom_filter.cpp + test_identify_client.cpp + test_merkle.cpp + test_resolve_links.cpp + test_heterogeneous_queue.cpp + test_ip_voter.cpp + test_sliding_average.cpp + test_socket_io.cpp + test_part_file.cpp + test_peer_list.cpp + test_torrent_info.cpp + test_time.cpp + test_file_storage.cpp + test_peer_priority.cpp + test_threads.cpp + test_tailqueue.cpp + test_bandwidth_limiter.cpp + test_buffer.cpp + test_bencoding.cpp + test_bdecode.cpp + test_http_parser.cpp + test_xml.cpp + test_ip_filter.cpp + test_hasher.cpp + test_block_cache.cpp + test_peer_classes.cpp + test_settings_pack.cpp + test_fence.cpp + test_dos_blocker.cpp + test_stat_cache.cpp + test_enum_net.cpp + test_linked_list.cpp + test_stack_allocator.cpp + test_file_progress.cpp + test_generate_peer_id.cpp + test_alloca.cpp ; - [ run test_listen_socket.cpp - : : : openssl:/torrent//ssl - openssl:/torrent//crypto - ] +run test_listen_socket.cpp + : : : openssl:/torrent//ssl + openssl:/torrent//crypto ; - [ run test_piece_picker.cpp ] +run test_piece_picker.cpp ; - [ run test_dht.cpp - test_dht_storage.cpp - test_direct_dht.cpp - test_hasher512.cpp - : : : openssl:/torrent//ssl - openssl:/torrent//crypto - ] +run test_dht.cpp + test_dht_storage.cpp + test_direct_dht.cpp + test_hasher512.cpp + : : : openssl:/torrent//ssl + openssl:/torrent//crypto ; - [ run test_string.cpp test_utf8.cpp ] +run test_string.cpp test_utf8.cpp ; - [ run test_sha1_hash.cpp ] - [ run test_span.cpp ] - [ run test_bitfield.cpp ] - [ run test_crc32.cpp ] - [ run test_ffs.cpp ] - [ run test_ed25519.cpp ] - [ run test_gzip.cpp ] - [ run test_receive_buffer.cpp ] - [ run test_alert_manager.cpp ] - [ run test_alert_types.cpp ] - [ run test_magnet.cpp ] - [ run test_storage.cpp ] - [ run test_session.cpp ] - [ run test_session_params.cpp ] - [ run test_read_piece.cpp ] - [ run test_remove_torrent.cpp ] - [ run test_flags.cpp ] +run test_sha1_hash.cpp ; +run test_span.cpp ; +run test_bitfield.cpp ; +run test_crc32.cpp ; +run test_ffs.cpp ; +run test_ed25519.cpp ; +run test_gzip.cpp ; +run test_receive_buffer.cpp ; +run test_alert_manager.cpp ; +run test_alert_types.cpp ; +run test_magnet.cpp ; +run test_storage.cpp ; +run test_session.cpp ; +run test_session_params.cpp ; +run test_read_piece.cpp ; +run test_remove_torrent.cpp ; +run test_flags.cpp ; - [ run test_file.cpp ] - [ run test_fast_extension.cpp ] - [ run test_privacy.cpp ] - [ run test_recheck.cpp ] - [ run test_read_resume.cpp ] - [ run test_resume.cpp ] - [ run test_ssl.cpp : : +run test_file.cpp ; +run test_fast_extension.cpp ; +run test_privacy.cpp ; +run test_recheck.cpp ; +run test_read_resume.cpp ; +run test_resume.cpp ; +run test_ssl.cpp : : + : openssl:/torrent//ssl + openssl:/torrent//crypto ; +run test_tracker.cpp ; +run test_checking.cpp ; +run test_url_seed.cpp ; +run test_web_seed.cpp ; +run test_web_seed_redirect.cpp ; +run test_web_seed_socks4.cpp ; +run test_web_seed_socks5.cpp ; +run test_web_seed_socks5_no_peers.cpp ; +run test_web_seed_socks5_pw.cpp ; +run test_web_seed_http.cpp ; +run test_web_seed_http_pw.cpp ; +run test_web_seed_chunked.cpp ; +run test_web_seed_ban.cpp ; +run test_pe_crypto.cpp ; + +run test_remap_files.cpp ; +run test_utp.cpp ; +run test_auto_unchoke.cpp ; +run test_http_connection.cpp : : : openssl:/torrent//ssl openssl:/torrent//crypto - ] - [ run test_tracker.cpp ] - [ run test_checking.cpp ] - [ run test_url_seed.cpp ] - [ run test_web_seed.cpp ] - [ run test_web_seed_redirect.cpp ] - [ run test_web_seed_socks4.cpp ] - [ run test_web_seed_socks5.cpp ] - [ run test_web_seed_socks5_no_peers.cpp ] - [ run test_web_seed_socks5_pw.cpp ] - [ run test_web_seed_http.cpp ] - [ run test_web_seed_http_pw.cpp ] - [ run test_web_seed_chunked.cpp ] - [ run test_web_seed_ban.cpp ] - [ run test_pe_crypto.cpp ] - - [ run test_remap_files.cpp ] - [ run test_utp.cpp ] - [ run test_auto_unchoke.cpp ] - [ run test_http_connection.cpp : : - : openssl:/torrent//ssl - openssl:/torrent//crypto - ] - [ run test_torrent.cpp ] - [ run test_transfer.cpp ] - [ run test_time_critical.cpp ] - [ run test_pex.cpp ] - [ run test_priority.cpp ] + ; +run test_torrent.cpp ; +run test_transfer.cpp ; +run test_time_critical.cpp ; +run test_pex.cpp ; +run test_priority.cpp ; # turn these tests into simulations - [ run test_upnp.cpp ] - [ run test_lsd.cpp ] - ; +run test_upnp.cpp ; + +run test_lsd.cpp ; +explicit test_lsd ; # these are the tests run on appveyor, while the flapping ones are being # transitioned into simulations @@ -231,6 +227,7 @@ alias win-tests : test_string test_dht test_sha1_hash + test_span test_bitfield test_crc32 test_pe_crypto diff --git a/test/Makefile.am b/test/Makefile.am index f91a65645..ec5149757 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -190,7 +190,6 @@ test_primitives_SOURCES = \ test_ip_voter.cpp \ test_sliding_average.cpp \ test_socket_io.cpp \ - test_random.cpp \ test_utf8.cpp \ test_gzip.cpp \ test_bitfield.cpp \ diff --git a/test/test_random.cpp b/test/test_random.cpp deleted file mode 100644 index cced2cebc..000000000 --- a/test/test_random.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - -Copyright (c) 2014, Arvid Norberg -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 "test.hpp" -#include "setup_transfer.hpp" -#include "libtorrent/random.hpp" - -#include - -using namespace lt; - -TORRENT_TEST(random) -{ - - const int repetitions = 200000; - - for (int byte = 0; byte < 4; ++byte) - { - std::array buckets; - buckets.fill(0); - - for (int i = 0; i < repetitions; ++i) - { - std::uint32_t val = lt::random(0xffffffff); - val >>= byte * 8; - ++buckets[val & 0xff]; - } - - for (std::size_t i = 0; i < 256; ++i) - { - const int expected = repetitions / 256; - // expect each bucket to be within 15% of the expected value - std::printf("%d: %f\n", int(i), double(buckets[i] - expected) * 100.0 / expected); - TEST_CHECK(std::abs(buckets[i] - expected) < expected / 6); - } - } -}