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();