From 0dbbc18186f2cf084af95d3948f1f18693a69761 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sun, 25 Jan 2004 18:18:36 +0000 Subject: [PATCH] removed most warnings on msvc. reimplemented piece_manager::check_pieces to take care of all possible cases of the storage state. --- docs/manual.html | 7 +- docs/manual.rst | 7 +- examples/client_test.cpp | 16 +- include/libtorrent/alert.hpp | 15 +- include/libtorrent/bencode.hpp | 9 + include/libtorrent/debug.hpp | 8 + include/libtorrent/file.hpp | 8 + include/libtorrent/invariant_check.hpp | 77 +++++ include/libtorrent/peer_connection.hpp | 23 +- include/libtorrent/peer_info.hpp | 8 +- include/libtorrent/piece_picker.hpp | 8 + include/libtorrent/policy.hpp | 10 +- include/libtorrent/session.hpp | 11 +- include/libtorrent/size_type.hpp | 8 + include/libtorrent/socket.hpp | 11 +- include/libtorrent/stat.hpp | 22 +- include/libtorrent/storage.hpp | 33 +- include/libtorrent/torrent.hpp | 10 +- include/libtorrent/torrent_handle.hpp | 9 + include/libtorrent/torrent_info.hpp | 25 +- src/identify_client.cpp | 11 +- src/peer_connection.cpp | 141 ++++++--- src/piece_picker.cpp | 48 +-- src/policy.cpp | 74 +++-- src/session.cpp | 39 ++- src/stat.cpp | 7 +- src/storage.cpp | 415 ++++++++++++++++++++----- src/torrent.cpp | 16 +- src/torrent_handle.cpp | 14 +- src/torrent_info.cpp | 16 +- 30 files changed, 857 insertions(+), 249 deletions(-) create mode 100755 include/libtorrent/invariant_check.hpp diff --git a/docs/manual.html b/docs/manual.html index 90779cbb9..c067d9c72 100755 --- a/docs/manual.html +++ b/docs/manual.html @@ -712,14 +712,15 @@ struct peer_info address ip; float up_speed; float down_speed; - unsigned int total_download; - unsigned int total_upload; + size_type total_download; + size_type total_upload; peer_id id; std::vector<bool> pieces; int upload_limit; int upload_ceiling; - int load_balancing; + size_type load_balancing; + int download_queue_length; int upload_queue_length; diff --git a/docs/manual.rst b/docs/manual.rst index 40f4378c4..1b6ff9715 100755 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -718,14 +718,15 @@ fields:: address ip; float up_speed; float down_speed; - unsigned int total_download; - unsigned int total_upload; + size_type total_download; + size_type total_upload; peer_id id; std::vector pieces; int upload_limit; int upload_ceiling; - int load_balancing; + size_type load_balancing; + int download_queue_length; int upload_queue_length; diff --git a/examples/client_test.cpp b/examples/client_test.cpp index 6da01d645..159e89b67 100755 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -35,11 +35,19 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + #include #include #include #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #include "libtorrent/entry.hpp" #include "libtorrent/bencode.hpp" #include "libtorrent/session.hpp" @@ -261,7 +269,7 @@ int main(int argc, char* argv[]) handles.push_back(ses.add_torrent(t, save_path, resume_data)); handles.back().set_max_connections(60); handles.back().set_max_uploads(-1); - handles.back().set_ratio(1.02); + handles.back().set_ratio(1.02f); } catch (std::exception& e) { @@ -342,9 +350,9 @@ int main(int argc, char* argv[]) i->get_peer_info(peers); float down = s.download_rate; float up = s.upload_rate; - int total_down = s.total_download; - int total_up = s.total_upload; - int num_peers = peers.size(); + size_type total_down = s.total_download; + size_type total_up = s.total_upload; + int num_peers = (int)peers.size(); out.precision(4); out.width(5); diff --git a/include/libtorrent/alert.hpp b/include/libtorrent/alert.hpp index 5a265a081..3fec24a19 100755 --- a/include/libtorrent/alert.hpp +++ b/include/libtorrent/alert.hpp @@ -30,8 +30,8 @@ POSSIBILITY OF SUCH DAMAGE. */ -#ifndef TORRENT_ERROR_HPP_INCLUDED -#define TORRENT_ERROR_HPP_INCLUDED +#ifndef TORRENT_ALERT_HPP_INCLUDED +#define TORRENT_ALERT_HPP_INCLUDED #include #include @@ -39,6 +39,10 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + #include #include @@ -47,6 +51,11 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + namespace libtorrent { class alert @@ -158,5 +167,5 @@ namespace libtorrent { } // namespace libtorrent -#endif // TORRENT_ERROR_HPP_INCLUDED +#endif // TORRENT_ALERT_HPP_INCLUDED diff --git a/include/libtorrent/bencode.hpp b/include/libtorrent/bencode.hpp index 03b5afb73..0f1700d5b 100755 --- a/include/libtorrent/bencode.hpp +++ b/include/libtorrent/bencode.hpp @@ -64,8 +64,17 @@ POSSIBILITY OF SUCH DAMAGE. #include + +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #include "libtorrent/entry.hpp" #if defined(_MSC_VER) diff --git a/include/libtorrent/debug.hpp b/include/libtorrent/debug.hpp index 79c3b1c9a..11ef9192b 100755 --- a/include/libtorrent/debug.hpp +++ b/include/libtorrent/debug.hpp @@ -36,8 +36,16 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + namespace libtorrent { diff --git a/include/libtorrent/file.hpp b/include/libtorrent/file.hpp index 4fd823e6f..1953c97e9 100755 --- a/include/libtorrent/file.hpp +++ b/include/libtorrent/file.hpp @@ -36,9 +36,17 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + #include #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #include "libtorrent/size_type.hpp" namespace libtorrent diff --git a/include/libtorrent/invariant_check.hpp b/include/libtorrent/invariant_check.hpp new file mode 100755 index 000000000..2c119d7ca --- /dev/null +++ b/include/libtorrent/invariant_check.hpp @@ -0,0 +1,77 @@ +// Copyright Daniel Wallin 2004. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef TORRENT_INVARIANT_ACCESS_HPP_INCLUDED +#define TORRENT_INVARIANT_ACCESS_HPP_INCLUDED + +#include +#include + +namespace libtorrent +{ + + class invariant_access + { + public: + template + static void check_invariant(T const& self) + { + self.check_invariant(); + } + }; + + template + void check_invariant(T const& x) + { + invariant_access::check_invariant(x); + } + + struct invariant_checker {}; + + template + struct invariant_checker_impl : invariant_checker + { + invariant_checker_impl(T const& self_) + : self(self_) + { + try + { + check_invariant(self); + } + catch (...) + { + assert(false); + } + } + + ~invariant_checker_impl() + { + try + { + check_invariant(self); + } + catch (...) + { + assert(false); + } + } + + T const& self; + }; + + template + invariant_checker_impl make_invariant_checker(T const& x) + { + return invariant_checker_impl(x); + } +} + +#ifndef NDEBUG +#define INVARIANT_CHECK \ + invariant_checker const& _invariant_check = make_invariant_checker(*this) +#else +#define INVARIANT_CHECK do {} while (false) +#endif + +#endif // TORRENT_INVARIANT_ACCESS_HPP_INCLUDED diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index 0283e43a5..3bf7a6c9b 100755 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -39,6 +39,10 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + #include #include #include @@ -46,6 +50,10 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #include "libtorrent/socket.hpp" #include "libtorrent/peer_id.hpp" #include "libtorrent/storage.hpp" @@ -196,6 +204,7 @@ namespace libtorrent class peer_connection: public boost::noncopyable { + friend class invariant_access; public: // this is the constructor where the we are teh active part. The peer_conenction @@ -304,10 +313,10 @@ namespace libtorrent // quota is unlimited. int send_quota_left() const { return m_send_quota_left; } - int total_free_upload() const + size_type total_free_upload() const { return m_free_upload; } - void add_free_upload(int free_upload) + void add_free_upload(size_type free_upload) { m_free_upload += free_upload; } // returns the send quota assigned to this @@ -332,7 +341,7 @@ namespace libtorrent int send_quota_limit() const { return m_send_quota_limit; } - int share_diff() const; + size_type share_diff() const; bool support_extensions() const { return m_supports_extensions; } @@ -388,6 +397,8 @@ namespace libtorrent private: + void check_invariant() const; + bool dispatch_message(int received); void send_buffer_updated(); @@ -429,8 +440,8 @@ namespace libtorrent const static message_handler m_message_handler[num_supported_messages]; - std::size_t m_packet_size; - std::size_t m_recv_pos; + int m_packet_size; + int m_recv_pos; std::vector m_recv_buffer; // this is the buffer where data that is @@ -542,7 +553,7 @@ namespace libtorrent // this will be negative on a peer from which // we get free download, and positive on peers // that we give the free upload, to keep the balance. - int m_free_upload; + size_type m_free_upload; // this is used to limit upload bandwidth. // it is reset to the allowed number of diff --git a/include/libtorrent/peer_info.hpp b/include/libtorrent/peer_info.hpp index 2ee91732d..fa340a866 100755 --- a/include/libtorrent/peer_info.hpp +++ b/include/libtorrent/peer_info.hpp @@ -34,8 +34,10 @@ POSSIBILITY OF SUCH DAMAGE. #define TORRENT_PEER_INFO_HPP_INCLUDED #include + #include "libtorrent/socket.hpp" #include "libtorrent/peer_id.hpp" +#include "libtorrent/size_type.hpp" namespace libtorrent { @@ -54,14 +56,14 @@ namespace libtorrent address ip; float up_speed; float down_speed; - unsigned int total_download; - unsigned int total_upload; + size_type total_download; + size_type total_upload; peer_id id; std::vector pieces; int upload_limit; // from peer_connection int upload_ceiling; // from the global upload limiter - int load_balancing; + size_type load_balancing; // this is the number of requests // we have sent to this peer diff --git a/include/libtorrent/piece_picker.hpp b/include/libtorrent/piece_picker.hpp index e9a079208..a6526fb04 100755 --- a/include/libtorrent/piece_picker.hpp +++ b/include/libtorrent/piece_picker.hpp @@ -37,8 +37,16 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #include "libtorrent/peer_id.hpp" #include "libtorrent/socket.hpp" diff --git a/include/libtorrent/policy.hpp b/include/libtorrent/policy.hpp index d5786e7fe..1037070bd 100755 --- a/include/libtorrent/policy.hpp +++ b/include/libtorrent/policy.hpp @@ -36,8 +36,16 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #include "libtorrent/peer.hpp" #include "libtorrent/piece_picker.hpp" #include "libtorrent/socket.hpp" @@ -202,7 +210,7 @@ namespace libtorrent // free download we have got that hasn't // been distributed yet. - int m_available_free_upload; + size_type m_available_free_upload; // if there is a connection limit, // we disconnect one peer every minute in hope of diff --git a/include/libtorrent/session.hpp b/include/libtorrent/session.hpp index cb3466f02..a7406ef06 100755 --- a/include/libtorrent/session.hpp +++ b/include/libtorrent/session.hpp @@ -40,11 +40,19 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + #include #include #include #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #include "libtorrent/torrent_handle.hpp" #include "libtorrent/torrent.hpp" #include "libtorrent/entry.hpp" @@ -145,6 +153,7 @@ namespace libtorrent // thread started to run the main downloader loop struct session_impl: boost::noncopyable { + friend class invariant_access; typedef std::map, boost::shared_ptr > connection_map; session_impl(int listen_port, const fingerprint& cl_fprint); @@ -208,7 +217,7 @@ namespace libtorrent void purge_connections(); #ifndef NDEBUG - void assert_invariant(const char *place); + void check_invariant(const char *place = 0); boost::shared_ptr create_log(std::string name); boost::shared_ptr m_logger; #endif diff --git a/include/libtorrent/size_type.hpp b/include/libtorrent/size_type.hpp index 3050b46a3..f636475be 100755 --- a/include/libtorrent/size_type.hpp +++ b/include/libtorrent/size_type.hpp @@ -33,8 +33,16 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef TORRENT_SIZE_TYPE_HPP_INCLUDED #define TORRENT_SIZE_TYPE_HPP_INCLUDED +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + namespace libtorrent { #if defined(_MSC_VER) && _MSC_VER < 1300 diff --git a/include/libtorrent/socket.hpp b/include/libtorrent/socket.hpp index 4d1529634..c85f64724 100755 --- a/include/libtorrent/socket.hpp +++ b/include/libtorrent/socket.hpp @@ -33,10 +33,19 @@ POSSIBILITY OF SUCH DAMAGE. #ifndef TORRENT_SOCKET_HPP_INCLUDED #define TORRENT_SOCKET_HPP_INCLUDED -#include +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + +#include #include #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + #include #include #include diff --git a/include/libtorrent/stat.hpp b/include/libtorrent/stat.hpp index dbbb9e9ed..5852a20bc 100755 --- a/include/libtorrent/stat.hpp +++ b/include/libtorrent/stat.hpp @@ -38,12 +38,14 @@ POSSIBILITY OF SUCH DAMAGE. #include #include "libtorrent/size_type.hpp" +#include "libtorrent/invariant_check.hpp" namespace libtorrent { class stat { + friend class invariant_access; enum { history = 10 }; public: @@ -67,6 +69,8 @@ namespace libtorrent void operator+=(const stat& s) { + INVARIANT_CHECK; + m_downloaded_payload += s.m_downloaded_payload; m_total_download_payload += s.m_downloaded_payload; m_downloaded_protocol += s.m_downloaded_protocol; @@ -80,22 +84,26 @@ namespace libtorrent void received_bytes(int bytes_payload, int bytes_protocol) { + INVARIANT_CHECK; + assert(bytes_payload >= 0); assert(bytes_protocol >= 0); + m_downloaded_payload += bytes_payload; m_total_download_payload += bytes_payload; - m_downloaded_protocol += bytes_protocol; m_total_download_protocol += bytes_protocol; } void sent_bytes(int bytes_payload, int bytes_protocol) { + INVARIANT_CHECK; + assert(bytes_payload >= 0); assert(bytes_protocol >= 0); + m_uploaded_payload += bytes_payload; m_total_upload_payload += bytes_payload; - m_uploaded_protocol += bytes_protocol; m_total_upload_protocol += bytes_protocol; } @@ -119,7 +127,7 @@ namespace libtorrent private: #ifndef NDEBUG - void check_invariant() + void check_invariant() const { assert(m_mean_upload_per_second >= 0); assert(m_mean_download_per_second >= 0); @@ -159,12 +167,12 @@ namespace libtorrent size_type m_total_upload_protocol; // peak mean download/upload rates - int m_peak_downloaded_per_second; - int m_peak_uploaded_per_second; + float m_peak_downloaded_per_second; + float m_peak_uploaded_per_second; // current mean download/upload rates - int m_mean_download_per_second; - int m_mean_upload_per_second; + float m_mean_download_per_second; + float m_mean_upload_per_second; }; } diff --git a/include/libtorrent/storage.hpp b/include/libtorrent/storage.hpp index 2e8758159..166654b55 100755 --- a/include/libtorrent/storage.hpp +++ b/include/libtorrent/storage.hpp @@ -36,10 +36,19 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + #include #include #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + + #include "libtorrent/torrent_info.hpp" #include "libtorrent/opaque_value_ptr.hpp" @@ -78,11 +87,14 @@ namespace libtorrent void swap(storage&); - size_type read(char* buf, int slot, size_type offset, size_type size); - void write(const char* buf, int slot, size_type offset, size_type size); + // may throw file_error if storage for slot does not exist + size_type read(char* buf, int slot, int offset, int size); + + // may throw file_error if storage for slot hasn't been allocated + void write(const char* buf, int slot, int offset, int size); private: - struct impl; + class impl; opaque_value_ptr m_pimpl; }; @@ -110,8 +122,17 @@ namespace libtorrent , const std::bitset<256>& bitmask); int slot_for_piece(int piece_index) const; - size_type read(char* buf, int piece_index, size_type offset, size_type size); - void write(const char* buf, int piece_index, size_type offset, size_type size); + size_type read( + char* buf + , int piece_index + , int offset + , int size); + + void write( + const char* buf + , int piece_index + , int offset + , int size); const boost::filesystem::path& save_path() const; @@ -122,7 +143,7 @@ namespace libtorrent void export_piece_map(std::vector& pieces) const; private: - struct impl; + class impl; std::auto_ptr m_pimpl; }; diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index aa0fac812..e7e5014ef 100755 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -39,10 +39,18 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + #include #include #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #include "libtorrent/torrent_handle.hpp" #include "libtorrent/entry.hpp" #include "libtorrent/torrent_info.hpp" @@ -151,7 +159,7 @@ namespace libtorrent } // the number of peers that belong to this torrent - int num_peers() const { return m_connections.size(); } + int num_peers() const { return (int)m_connections.size(); } // returns true if this torrent has a connection // to a peer with the given peer_id diff --git a/include/libtorrent/torrent_handle.hpp b/include/libtorrent/torrent_handle.hpp index b30388980..8e754c8dd 100755 --- a/include/libtorrent/torrent_handle.hpp +++ b/include/libtorrent/torrent_handle.hpp @@ -34,8 +34,17 @@ POSSIBILITY OF SUCH DAMAGE. #define TORRENT_TORRENT_HANDLE_HPP_INCLUDED #include + +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #include "libtorrent/peer_id.hpp" #include "libtorrent/peer_info.hpp" #include "libtorrent/piece_picker.hpp" diff --git a/include/libtorrent/torrent_info.hpp b/include/libtorrent/torrent_info.hpp index eb7bc8f6f..327f54f19 100755 --- a/include/libtorrent/torrent_info.hpp +++ b/include/libtorrent/torrent_info.hpp @@ -36,8 +36,17 @@ POSSIBILITY OF SUCH DAMAGE. #include #include + +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #include "libtorrent/entry.hpp" #include "libtorrent/socket.hpp" #include "libtorrent/peer_id.hpp" @@ -106,7 +115,7 @@ namespace libtorrent reverse_file_iterator rbegin_files() const { return m_files.rbegin(); } reverse_file_iterator rend_files() const { return m_files.rend(); } - std::size_t num_files() const { return m_files.size(); } + int num_files() const { return (int)m_files.size(); } const file_entry& file_at(int index) const { assert(index >= 0 && index < (int)m_files.size()); return m_files[index]; } const std::vector& trackers() const { return m_urls; } @@ -116,8 +125,8 @@ namespace libtorrent // the begining) and return the new index to the tracker. int prioritize_tracker(int index); - size_type total_size() const { assert(m_total_size>=0); return m_total_size; } - size_type piece_length() const { assert(m_piece_length>0); return m_piece_length; } + size_type total_size() const { return m_total_size; } + int piece_length() const { return m_piece_length; } int num_pieces() const { return (int)m_piece_hash.size(); } const sha1_hash& info_hash() const { return m_info_hash; } const std::string& name() const { return m_name; } @@ -125,12 +134,13 @@ namespace libtorrent void convert_file_names(); - size_type piece_size(int index) const + int piece_size(int index) const { assert(index >= 0 && index < num_pieces()); if (index == num_pieces()-1) { - size_type s = total_size() - (size_type)(num_pieces() - 1)*piece_length(); + int s = static_cast(total_size() + - (size_type)(num_pieces() - 1) * piece_length()); assert(s > 0); assert(s <= piece_length()); return s; @@ -141,7 +151,8 @@ namespace libtorrent const sha1_hash& hash_for_piece(int index) const { - assert(index >= 0 && index < (int)m_piece_hash.size()); + assert(index >= 0); + assert(index < (int)m_piece_hash.size()); return m_piece_hash[index]; } @@ -159,7 +170,7 @@ namespace libtorrent std::vector m_urls; // the length of one piece - size_type m_piece_length; + int m_piece_length; // the sha-1 hashes of each piece std::vector m_piece_hash; diff --git a/src/identify_client.cpp b/src/identify_client.cpp index 113979c4e..9f79c9468 100755 --- a/src/identify_client.cpp +++ b/src/identify_client.cpp @@ -30,9 +30,18 @@ POSSIBILITY OF SUCH DAMAGE. */ -#include #include +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + +#include + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #include "libtorrent/identify_client.hpp" #include "libtorrent/fingerprint.hpp" diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 9bd7cf7e8..29528148e 100755 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/entry.hpp" #include "libtorrent/bencode.hpp" #include "libtorrent/alert_types.hpp" +#include "libtorrent/invariant_check.hpp" #if defined(_MSC_VER) #define for if (false) {} else for @@ -82,8 +83,8 @@ namespace libtorrent , m_timeout(120) , m_packet_size(1) , m_recv_pos(0) - , m_last_receive(boost::gregorian::date(std::time(0))) - , m_last_sent(boost::gregorian::date(std::time(0))) + , m_last_receive(boost::posix_time::second_clock::local_time()) + , m_last_sent(boost::posix_time::second_clock::local_time()) , m_selector(sel) , m_socket(s) , m_torrent(t) @@ -102,10 +103,12 @@ namespace libtorrent , m_send_quota_limit(100) , m_trust_points(0) , m_num_invalid_requests(0) - , m_last_piece(boost::gregorian::date(std::time(0))) + , m_last_piece(boost::posix_time::second_clock::local_time()) , m_last_piece_time(boost::posix_time::seconds(0)) , m_disconnecting(false) { + INVARIANT_CHECK; + assert(!m_socket->is_blocking()); assert(m_torrent != 0); @@ -141,8 +144,8 @@ namespace libtorrent , m_timeout(120) , m_packet_size(1) , m_recv_pos(0) - , m_last_receive(boost::gregorian::date(std::time(0))) - , m_last_sent(boost::gregorian::date(std::time(0))) + , m_last_receive(boost::posix_time::second_clock::local_time()) + , m_last_sent(boost::posix_time::second_clock::local_time()) , m_selector(sel) , m_socket(s) , m_torrent(0) @@ -162,10 +165,12 @@ namespace libtorrent , m_send_quota_limit(100) , m_trust_points(0) , m_num_invalid_requests(0) - , m_last_piece(boost::gregorian::date(std::time(0))) + , m_last_piece(boost::posix_time::second_clock::local_time()) , m_last_piece_time(boost::posix_time::seconds(0)) , m_disconnecting(false) { + INVARIANT_CHECK; + assert(!m_socket->is_blocking()); std::fill(m_peer_id.begin(), m_peer_id.end(), 0); @@ -200,6 +205,8 @@ namespace libtorrent void peer_connection::set_send_quota(int num_bytes) { + INVARIANT_CHECK; + assert(num_bytes <= m_send_quota_limit || m_send_quota_limit == -1); if (num_bytes > m_send_quota_limit && m_send_quota_limit!=-1) num_bytes = m_send_quota_limit; @@ -210,6 +217,8 @@ namespace libtorrent void peer_connection::send_handshake() { + INVARIANT_CHECK; + assert(m_send_buffer.size() == 0); // add handshake to the send buffer @@ -312,6 +321,8 @@ namespace libtorrent void peer_connection::on_choke(int received) { + INVARIANT_CHECK; + if (m_packet_size != 1) throw protocol_error("'choke' message size != 1"); m_statistics.received_bytes(0, received); @@ -343,6 +354,8 @@ namespace libtorrent void peer_connection::on_unchoke(int received) { + INVARIANT_CHECK; + if (m_packet_size != 1) throw protocol_error("'unchoke' message size != 1"); m_statistics.received_bytes(0, received); @@ -361,6 +374,8 @@ namespace libtorrent void peer_connection::on_interested(int received) { + INVARIANT_CHECK; + if (m_packet_size != 1) throw protocol_error("'interested' message size != 1"); m_statistics.received_bytes(0, received); @@ -379,6 +394,8 @@ namespace libtorrent void peer_connection::on_not_interested(int received) { + INVARIANT_CHECK; + if (m_packet_size != 1) throw protocol_error("'not interested' message size != 1"); m_statistics.received_bytes(0, received); @@ -400,6 +417,8 @@ namespace libtorrent void peer_connection::on_have(int received) { + INVARIANT_CHECK; + if (m_packet_size != 5) throw protocol_error("'have' message size != 5"); m_statistics.received_bytes(0, received); @@ -408,7 +427,7 @@ namespace libtorrent const char* ptr = &m_recv_buffer[1]; int index = detail::read_int32(ptr); // if we got an invalid message, abort - if (index >= m_have_piece.size() || index < 0) + if (index >= (int)m_have_piece.size() || index < 0) throw protocol_error("have message with higher index than the number of pieces"); #ifndef NDEBUG @@ -442,6 +461,8 @@ namespace libtorrent void peer_connection::on_bitfield(int received) { + INVARIANT_CHECK; + if (m_packet_size - 1 != (m_have_piece.size() + 7) / 8) throw protocol_error("bitfield with invalid size"); m_statistics.received_bytes(0, received); @@ -452,9 +473,9 @@ namespace libtorrent #endif // build a vector of all pieces std::vector piece_list; - for (std::size_t i = 0; i < m_have_piece.size(); ++i) + for (int i = 0; i < (int)m_have_piece.size(); ++i) { - bool have = m_recv_buffer[1 + (i>>3)] & (1 << (7 - (i&7))); + bool have = (m_recv_buffer[1 + (i>>3)] & (1 << (7 - (i&7)))) != 0; if (have && !m_have_piece[i]) { m_have_piece[i] = true; @@ -507,6 +528,8 @@ namespace libtorrent void peer_connection::on_request(int received) { + INVARIANT_CHECK; + if (m_packet_size != 13) throw protocol_error("'request' message size != 13"); m_statistics.received_bytes(0, received); @@ -572,6 +595,8 @@ namespace libtorrent void peer_connection::on_piece(int received) { + INVARIANT_CHECK; + if (m_recv_pos - received <= 9) { m_last_piece = boost::posix_time::second_clock::local_time(); @@ -717,6 +742,8 @@ namespace libtorrent void peer_connection::on_cancel(int received) { + INVARIANT_CHECK; + if (m_packet_size != 13) throw protocol_error("'cancel' message size != 13"); m_statistics.received_bytes(0, received); @@ -752,6 +779,8 @@ namespace libtorrent void peer_connection::on_extension_list(int received) { + INVARIANT_CHECK; + if (m_packet_size > 100 * 1024) { // too big extension message, abort @@ -771,7 +800,7 @@ namespace libtorrent extensions.find(extension_names[i]); if (f != extensions.end()) { - m_extension_messages[i] = f->second.integer(); + m_extension_messages[i] = (int)f->second.integer(); } } #ifndef NDEBUG @@ -784,11 +813,11 @@ namespace libtorrent } #endif } - catch(invalid_encoding& e) + catch(invalid_encoding&) { throw protocol_error("'extensions' packet contains invalid bencoding"); } - catch(type_error& e) + catch(type_error&) { throw protocol_error("'extensions' packet contains incorrect types"); } @@ -800,6 +829,8 @@ namespace libtorrent void peer_connection::on_extended(int received) { + INVARIANT_CHECK; + m_statistics.received_bytes(0, received); if (m_packet_size < 5) throw protocol_error("'extended' message smaller than 5 bytes"); @@ -837,11 +868,11 @@ namespace libtorrent } } - catch (invalid_encoding& e) + catch (invalid_encoding&) { throw protocol_error("invalid bencoding in CHAT message"); } - catch (type_error& e) + catch (type_error&) { throw protocol_error("invalid types in bencoded CHAT message"); } @@ -873,6 +904,8 @@ namespace libtorrent bool peer_connection::dispatch_message(int received) { + INVARIANT_CHECK; + assert(m_recv_pos >= received); assert(m_recv_pos > 0); assert(m_torrent); @@ -898,6 +931,8 @@ namespace libtorrent void peer_connection::send_cancel(piece_block block) { + INVARIANT_CHECK; + assert(block.piece_index >= 0); assert(block.piece_index < m_torrent->torrent_file().num_pieces()); assert(m_torrent->picker().is_downloading(block)); @@ -944,6 +979,8 @@ namespace libtorrent void peer_connection::send_request(piece_block block) { + INVARIANT_CHECK; + assert(block.piece_index >= 0); assert(block.piece_index < m_torrent->torrent_file().num_pieces()); assert(!m_torrent->picker().is_downloading(block)); @@ -995,6 +1032,8 @@ namespace libtorrent void peer_connection::send_chat_message(const std::string& msg) { + INVARIANT_CHECK; + assert(msg.length() <= 1 * 1024); if (m_extension_messages[extended_chat_message] == -1) return; @@ -1005,7 +1044,7 @@ namespace libtorrent bencode(std::back_inserter(message), e); std::back_insert_iterator > ptr(m_send_buffer); - detail::write_uint32(1 + 4 + message.size(), ptr); + detail::write_uint32(1 + 4 + (int)message.size(), ptr); detail::write_uint8(msg_extended, ptr); detail::write_int32(m_extension_messages[extended_chat_message], ptr); std::copy(message.begin(), message.end(), ptr); @@ -1014,17 +1053,21 @@ namespace libtorrent void peer_connection::send_bitfield() { + INVARIANT_CHECK; + #ifndef NDEBUG (*m_logger) << " ==> BITFIELD\n"; #endif - const int packet_size = (m_have_piece.size() + 7) / 8 + 5; - const int old_size = m_send_buffer.size(); + const int packet_size = ((int)m_have_piece.size() + 7) / 8 + 5; + const int old_size = (int)m_send_buffer.size(); m_send_buffer.resize(old_size + packet_size); + char* ptr = &m_send_buffer[old_size]; detail::write_int32(packet_size - 4, ptr); - m_send_buffer[old_size+4] = msg_bitfield; - std::fill(m_send_buffer.begin()+old_size+5, m_send_buffer.end(), 0); - for (std::size_t i = 0; i < m_have_piece.size(); ++i) + detail::write_uint8(msg_bitfield, ptr); + + std::fill(m_send_buffer.begin() + old_size + 5, m_send_buffer.end(), 0); + for (int i = 0; i < (int)m_have_piece.size(); ++i) { if (m_torrent->have_piece(i)) m_send_buffer[old_size + 5 + (i>>3)] |= 1 << (7 - (i&7)); @@ -1034,6 +1077,8 @@ namespace libtorrent void peer_connection::send_extensions() { + INVARIANT_CHECK; + #ifndef NDEBUG (*m_logger) << " ==> EXTENSIONS\n"; #endif @@ -1047,7 +1092,7 @@ namespace libtorrent } // make room for message size - const int msg_size_pos = m_send_buffer.size(); + const int msg_size_pos = (int)m_send_buffer.size(); m_send_buffer.resize(msg_size_pos + 4); m_send_buffer.push_back(msg_extension_list); @@ -1056,13 +1101,15 @@ namespace libtorrent // write the length of the message char* ptr = &m_send_buffer[msg_size_pos]; - detail::write_int32(m_send_buffer.size() - msg_size_pos - 4, ptr); + detail::write_int32((int)m_send_buffer.size() - msg_size_pos - 4, ptr); send_buffer_updated(); } void peer_connection::send_choke() { + INVARIANT_CHECK; + if (m_choked) return; char msg[] = {0,0,0,1,msg_choke}; m_send_buffer.insert(m_send_buffer.end(), msg, msg+sizeof(msg)); @@ -1077,6 +1124,8 @@ namespace libtorrent void peer_connection::send_unchoke() { + INVARIANT_CHECK; + if (!m_choked) return; char msg[] = {0,0,0,1,msg_unchoke}; m_send_buffer.insert(m_send_buffer.end(), msg, msg+sizeof(msg)); @@ -1089,6 +1138,8 @@ namespace libtorrent void peer_connection::send_interested() { + INVARIANT_CHECK; + if (m_interesting) return; char msg[] = {0,0,0,1,msg_interested}; m_send_buffer.insert(m_send_buffer.end(), msg, msg+sizeof(msg)); @@ -1101,6 +1152,8 @@ namespace libtorrent void peer_connection::send_not_interested() { + INVARIANT_CHECK; + if (!m_interesting) return; char msg[] = {0,0,0,1,msg_not_interested}; m_send_buffer.insert(m_send_buffer.end(), msg, msg+sizeof(msg)); @@ -1113,6 +1166,8 @@ namespace libtorrent void peer_connection::send_have(int index) { + INVARIANT_CHECK; + // optimization, don't send have messages // to peers that already have the piece if (m_have_piece[index]) return; @@ -1128,7 +1183,7 @@ namespace libtorrent send_buffer_updated(); } - int peer_connection::share_diff() const + size_type peer_connection::share_diff() const { float ratio = m_torrent->ratio(); @@ -1137,12 +1192,14 @@ namespace libtorrent if (ratio == 0.f) return std::numeric_limits::max(); return m_free_upload - + static_cast(m_statistics.total_payload_download() * ratio) + + static_cast(m_statistics.total_payload_download() * ratio) - m_statistics.total_payload_upload(); } void peer_connection::second_tick() { + INVARIANT_CHECK; + m_statistics.second_tick(); m_send_quota_left = m_send_quota; if (m_send_quota > 0) send_buffer_updated(); @@ -1154,7 +1211,7 @@ namespace libtorrent // maintain the share ratio given by m_ratio // with all peers. - int diff = share_diff(); + size_type diff = share_diff(); enum { block_limit=2 }; // how many blocks difference is considered unfair @@ -1200,6 +1257,8 @@ namespace libtorrent // throws exception when the client should be disconnected void peer_connection::receive_data() { + INVARIANT_CHECK; + assert(!m_socket->is_blocking()); assert(m_packet_size > 0); assert(m_socket->is_readable()); @@ -1466,6 +1525,8 @@ namespace libtorrent // throws exception when the client should be disconnected void peer_connection::send_data() { + INVARIANT_CHECK; + assert(m_socket->is_writable()); assert(has_data()); @@ -1475,19 +1536,22 @@ namespace libtorrent // requested block. Have a limit of how much of the requested // block is actually read at a time. while (!m_requests.empty() - && (m_send_buffer.size() < m_torrent->block_size()) + && ((int)m_send_buffer.size() < m_torrent->block_size()) && !m_choked) { peer_request& r = m_requests.front(); - assert(r.piece >= 0 && r.piece < m_have_piece.size() && m_torrent && m_torrent->have_piece(r.piece)); + assert(r.piece >= 0); + assert(r.piece < (int)m_have_piece.size()); + assert(m_torrent != 0); + assert(m_torrent->have_piece(r.piece)); assert(r.start + r.length <= m_torrent->torrent_file().piece_size(r.piece)); assert(r.length > 0 && r.start >= 0); #ifndef NDEBUG // assert(m_torrent->verify_piece(r.piece) && "internal error"); #endif - const int send_buffer_offset = m_send_buffer.size(); + const int send_buffer_offset = (int)m_send_buffer.size(); const int packet_size = 4 + 5 + 4 + r.length; m_send_buffer.resize(send_buffer_offset + packet_size); char* ptr = &m_send_buffer[send_buffer_offset]; @@ -1539,7 +1603,7 @@ namespace libtorrent if (!m_send_buffer.empty()) { - int amount_to_send = m_send_buffer.size(); + int amount_to_send = (int)m_send_buffer.size(); assert(m_send_quota_left != 0); if (m_send_quota_left > 0) amount_to_send = std::min(m_send_quota_left, amount_to_send); @@ -1615,22 +1679,19 @@ namespace libtorrent assert(m_added_to_selector); send_buffer_updated(); -/* - #ifndef NDEBUG - if (has_data()) - { - if (m_socket->is_writable()) - { - std::cout << "ERROR, not good\n"; - } - } - #endif -*/ } +#ifndef NDEBUG + void peer_connection::check_invariant() const + { + assert(has_data() == m_selector.is_writability_monitored(m_socket)); + } +#endif void peer_connection::keep_alive() { + INVARIANT_CHECK; + boost::posix_time::time_duration d; d = boost::posix_time::second_clock::local_time() - m_last_sent; if (d.seconds() < m_timeout / 2) return; diff --git a/src/piece_picker.cpp b/src/piece_picker.cpp index f1a4174c1..6cace6408 100755 --- a/src/piece_picker.cpp +++ b/src/piece_picker.cpp @@ -87,7 +87,7 @@ namespace libtorrent ++i) { if (*i) continue; - int index = i - pieces.begin(); + int index = static_cast(i - pieces.begin()); piece_list.push_back(index); } @@ -100,14 +100,14 @@ namespace libtorrent ++i) { int index = *i; - assert(index < m_piece_map.size()); + assert(index < (int)m_piece_map.size()); assert(m_piece_map[index].index == 0xffffff); int peer_count = m_piece_map[index].peer_count; assert(peer_count == 0); assert(m_piece_info.size() == 2); - m_piece_map[index].index = m_piece_info[peer_count].size(); + m_piece_map[index].index = (int)m_piece_info[peer_count].size(); m_piece_info[peer_count].push_back(index); } @@ -147,7 +147,7 @@ namespace libtorrent i != m_piece_map.end(); ++i) { - int index = i - m_piece_map.begin(); + int index = static_cast(i - m_piece_map.begin()); if (t != 0) { @@ -249,8 +249,8 @@ namespace libtorrent { std::vector >& src_vec = (downloading)?m_downloading_piece_info:m_piece_info; - assert(src_vec.size() > peer_count); - assert(src_vec[peer_count].size() > elem_index); + assert((int)src_vec.size() > peer_count); + assert((int)src_vec[peer_count].size() > elem_index); int index = src_vec[peer_count][elem_index]; // update the piece_map @@ -266,7 +266,7 @@ namespace libtorrent assert(dst_vec.size() > p.peer_count); } - p.index = dst_vec[p.peer_count].size(); + p.index = (int)dst_vec[p.peer_count].size(); dst_vec[p.peer_count].push_back(index); assert(p.index < dst_vec[p.peer_count].size()); assert(dst_vec[p.peer_count][p.index] == index); @@ -279,7 +279,7 @@ namespace libtorrent // update the entry we moved from the back m_piece_map[replace_index].index = elem_index; - assert(src_vec[peer_count].size() > elem_index); + assert((int)src_vec[peer_count].size() > elem_index); assert(m_piece_map[replace_index].peer_count == peer_count); assert(m_piece_map[replace_index].index == elem_index); assert(src_vec[peer_count][elem_index] == replace_index); @@ -297,8 +297,8 @@ namespace libtorrent { std::vector >& src_vec = (downloading)?m_downloading_piece_info:m_piece_info; - assert(src_vec.size() > peer_count); - assert(src_vec[peer_count].size() > elem_index); + assert((int)src_vec.size() > peer_count); + assert((int)src_vec[peer_count].size() > elem_index); int index = src_vec[peer_count][elem_index]; m_piece_map[index].index = 0xffffff; @@ -318,7 +318,7 @@ namespace libtorrent // preserving order index = src_vec[peer_count][elem_index] = src_vec[peer_count].back(); // update the entry we moved from the back - if (src_vec[peer_count].size() > elem_index+1) + if ((int)src_vec[peer_count].size() > elem_index+1) m_piece_map[index].index = elem_index; src_vec[peer_count].pop_back(); @@ -327,7 +327,7 @@ namespace libtorrent void piece_picker::restore_piece(int index) { assert(index >= 0); - assert(index < m_piece_map.size()); + assert(index < (int)m_piece_map.size()); assert(m_piece_map[index].downloading == 1); @@ -349,7 +349,7 @@ namespace libtorrent void piece_picker::inc_refcount(int i) { assert(i >= 0); - assert(i < m_piece_map.size()); + assert(i < (int)m_piece_map.size()); int peer_count = m_piece_map[i].peer_count; int index = m_piece_map[i].index; @@ -371,7 +371,7 @@ namespace libtorrent void piece_picker::dec_refcount(int i) { assert(i >= 0); - assert(i < m_piece_map.size()); + assert(i < (int)m_piece_map.size()); int peer_count = m_piece_map[i].peer_count; int index = m_piece_map[i].index; @@ -385,7 +385,7 @@ namespace libtorrent void piece_picker::we_have(int index) { - assert(index < m_piece_map.size()); + assert(index < (int)m_piece_map.size()); int info_index = m_piece_map[index].index; int peer_count = m_piece_map[index].peer_count; @@ -448,7 +448,7 @@ namespace libtorrent i != piece_list.end(); ++i) { - assert(*i < m_piece_map.size()); + assert(*i < (int)m_piece_map.size()); // if the peer doesn't have the piece // skip it if (!pieces[*i]) continue; @@ -496,14 +496,14 @@ namespace libtorrent bool piece_picker::is_piece_finished(int index) const { - assert(index < m_piece_map.size()); + assert(index < (int)m_piece_map.size()); assert(index >= 0); if (m_piece_map[index].downloading == 0) return false; std::vector::const_iterator i = std::find_if(m_downloads.begin(), m_downloads.end(), has_index(index)); assert(i != m_downloads.end()); - assert(i->finished_blocks.count() <= m_blocks_per_piece); + assert((int)i->finished_blocks.count() <= m_blocks_per_piece); int max_blocks = blocks_in_piece(index); if (i->finished_blocks.count() != max_blocks) return false; @@ -513,7 +513,7 @@ namespace libtorrent bool piece_picker::is_downloading(piece_block block) const { - assert(block.piece_index < m_piece_map.size()); + assert(block.piece_index < (int)m_piece_map.size()); assert(block.block_index < max_blocks_per_piece); if (m_piece_map[block.piece_index].downloading == 0) return false; @@ -529,7 +529,7 @@ namespace libtorrent bool piece_picker::is_finished(piece_block block) const { - assert(block.piece_index < m_piece_map.size()); + assert(block.piece_index < (int)m_piece_map.size()); assert(block.block_index < max_blocks_per_piece); if (m_piece_map[block.piece_index].index == 0xffffff) return true; @@ -546,7 +546,7 @@ namespace libtorrent #ifndef NDEBUG // integrity_check(); #endif - assert(block.piece_index < m_piece_map.size()); + assert(block.piece_index < (int)m_piece_map.size()); assert(block.block_index < blocks_in_piece(block.piece_index)); piece_pos& p = m_piece_map[block.piece_index]; @@ -580,7 +580,7 @@ namespace libtorrent #ifndef NDEBUG // integrity_check(); #endif - assert(block.piece_index < m_piece_map.size()); + assert(block.piece_index < (int)m_piece_map.size()); assert(block.block_index < blocks_in_piece(block.piece_index)); piece_pos& p = m_piece_map[block.piece_index]; @@ -675,7 +675,7 @@ namespace libtorrent // integrity_check(); #endif - assert(block.piece_index < m_piece_map.size()); + assert(block.piece_index < (int)m_piece_map.size()); assert(block.block_index < max_blocks_per_piece); if (m_piece_map[block.piece_index].downloading == 0) @@ -716,7 +716,7 @@ namespace libtorrent i != m_downloads.end(); ++i) { - counter += i->finished_blocks.count(); + counter += (int)i->finished_blocks.count(); } return counter; } diff --git a/src/policy.cpp b/src/policy.cpp index c4ff608e9..622bf6714 100755 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -32,8 +32,16 @@ POSSIBILITY OF SUCH DAMAGE. #include +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #include "libtorrent/policy.hpp" #include "libtorrent/torrent.hpp" #include "libtorrent/socket.hpp" @@ -99,7 +107,7 @@ namespace assert(desired_queue_size >= min_request_queue); - int num_requests = desired_queue_size - c.download_queue().size(); + int num_requests = desired_queue_size - (int)c.download_queue().size(); // if our request queue is already full, we // don't have to make any new requests yet @@ -187,18 +195,18 @@ namespace } - int collect_free_download( + size_type collect_free_download( torrent::peer_iterator start , torrent::peer_iterator end) { - int accumulator = 0; + size_type accumulator = 0; for (torrent::peer_iterator i = start; i != end; ++i) { // if the peer is interested in us, it means it may // want to trade it's surplus uploads for downloads itself // (and we should consider it free). If the share diff is // negative, there's no free download to get from this peer. - int diff = i->second->share_diff(); + size_type diff = i->second->share_diff(); if (i->second->is_peer_interested() || diff <= 0) continue; @@ -214,14 +222,14 @@ namespace // returns the amount of free upload left after // it has been distributed to the peers - int distribute_free_upload( + size_type distribute_free_upload( torrent::peer_iterator start , torrent::peer_iterator end - , int free_upload) + , size_type free_upload) { if (free_upload <= 0) return free_upload; int num_peers = 0; - int total_diff = 0; + size_type total_diff = 0; for (torrent::peer_iterator i = start; i != end; ++i) { total_diff += i->second->share_diff(); @@ -230,7 +238,7 @@ namespace } if (num_peers == 0) return free_upload; - int upload_share; + size_type upload_share; if (total_diff >= 0) { upload_share = std::min(free_upload, total_diff) / num_peers; @@ -295,7 +303,7 @@ namespace libtorrent policy::peer* policy::find_choke_candidate() { peer* worst_peer = 0; - int min_weight = std::numeric_limits::max(); + size_type min_weight = std::numeric_limits::max(); // TODO: make this selection better @@ -311,10 +319,10 @@ namespace libtorrent if (!c->is_peer_interested()) return &(*i); - int diff = i->total_download() + size_type diff = i->total_download() - i->total_upload(); - int weight = static_cast(c->statistics().download_rate() * 10.f) + size_type weight = static_cast(c->statistics().download_rate() * 10.f) + diff + (c->has_peer_choked()?-10:10)*1024; @@ -367,11 +375,10 @@ namespace libtorrent policy::peer* policy::find_disconnect_candidate() { peer *disconnect_peer = 0; - double slowest_transfer_rate=std::numeric_limits::max(); + double slowest_transfer_rate = std::numeric_limits::max(); - bool is_seed=m_torrent->is_seed(); - - boost::posix_time::ptime local_time=boost::posix_time::second_clock::local_time(); + boost::posix_time::ptime local_time + = boost::posix_time::second_clock::local_time(); for (std::vector::iterator i = m_peers.begin(); i != m_peers.end(); @@ -383,24 +390,24 @@ namespace libtorrent if(c->is_disconnecting()) continue; - double transferred_amount; + double transferred_amount + = (double)c->statistics().total_payload_download(); - if(is_seed) - transferred_amount=c->statistics().total_payload_download(); - else - transferred_amount=c->statistics().total_payload_download(); + boost::posix_time::time_duration connected_time + = local_time - i->connected; - boost::posix_time::time_duration connected_time = local_time - i->connected; + double connected_time_in_seconds + = connected_time.seconds() + + connected_time.minutes()*60.0 + + connected_time.hours()*60.0*60.0; - - double connected_time_in_seconds=connected_time.seconds() + connected_time.minutes()*60.0 + connected_time.hours()*60.0*60.0; - - double transfer_rate=transferred_amount/(connected_time_in_seconds+1); + double transfer_rate + = transferred_amount / (connected_time_in_seconds+1); if (transfer_rate <= slowest_transfer_rate) { - slowest_transfer_rate=transfer_rate; - disconnect_peer=&*i; + slowest_transfer_rate = transfer_rate; + disconnect_peer = &(*i); } } return disconnect_peer; @@ -410,7 +417,7 @@ namespace libtorrent { boost::posix_time::ptime local_time=boost::posix_time::second_clock::local_time(); boost::posix_time::ptime ptime(local_time); - policy::peer *candidate=0; + policy::peer* candidate =0; for (std::vector::iterator i = m_peers.begin(); i != m_peers.end(); @@ -422,12 +429,13 @@ namespace libtorrent assert(i->connected <= local_time); - boost::posix_time::ptime next_connect=i->connected + boost::posix_time::seconds(10*60); + boost::posix_time::ptime next_connect + = i->connected + boost::posix_time::seconds(10 * 60); if (next_connect <= ptime) { - ptime=next_connect; - candidate=&*i; + ptime = next_connect; + candidate = &(*i); } } @@ -557,7 +565,7 @@ namespace libtorrent peer_connection* c = i->connection; if (c == 0) continue; - int diff = i->connection->share_diff(); + size_type diff = i->connection->share_diff(); if (diff < -free_upload_amount && !c->is_choked()) { @@ -796,7 +804,7 @@ namespace libtorrent if (m_torrent->ratio() != 0.f) { assert(c.share_diff() < std::numeric_limits::max()); - int diff = c.share_diff(); + size_type diff = c.share_diff(); if (diff > 0 && c.is_seed()) { // the peer is a seed and has sent diff --git a/src/session.cpp b/src/session.cpp index a92d7f12e..8ee64cace 100755 --- a/src/session.cpp +++ b/src/session.cpp @@ -40,12 +40,20 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + #include #include #include #include #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #include "libtorrent/peer_id.hpp" #include "libtorrent/torrent_info.hpp" #include "libtorrent/url_handler.hpp" @@ -56,6 +64,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/fingerprint.hpp" #include "libtorrent/entry.hpp" #include "libtorrent/alert_types.hpp" +#include "libtorrent/invariant_check.hpp" #if defined(_MSC_VER) && _MSC_VER < 1300 namespace std @@ -208,7 +217,7 @@ namespace // Rounds upwards to avoid trying to give 0 bandwidth to someone // (may get caught in an endless loop otherwise) - int num_peers_left_to_share_quota = peer_info.size() - i; + int num_peers_left_to_share_quota = (int)peer_info.size() - i; int try_to_give_to_this_peer = (quota_left_to_distribute + num_peers_left_to_share_quota - 1) / num_peers_left_to_share_quota; @@ -359,7 +368,7 @@ namespace libtorrent // ---- generate a peer id ---- - std::srand(std::time(0)); + std::srand((unsigned int)std::time(0)); std::string print = cl_fprint.to_string(); assert(print.length() == 8); @@ -438,7 +447,7 @@ namespace libtorrent { #ifndef NDEBUG - assert_invariant("loops_per_second++"); + check_invariant("loops_per_second++"); loops_per_second++; #endif @@ -479,7 +488,7 @@ namespace libtorrent } #ifndef NDEBUG - assert_invariant("before SEND SOCKETS"); + check_invariant("before SEND SOCKETS"); #endif // ************************ @@ -527,7 +536,7 @@ namespace libtorrent purge_connections(); #ifndef NDEBUG - assert_invariant("after SEND SOCKETS"); + check_invariant("after SEND SOCKETS"); #endif // ************************ // RECEIVE SOCKETS @@ -591,7 +600,7 @@ namespace libtorrent } purge_connections(); #ifndef NDEBUG - assert_invariant("after RECEIVE SOCKETS"); + check_invariant("after RECEIVE SOCKETS"); #endif // ************************ @@ -623,7 +632,7 @@ namespace libtorrent } #ifndef NDEBUG - assert_invariant("after ERROR SOCKETS"); + check_invariant("after ERROR SOCKETS"); #endif boost::posix_time::time_duration d = boost::posix_time::second_clock::local_time() - timer; @@ -751,7 +760,7 @@ namespace libtorrent #endif #ifndef NDEBUG - void session_impl::assert_invariant(const char *place) + void session_impl::check_invariant(const char *place) { assert(place); @@ -763,7 +772,7 @@ namespace libtorrent { std::ofstream error_log("error.log", std::ios_base::app); boost::shared_ptr p = i->second; - error_log << "session_imple::assert_invariant()\n" + error_log << "session_imple::check_invariant()\n" "peer_connection::has_data() != is_writability_monitored()\n"; error_log << "peer_connection::has_data() " << p->has_data() << "\n"; error_log << "peer_connection::send_quota_left " << p->send_quota_left() << "\n"; @@ -982,7 +991,9 @@ namespace libtorrent i != peer_list.end(); ++i) { - address a(i->dict()["ip"].string(), i->dict()["port"].integer()); + address a( + i->dict()["ip"].string() + , (unsigned short)i->dict()["port"].integer()); tmp_peers.push_back(a); } @@ -1001,14 +1012,14 @@ namespace libtorrent i != slots.end(); ++i) { - int index = i->integer(); + int index = (int)i->integer(); if (index >= info.num_pieces() || index < -2) return; tmp_pieces.push_back(index); } - int num_blocks_per_piece = rd.dict()["blocks per piece"].integer(); + int num_blocks_per_piece = (int)rd.dict()["blocks per piece"].integer(); if (num_blocks_per_piece != info.piece_length() / torrent_ptr->block_size()) return; @@ -1024,7 +1035,7 @@ namespace libtorrent { piece_picker::downloading_piece p; - p.index = i->dict()["piece"].integer(); + p.index = (int)i->dict()["piece"].integer(); if (p.index < 0 || p.index >= info.num_pieces()) return; @@ -1055,7 +1066,7 @@ namespace libtorrent } assert(*slot_iter == p.index); - int slot_index = slot_iter - tmp_pieces.begin(); + int slot_index = static_cast(slot_iter - tmp_pieces.begin()); unsigned long adler = torrent_ptr->filesystem().piece_crc( slot_index diff --git a/src/stat.cpp b/src/stat.cpp index 1bb06b098..d3b4c19b3 100755 --- a/src/stat.cpp +++ b/src/stat.cpp @@ -38,11 +38,14 @@ POSSIBILITY OF SUCH DAMAGE. #include #include "libtorrent/stat.hpp" +#include "libtorrent/invariant_check.hpp" using namespace libtorrent; void libtorrent::stat::second_tick() { + INVARIANT_CHECK; + std::copy(m_download_per_second_history, m_download_per_second_history+history-1, m_download_per_second_history+1); @@ -59,11 +62,11 @@ void libtorrent::stat::second_tick() m_uploaded_protocol = 0; m_mean_download_per_second - = std::accumulate(m_download_per_second_history, + = (float)std::accumulate(m_download_per_second_history, m_download_per_second_history+history, 0) / history; m_mean_upload_per_second - = std::accumulate(m_upload_per_second_history, + = (float)std::accumulate(m_upload_per_second_history, m_upload_per_second_history+history, 0) / history; if (m_mean_download_per_second > m_peak_downloaded_per_second) diff --git a/src/storage.cpp b/src/storage.cpp index 5582983cc..a7cfa3e3e 100755 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -38,25 +38,35 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + #include #include #include #include #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #include "libtorrent/storage.hpp" #include "libtorrent/torrent.hpp" #include "libtorrent/hasher.hpp" #include "libtorrent/session.hpp" #include "libtorrent/peer_id.hpp" #include "libtorrent/file.hpp" +#include "libtorrent/invariant_check.hpp" #if defined(_MSC_VER) #define for if (false) {} else for #endif -namespace { - +/* +namespace +{ struct lazy_hash { mutable libtorrent::sha1_hash digest; @@ -85,10 +95,12 @@ namespace { }; } // namespace unnamed +*/ namespace fs = boost::filesystem; -namespace { +namespace +{ void print_to_log(const std::string& s) { @@ -190,8 +202,9 @@ namespace libtorrent int slot; }; - struct storage::impl : thread_safe_storage + class storage::impl : public thread_safe_storage { + public: impl(const torrent_info& info, const fs::path& path) : thread_safe_storage(info.num_pieces()) , info(info) @@ -222,10 +235,10 @@ namespace libtorrent size_type storage::read( char* buf , int slot - , size_type offset - , size_type size) + , int offset + , int size) { - assert(buf); + assert(buf != 0); assert(slot >= 0 && slot < m_pimpl->info.num_pieces()); assert(offset >= 0); assert(offset < m_pimpl->info.piece_size(slot)); @@ -247,51 +260,53 @@ namespace libtorrent file_offset -= file_iter->size; ++file_iter; } -/* - fs::ifstream in( - m_pimpl->save_path / file_iter->path / file_iter->filename - , std::ios_base::binary - ); -*/ + file in( m_pimpl->save_path / file_iter->path / file_iter->filename , file::in); assert(file_offset < file_iter->size); -// in.seekg(file_offset); in.seek(file_offset); + if (in.tell() != file_offset) + { + // the file was not big enough + throw file_error("slot has no storage"); + } -// assert(size_type(in.tellg()) == file_offset); #ifndef NDEBUG size_type in_tell = in.tell(); assert(in_tell == file_offset); #endif - size_type left_to_read = size; - size_type slot_size = m_pimpl->info.piece_size(slot); + int left_to_read = size; + int slot_size = m_pimpl->info.piece_size(slot); if (offset + left_to_read > slot_size) left_to_read = slot_size - offset; assert(left_to_read >= 0); - int result = left_to_read; + size_type result = left_to_read; int buf_pos = 0; while (left_to_read > 0) { int read_bytes = left_to_read; if (file_offset + read_bytes > file_iter->size) - read_bytes = file_iter->size - file_offset; + read_bytes = static_cast(file_iter->size - file_offset); assert(read_bytes > 0); // in.read(buf + buf_pos, read_bytes); // int actual_read = in.gcount(); - int actual_read = in.read(buf + buf_pos, read_bytes); + size_type actual_read = in.read(buf + buf_pos, read_bytes); - assert(read_bytes == actual_read); + if (read_bytes != actual_read) + { + // the file was not big enough + throw file_error("slot has no storage"); + } left_to_read -= read_bytes; buf_pos += read_bytes; @@ -304,9 +319,6 @@ namespace libtorrent fs::path path = m_pimpl->save_path / file_iter->path / file_iter->filename; file_offset = 0; -// in.close(); -// in.clear(); -// in.open(path, std::ios_base::binary); in.open(path, file::in); } } @@ -314,10 +326,15 @@ namespace libtorrent return result; } - void storage::write(const char* buf, int slot, size_type offset, size_type size) + void storage::write( + const char* buf + , int slot + , int offset + , int size) { assert(buf != 0); - assert(slot >= 0 && slot < m_pimpl->info.num_pieces()); + assert(slot >= 0); + assert(slot < m_pimpl->info.num_pieces()); assert(offset >= 0); assert(size > 0); @@ -360,8 +377,8 @@ namespace libtorrent assert(file_offset == out_tell); #endif - size_type left_to_write = size; - size_type slot_size = m_pimpl->info.piece_size(slot); + int left_to_write = size; + int slot_size = m_pimpl->info.piece_size(slot); if (offset + left_to_write > slot_size) left_to_write = slot_size - offset; @@ -378,7 +395,7 @@ namespace libtorrent if (file_offset + write_bytes > file_iter->size) { assert(file_iter->size > file_offset); - write_bytes = file_iter->size - file_offset; + write_bytes = static_cast(file_iter->size - file_offset); } assert(buf_pos >= 0); @@ -422,6 +439,7 @@ namespace libtorrent class piece_manager::impl { + friend class invariant_access; public: impl( @@ -442,8 +460,17 @@ namespace libtorrent int slot_for_piece(int piece_index) const; - size_type read(char* buf, int piece_index, size_type offset, size_type size); - void write(const char* buf, int piece_index, size_type offset, size_type size); + size_type read( + char* buf + , int piece_index + , int offset + , int size); + + void write( + const char* buf + , int piece_index + , int offset + , int size); const boost::filesystem::path& save_path() const { return m_save_path; } @@ -454,6 +481,12 @@ namespace libtorrent // returns the slot currently associated with the given // piece or assigns the given piece_index to a free slot + int identify_data( + const std::vector& piece_data + , int current_slot + , std::vector& have_pieces + , const std::multimap& hash_to_piece); + int allocate_slot_for_piece(int piece_index); #ifndef NDEBUG void check_invariant() const; @@ -468,24 +501,28 @@ namespace libtorrent const torrent_info& m_info; - // maps piece index to slot index. -1 means the piece - // doesn't exist - enum { has_no_slot = -3 }; - std::vector m_piece_to_slot; // slots that hasn't had any file storage allocated std::vector m_unallocated_slots; // slots that has file storage, but isn't assigned to a piece std::vector m_free_slots; - // index here is a slot number in the file - // if index>=0, the slot is assigned to this piece - // otherwise it can have one of these values: + enum + { + has_no_slot = -3 // the piece has no storage + }; + + // maps piece indices to slots. If a piece doesn't + // have any storage, it is set to 'has_no_slot' + std::vector m_piece_to_slot; + enum { unallocated = -1, // the slot is unallocated unassigned = -2 // the slot is allocated but not assigned to a piece }; + // maps slots to piece indices, if a slot doesn't have a piece + // it can either be 'unassigned' or 'unallocated' std::vector m_slot_to_piece; boost::filesystem::path m_save_path; @@ -503,6 +540,7 @@ namespace libtorrent : m_storage(info, save_path) , m_info(info) , m_save_path(save_path) + , m_allocating(false) { } @@ -644,8 +682,8 @@ namespace libtorrent size_type piece_manager::impl::read( char* buf , int piece_index - , size_type offset - , size_type size) + , int offset + , int size) { assert(buf); assert(offset >= 0); @@ -660,8 +698,8 @@ namespace libtorrent size_type piece_manager::read( char* buf , int piece_index - , size_type offset - , size_type size) + , int offset + , int size) { return m_pimpl->read(buf, piece_index, offset, size); } @@ -669,8 +707,8 @@ namespace libtorrent void piece_manager::impl::write( const char* buf , int piece_index - , size_type offset - , size_type size) + , int offset + , int size) { assert(buf); assert(offset >= 0); @@ -684,12 +722,12 @@ namespace libtorrent void piece_manager::write( const char* buf , int piece_index - , size_type offset - , size_type size) + , int offset + , int size) { m_pimpl->write(buf, piece_index, offset, size); } - +/* void piece_manager::impl::check_pieces( boost::mutex& mutex , detail::piece_checker_data& data @@ -787,7 +825,7 @@ namespace libtorrent end_iter = m_info.end_files(); file_iter != end_iter;) { - assert(current_slot>=0 && current_slot= 0 && current_slot < m_info.num_pieces()); // Update progress meter and check if we've been requested to abort { @@ -856,10 +894,13 @@ namespace libtorrent { m_unallocated_slots.push_back(current_slot); ++current_slot; - assert(current_slot <= m_info.num_pieces()); } seek_into_next = pos - file_end; + if (current_slot >= m_info.num_pieces()) + { + break; + } bytes_to_read = m_info.piece_size(current_slot); piece_offset = 0; } @@ -952,7 +993,7 @@ namespace libtorrent } // dirty "fix" for a bug when file is corrupt - for(int i = 0; i < (int)m_info.num_pieces(); ++i) + for (int i = 0; i < (int)m_info.num_pieces(); ++i) { if(m_piece_to_slot[i] != has_no_slot && m_piece_to_slot[i] != i @@ -1000,6 +1041,230 @@ namespace libtorrent check_invariant(); #endif } +*/ + int piece_manager::impl::identify_data( + const std::vector& piece_data + , int current_slot + , std::vector& have_pieces + , const std::multimap& hash_to_piece) + { + assert(have_pieces.size() == m_info.num_pieces()); + + const int piece_size = m_info.piece_length(); + const int last_piece_size = m_info.piece_size( + m_info.num_pieces() - 1); + + assert((int)piece_data.size() >= last_piece_size); + + // calculate a small digest, with the same + // size as the last piece. And a large digest + // which has the same size as a normal piece + hasher small_digest; + small_digest.update(&piece_data[0], last_piece_size); + hasher large_digest(small_digest); + large_digest.update( + &piece_data[last_piece_size] + , piece_size - last_piece_size); + sha1_hash large_hash = large_digest.final(); + sha1_hash small_hash = small_digest.final(); + + typedef std::multimap::const_iterator map_iter; + map_iter begin1; + map_iter end1; + map_iter begin2; + map_iter end2; + + // makes the lookups for the small digest and the large digest + boost::tie(begin1, end1) = hash_to_piece.equal_range(small_hash); + boost::tie(begin2, end2) = hash_to_piece.equal_range(large_hash); + + // copy all potential piece indices into this vector + std::vector matching_pieces; + for (map_iter i = begin1; i != end1; ++i) + matching_pieces.push_back(i->second); + for (map_iter i = begin2; i != end2; ++i) + matching_pieces.push_back(i->second); + + + // no piece matched the data in the slot + if (matching_pieces.empty()) + return -1; + + // ------------------------------------------ + // CHECK IF THE PIECE IS IN ITS CORRECT PLACE + // ------------------------------------------ + + if (std::find( + matching_pieces.begin() + , matching_pieces.end() + , current_slot) != matching_pieces.end()) + { + const int piece_index = current_slot; + + if (have_pieces[piece_index]) + { + // we have already found a piece with + // this index. + int other_slot = m_piece_to_slot[piece_index]; + assert(other_slot >= 0); + + // take one of the other matching pieces + // that hasn't already been assigned + std::sort(matching_pieces.begin(), matching_pieces.end()); + int other_piece = -1; + for (std::vector::iterator i = matching_pieces.begin(); + i != matching_pieces.end(); + ++i) + { + if (have_pieces[*i] || *i == piece_index) continue; + other_piece = *i; + break; + } + if (other_piece >= 0) + { + assert(have_pieces[other_piece] == false); + have_pieces[other_piece] = true; + m_slot_to_piece[other_slot] = other_piece; + m_piece_to_slot[other_piece] = other_slot; + } + else + { + m_slot_to_piece[other_slot] = unassigned; + m_free_slots.push_back(other_slot); + } + } + + have_pieces[piece_index] = true; + return piece_index; + } + + std::sort(matching_pieces.begin(), matching_pieces.end()); + const int piece_index = matching_pieces.back(); + have_pieces[piece_index] = true; + return piece_index; + } + + void piece_manager::impl::check_pieces( + boost::mutex& mutex + , detail::piece_checker_data& data + , std::vector& pieces) + { + // synchronization ------------------------------------------------------ + boost::recursive_mutex::scoped_lock lock(m_mutex); + // ---------------------------------------------------------------------- + + INVARIANT_CHECK; + + m_piece_to_slot.resize(m_info.num_pieces(), has_no_slot); + m_slot_to_piece.resize(m_info.num_pieces(), unallocated); + m_free_slots.clear(); + m_unallocated_slots.clear(); + pieces.clear(); + pieces.resize(m_info.num_pieces(), false); + + // if we have fast-resume info + // use it instead of doing the actual checking + if (!data.piece_map.empty() + && data.piece_map.size() <= m_slot_to_piece.size()) + { + for (int i = 0; i < (int)data.piece_map.size(); ++i) + { + m_slot_to_piece[i] = data.piece_map[i]; + if (data.piece_map[i] >= 0) + { + m_piece_to_slot[data.piece_map[i]] = i; + int found_piece = data.piece_map[i]; + + // if the piece is not in the unfinished list + // we have all of it + if (std::find_if( + data.unfinished_pieces.begin() + , data.unfinished_pieces.end() + , piece_picker::has_index(found_piece)) + == data.unfinished_pieces.end()) + { + pieces[found_piece] = true; + } + } + else if (data.piece_map[i] == unassigned) + { + m_free_slots.push_back(i); + } + else + { + assert(data.piece_map[i] == unallocated); + m_unallocated_slots.push_back(i); + } + } + + for (int i = (int)data.piece_map.size(); i < (int)pieces.size(); ++i) + { + m_unallocated_slots.push_back(i); + } + return; + } + + + + // do the full check + std::vector piece_data(m_info.piece_length()); + const int piece_size = m_info.piece_length(); + const int last_piece_size = m_info.piece_size( + m_info.num_pieces() - 1); + + std::multimap hash_to_piece; + // build the hash-map, that maps hashes to pieces + for (int i = 0; i < m_info.num_pieces(); ++i) + { + hash_to_piece.insert(std::make_pair(m_info.hash_for_piece(i), i)); + } + + for (int current_slot = 0; current_slot < m_info.num_pieces(); ++current_slot) + { + try + { + m_storage.read( + &piece_data[0] + , current_slot + , 0 + , m_info.piece_size(current_slot)); + + int piece_index = identify_data( + piece_data + , current_slot + , pieces + , hash_to_piece); + + if (piece_index >= 0) + { + // the slot was identified as piece 'piece_index' + m_piece_to_slot[piece_index] = current_slot; + m_slot_to_piece[current_slot] = piece_index; + } + else + { + // the data in the slot was not recognized + // consider the slot free + m_slot_to_piece[current_slot] = unassigned; + m_free_slots.push_back(current_slot); + } + } + catch (file_error&) + { + // this means the slot wasn't allocated + m_slot_to_piece[current_slot] = unallocated; + m_unallocated_slots.push_back(current_slot); + } + + // Update progress meter and check if we've been requested to abort + { + boost::mutex::scoped_lock lock(mutex); + data.progress = (float)current_slot / m_info.num_pieces(); + if (data.abort) + return; + } + } + } void piece_manager::check_pieces( boost::mutex& mutex @@ -1015,9 +1280,7 @@ namespace libtorrent boost::recursive_mutex::scoped_lock lock(m_mutex); // ---------------------------------------------------------------------- -#ifndef NDEBUG - check_invariant(); -#endif + INVARIANT_CHECK; assert(piece_index >= 0); assert(piece_index < (int)m_piece_to_slot.size()); @@ -1029,11 +1292,6 @@ namespace libtorrent { assert(slot_index >= 0); assert(slot_index < (int)m_slot_to_piece.size()); - -#ifndef NDEBUG - check_invariant(); -#endif - return slot_index; } @@ -1080,7 +1338,8 @@ namespace libtorrent if (slot_index != piece_index && m_slot_to_piece[piece_index] >= 0) { -#ifndef NDEBUG + +#if !defined(NDEBUG) && defined(TORRENT_STORAGE_DEBUG) std::stringstream s; s << "there is another piece at our slot, swapping.."; @@ -1092,15 +1351,14 @@ namespace libtorrent s << "\n piece at our slot: "; s << m_slot_to_piece[piece_index]; s << "\n"; -#endif - int piece_at_our_slot = m_slot_to_piece[piece_index]; - assert(m_piece_to_slot[piece_at_our_slot] == piece_index); -#ifndef NDEBUG + print_to_log(s.str()); -#ifdef TORRENT_STORAGE_DEBUG debug_log(); #endif -#endif + + int piece_at_our_slot = m_slot_to_piece[piece_index]; + assert(m_piece_to_slot[piece_at_our_slot] == piece_index); + std::swap( m_slot_to_piece[piece_index] , m_slot_to_piece[slot_index]); @@ -1117,6 +1375,7 @@ namespace libtorrent assert(m_piece_to_slot[piece_index] == piece_index); slot_index = piece_index; + #if !defined(NDEBUG) && defined(TORRENT_STORAGE_DEBUG) debug_log(); #endif @@ -1124,16 +1383,12 @@ namespace libtorrent assert(slot_index >= 0); assert(slot_index < (int)m_slot_to_piece.size()); - -#ifndef NDEBUG - check_invariant(); -#endif return slot_index; } void piece_manager::impl::allocate_slots(int num_slots) { - assert(num_slots>0); + assert(num_slots > 0); { boost::mutex::scoped_lock lock(m_allocating_monitor); @@ -1148,9 +1403,7 @@ namespace libtorrent boost::recursive_mutex::scoped_lock lock(m_mutex); // ---------------------------------------------------------------------- -#ifndef NDEBUG - check_invariant(); -#endif + INVARIANT_CHECK; namespace fs = boost::filesystem; @@ -1159,7 +1412,7 @@ namespace libtorrent std::vector::iterator end_iter = m_unallocated_slots.end(); - const size_type piece_size = m_info.piece_length(); + const int piece_size = m_info.piece_length(); std::vector zeros(piece_size, 0); @@ -1185,7 +1438,15 @@ namespace libtorrent m_slot_to_piece[new_free_slot] = unassigned; m_free_slots.push_back(new_free_slot); - m_storage.write(&zeros[0], pos, 0, m_info.piece_size(pos)); + try + { + m_storage.write(&zeros[0], pos, 0, m_info.piece_size(pos)); + } + catch(file_error&) + { + m_allocating = false; + throw; + } } m_unallocated_slots.erase(m_unallocated_slots.begin(), iter); @@ -1193,10 +1454,6 @@ namespace libtorrent m_allocating = false; assert(m_free_slots.size()>0); - -#ifndef NDEBUG - check_invariant(); -#endif } void piece_manager::allocate_slots(int num_slots) diff --git a/src/torrent.cpp b/src/torrent.cpp index d420735c0..cf2288640 100755 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -39,9 +39,17 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + #include #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #include "libtorrent/torrent_handle.hpp" #include "libtorrent/session.hpp" #include "libtorrent/torrent_info.hpp" @@ -219,7 +227,7 @@ namespace libtorrent , m_policy(new policy(this)) , m_ses(ses) , m_picker(torrent_file.piece_length() / m_block_size, - (torrent_file.total_size()+m_block_size-1)/m_block_size) + static_cast((torrent_file.total_size()+m_block_size-1)/m_block_size)) , m_last_working_tracker(0) , m_currently_trying_tracker(0) , m_time_scaler(0) @@ -493,7 +501,7 @@ namespace libtorrent i != pieces.end(); ++i) { - if (*i) piece_list.push_back(i - pieces.begin()); + if (*i) piece_list.push_back(static_cast(i - pieces.begin())); } std::random_shuffle(piece_list.begin(), piece_list.end()); @@ -677,7 +685,7 @@ namespace libtorrent assert(piece_index >= 0); assert(piece_index < m_torrent_file.num_pieces()); - size_type size = m_torrent_file.piece_size(piece_index); + int size = m_torrent_file.piece_size(piece_index); std::vector buffer(size); assert(size > 0); m_storage.read(&buffer[0], piece_index, 0, size); @@ -731,7 +739,7 @@ namespace libtorrent st.announce_interval = boost::posix_time::seconds(m_duration); - st.num_peers = m_connections.size(); + st.num_peers = (int)m_connections.size(); st.pieces = &m_have_pieces; diff --git a/src/torrent_handle.cpp b/src/torrent_handle.cpp index 17e86a919..8718ab4d6 100755 --- a/src/torrent_handle.cpp +++ b/src/torrent_handle.cpp @@ -40,10 +40,18 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + #include #include #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #include "libtorrent/peer_id.hpp" #include "libtorrent/torrent_info.hpp" #include "libtorrent/url_handler.hpp" @@ -233,7 +241,7 @@ namespace libtorrent ret.dict()["blocks per piece"] = num_blocks_per_piece; // num unfinished pieces - int num_unfinished = q.size(); + int num_unfinished = (int)q.size(); ret.dict()["unfinished"] = entry::list_type(); entry::list_type& up = ret.dict()["unfinished"].list(); @@ -436,8 +444,8 @@ namespace libtorrent p.load_balancing = peer->total_free_upload(); - p.download_queue_length = peer->download_queue().size(); - p.upload_queue_length = peer->upload_queue().size(); + p.download_queue_length = (int)peer->download_queue().size(); + p.upload_queue_length = (int)peer->upload_queue().size(); boost::optional ret = peer->downloading_piece(); if (ret) diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index 3bfecc255..642a1567e 100755 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -38,9 +38,17 @@ POSSIBILITY OF SUCH DAMAGE. #include #include +#ifdef _MSC_VER +#pragma warning(push, 1) +#endif + #include #include +#ifdef _MSC_VER +#pragma warning(pop) +#endif + #include "libtorrent/torrent_info.hpp" #include "libtorrent/bencode.hpp" #include "libtorrent/hasher.hpp" @@ -135,7 +143,9 @@ namespace libtorrent i = dict.find("creation date"); if (i != dict.end() && i->second.type() == entry::int_t) { - m_creation_date = m_creation_date + boost::posix_time::seconds(i->second.integer()); + m_creation_date + = m_creation_date + + boost::posix_time::seconds((long)i->second.integer()); } // extract comment @@ -153,7 +163,7 @@ namespace libtorrent std::vector buf; bencode(std::back_insert_iterator >(buf), info); hasher h; - h.update(&buf[0], buf.size()); + h.update(&buf[0], (int)buf.size()); m_info_hash = h.final(); // extract piece length @@ -192,7 +202,7 @@ namespace libtorrent // extract sha-1 hashes for all pieces // we want this division to round upwards, that's why we have the // extra addition - size_type num_pieces = (m_total_size + m_piece_length - 1) / m_piece_length; + int num_pieces = static_cast((m_total_size + m_piece_length - 1) / m_piece_length); i = info.dict().find("pieces"); if (i == info.dict().end()) throw invalid_torrent_file();