forked from premiere/premiere-libtorrent
removed most warnings on msvc.
reimplemented piece_manager::check_pieces to take care of all possible cases of the storage state.
This commit is contained in:
parent
718f01155f
commit
0dbbc18186
|
@ -712,14 +712,15 @@ struct peer_info
|
||||||
address ip;
|
address ip;
|
||||||
float up_speed;
|
float up_speed;
|
||||||
float down_speed;
|
float down_speed;
|
||||||
unsigned int total_download;
|
size_type total_download;
|
||||||
unsigned int total_upload;
|
size_type total_upload;
|
||||||
peer_id id;
|
peer_id id;
|
||||||
std::vector<bool> pieces;
|
std::vector<bool> pieces;
|
||||||
int upload_limit;
|
int upload_limit;
|
||||||
int upload_ceiling;
|
int upload_ceiling;
|
||||||
|
|
||||||
int load_balancing;
|
size_type load_balancing;
|
||||||
|
|
||||||
int download_queue_length;
|
int download_queue_length;
|
||||||
int upload_queue_length;
|
int upload_queue_length;
|
||||||
|
|
||||||
|
|
|
@ -718,14 +718,15 @@ fields::
|
||||||
address ip;
|
address ip;
|
||||||
float up_speed;
|
float up_speed;
|
||||||
float down_speed;
|
float down_speed;
|
||||||
unsigned int total_download;
|
size_type total_download;
|
||||||
unsigned int total_upload;
|
size_type total_upload;
|
||||||
peer_id id;
|
peer_id id;
|
||||||
std::vector<bool> pieces;
|
std::vector<bool> pieces;
|
||||||
int upload_limit;
|
int upload_limit;
|
||||||
int upload_ceiling;
|
int upload_ceiling;
|
||||||
|
|
||||||
int load_balancing;
|
size_type load_balancing;
|
||||||
|
|
||||||
int download_queue_length;
|
int download_queue_length;
|
||||||
int upload_queue_length;
|
int upload_queue_length;
|
||||||
|
|
||||||
|
|
|
@ -35,11 +35,19 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
#include <boost/filesystem/fstream.hpp>
|
#include <boost/filesystem/fstream.hpp>
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/entry.hpp"
|
#include "libtorrent/entry.hpp"
|
||||||
#include "libtorrent/bencode.hpp"
|
#include "libtorrent/bencode.hpp"
|
||||||
#include "libtorrent/session.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.push_back(ses.add_torrent(t, save_path, resume_data));
|
||||||
handles.back().set_max_connections(60);
|
handles.back().set_max_connections(60);
|
||||||
handles.back().set_max_uploads(-1);
|
handles.back().set_max_uploads(-1);
|
||||||
handles.back().set_ratio(1.02);
|
handles.back().set_ratio(1.02f);
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
|
@ -342,9 +350,9 @@ int main(int argc, char* argv[])
|
||||||
i->get_peer_info(peers);
|
i->get_peer_info(peers);
|
||||||
float down = s.download_rate;
|
float down = s.download_rate;
|
||||||
float up = s.upload_rate;
|
float up = s.upload_rate;
|
||||||
int total_down = s.total_download;
|
size_type total_down = s.total_download;
|
||||||
int total_up = s.total_upload;
|
size_type total_up = s.total_upload;
|
||||||
int num_peers = peers.size();
|
int num_peers = (int)peers.size();
|
||||||
|
|
||||||
out.precision(4);
|
out.precision(4);
|
||||||
out.width(5);
|
out.width(5);
|
||||||
|
|
|
@ -30,8 +30,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TORRENT_ERROR_HPP_INCLUDED
|
#ifndef TORRENT_ALERT_HPP_INCLUDED
|
||||||
#define TORRENT_ERROR_HPP_INCLUDED
|
#define TORRENT_ALERT_HPP_INCLUDED
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
@ -39,6 +39,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/thread/mutex.hpp>
|
#include <boost/thread/mutex.hpp>
|
||||||
|
|
||||||
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
|
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
|
||||||
|
@ -47,6 +51,11 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
|
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace libtorrent {
|
namespace libtorrent {
|
||||||
|
|
||||||
class alert
|
class alert
|
||||||
|
@ -158,5 +167,5 @@ namespace libtorrent {
|
||||||
|
|
||||||
} // namespace libtorrent
|
} // namespace libtorrent
|
||||||
|
|
||||||
#endif // TORRENT_ERROR_HPP_INCLUDED
|
#endif // TORRENT_ALERT_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
|
@ -64,8 +64,17 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/entry.hpp"
|
#include "libtorrent/entry.hpp"
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
|
|
@ -36,8 +36,16 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,17 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/size_type.hpp"
|
#include "libtorrent/size_type.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
|
|
|
@ -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 <iostream>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
namespace libtorrent
|
||||||
|
{
|
||||||
|
|
||||||
|
class invariant_access
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
template<class T>
|
||||||
|
static void check_invariant(T const& self)
|
||||||
|
{
|
||||||
|
self.check_invariant();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void check_invariant(T const& x)
|
||||||
|
{
|
||||||
|
invariant_access::check_invariant(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct invariant_checker {};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
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<class T>
|
||||||
|
invariant_checker_impl<T> make_invariant_checker(T const& x)
|
||||||
|
{
|
||||||
|
return invariant_checker_impl<T>(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
|
|
@ -39,6 +39,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/smart_ptr.hpp>
|
#include <boost/smart_ptr.hpp>
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
#include <boost/array.hpp>
|
#include <boost/array.hpp>
|
||||||
|
@ -46,6 +50,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
#include <boost/cstdint.hpp>
|
#include <boost/cstdint.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/socket.hpp"
|
#include "libtorrent/socket.hpp"
|
||||||
#include "libtorrent/peer_id.hpp"
|
#include "libtorrent/peer_id.hpp"
|
||||||
#include "libtorrent/storage.hpp"
|
#include "libtorrent/storage.hpp"
|
||||||
|
@ -196,6 +204,7 @@ namespace libtorrent
|
||||||
|
|
||||||
class peer_connection: public boost::noncopyable
|
class peer_connection: public boost::noncopyable
|
||||||
{
|
{
|
||||||
|
friend class invariant_access;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// this is the constructor where the we are teh active part. The peer_conenction
|
// this is the constructor where the we are teh active part. The peer_conenction
|
||||||
|
@ -304,10 +313,10 @@ namespace libtorrent
|
||||||
// quota is unlimited.
|
// quota is unlimited.
|
||||||
int send_quota_left() const { return m_send_quota_left; }
|
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; }
|
{ return m_free_upload; }
|
||||||
|
|
||||||
void add_free_upload(int free_upload)
|
void add_free_upload(size_type free_upload)
|
||||||
{ m_free_upload += free_upload; }
|
{ m_free_upload += free_upload; }
|
||||||
|
|
||||||
// returns the send quota assigned to this
|
// returns the send quota assigned to this
|
||||||
|
@ -332,7 +341,7 @@ namespace libtorrent
|
||||||
int send_quota_limit() const
|
int send_quota_limit() const
|
||||||
{ return m_send_quota_limit; }
|
{ return m_send_quota_limit; }
|
||||||
|
|
||||||
int share_diff() const;
|
size_type share_diff() const;
|
||||||
|
|
||||||
bool support_extensions() const
|
bool support_extensions() const
|
||||||
{ return m_supports_extensions; }
|
{ return m_supports_extensions; }
|
||||||
|
@ -388,6 +397,8 @@ namespace libtorrent
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void check_invariant() const;
|
||||||
|
|
||||||
bool dispatch_message(int received);
|
bool dispatch_message(int received);
|
||||||
void send_buffer_updated();
|
void send_buffer_updated();
|
||||||
|
|
||||||
|
@ -429,8 +440,8 @@ namespace libtorrent
|
||||||
|
|
||||||
const static message_handler m_message_handler[num_supported_messages];
|
const static message_handler m_message_handler[num_supported_messages];
|
||||||
|
|
||||||
std::size_t m_packet_size;
|
int m_packet_size;
|
||||||
std::size_t m_recv_pos;
|
int m_recv_pos;
|
||||||
std::vector<char> m_recv_buffer;
|
std::vector<char> m_recv_buffer;
|
||||||
|
|
||||||
// this is the buffer where data that is
|
// this is the buffer where data that is
|
||||||
|
@ -542,7 +553,7 @@ namespace libtorrent
|
||||||
// this will be negative on a peer from which
|
// this will be negative on a peer from which
|
||||||
// we get free download, and positive on peers
|
// we get free download, and positive on peers
|
||||||
// that we give the free upload, to keep the balance.
|
// 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.
|
// this is used to limit upload bandwidth.
|
||||||
// it is reset to the allowed number of
|
// it is reset to the allowed number of
|
||||||
|
|
|
@ -34,8 +34,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define TORRENT_PEER_INFO_HPP_INCLUDED
|
#define TORRENT_PEER_INFO_HPP_INCLUDED
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "libtorrent/socket.hpp"
|
#include "libtorrent/socket.hpp"
|
||||||
#include "libtorrent/peer_id.hpp"
|
#include "libtorrent/peer_id.hpp"
|
||||||
|
#include "libtorrent/size_type.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
@ -54,14 +56,14 @@ namespace libtorrent
|
||||||
address ip;
|
address ip;
|
||||||
float up_speed;
|
float up_speed;
|
||||||
float down_speed;
|
float down_speed;
|
||||||
unsigned int total_download;
|
size_type total_download;
|
||||||
unsigned int total_upload;
|
size_type total_upload;
|
||||||
peer_id id;
|
peer_id id;
|
||||||
std::vector<bool> pieces;
|
std::vector<bool> pieces;
|
||||||
int upload_limit; // from peer_connection
|
int upload_limit; // from peer_connection
|
||||||
int upload_ceiling; // from the global upload limiter
|
int upload_ceiling; // from the global upload limiter
|
||||||
|
|
||||||
int load_balancing;
|
size_type load_balancing;
|
||||||
|
|
||||||
// this is the number of requests
|
// this is the number of requests
|
||||||
// we have sent to this peer
|
// we have sent to this peer
|
||||||
|
|
|
@ -37,8 +37,16 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/peer_id.hpp"
|
#include "libtorrent/peer_id.hpp"
|
||||||
#include "libtorrent/socket.hpp"
|
#include "libtorrent/socket.hpp"
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,16 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/peer.hpp"
|
#include "libtorrent/peer.hpp"
|
||||||
#include "libtorrent/piece_picker.hpp"
|
#include "libtorrent/piece_picker.hpp"
|
||||||
#include "libtorrent/socket.hpp"
|
#include "libtorrent/socket.hpp"
|
||||||
|
@ -202,7 +210,7 @@ namespace libtorrent
|
||||||
|
|
||||||
// free download we have got that hasn't
|
// free download we have got that hasn't
|
||||||
// been distributed yet.
|
// been distributed yet.
|
||||||
int m_available_free_upload;
|
size_type m_available_free_upload;
|
||||||
|
|
||||||
// if there is a connection limit,
|
// if there is a connection limit,
|
||||||
// we disconnect one peer every minute in hope of
|
// we disconnect one peer every minute in hope of
|
||||||
|
|
|
@ -40,11 +40,19 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/limits.hpp>
|
#include <boost/limits.hpp>
|
||||||
#include <boost/tuple/tuple.hpp>
|
#include <boost/tuple/tuple.hpp>
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/torrent_handle.hpp"
|
#include "libtorrent/torrent_handle.hpp"
|
||||||
#include "libtorrent/torrent.hpp"
|
#include "libtorrent/torrent.hpp"
|
||||||
#include "libtorrent/entry.hpp"
|
#include "libtorrent/entry.hpp"
|
||||||
|
@ -145,6 +153,7 @@ namespace libtorrent
|
||||||
// thread started to run the main downloader loop
|
// thread started to run the main downloader loop
|
||||||
struct session_impl: boost::noncopyable
|
struct session_impl: boost::noncopyable
|
||||||
{
|
{
|
||||||
|
friend class invariant_access;
|
||||||
typedef std::map<boost::shared_ptr<socket>, boost::shared_ptr<peer_connection> > connection_map;
|
typedef std::map<boost::shared_ptr<socket>, boost::shared_ptr<peer_connection> > connection_map;
|
||||||
|
|
||||||
session_impl(int listen_port, const fingerprint& cl_fprint);
|
session_impl(int listen_port, const fingerprint& cl_fprint);
|
||||||
|
@ -208,7 +217,7 @@ namespace libtorrent
|
||||||
void purge_connections();
|
void purge_connections();
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
void assert_invariant(const char *place);
|
void check_invariant(const char *place = 0);
|
||||||
boost::shared_ptr<logger> create_log(std::string name);
|
boost::shared_ptr<logger> create_log(std::string name);
|
||||||
boost::shared_ptr<logger> m_logger;
|
boost::shared_ptr<logger> m_logger;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,8 +33,16 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef TORRENT_SIZE_TYPE_HPP_INCLUDED
|
#ifndef TORRENT_SIZE_TYPE_HPP_INCLUDED
|
||||||
#define TORRENT_SIZE_TYPE_HPP_INCLUDED
|
#define TORRENT_SIZE_TYPE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/cstdint.hpp>
|
#include <boost/cstdint.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1300
|
#if defined(_MSC_VER) && _MSC_VER < 1300
|
||||||
|
|
|
@ -33,10 +33,19 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef TORRENT_SOCKET_HPP_INCLUDED
|
#ifndef TORRENT_SOCKET_HPP_INCLUDED
|
||||||
#define TORRENT_SOCKET_HPP_INCLUDED
|
#define TORRENT_SOCKET_HPP_INCLUDED
|
||||||
|
|
||||||
#include <boost/smart_ptr.hpp>
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
|
@ -38,12 +38,14 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "libtorrent/size_type.hpp"
|
#include "libtorrent/size_type.hpp"
|
||||||
|
#include "libtorrent/invariant_check.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
|
||||||
class stat
|
class stat
|
||||||
{
|
{
|
||||||
|
friend class invariant_access;
|
||||||
enum { history = 10 };
|
enum { history = 10 };
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -67,6 +69,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void operator+=(const stat& s)
|
void operator+=(const stat& s)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
m_downloaded_payload += s.m_downloaded_payload;
|
m_downloaded_payload += s.m_downloaded_payload;
|
||||||
m_total_download_payload += s.m_downloaded_payload;
|
m_total_download_payload += s.m_downloaded_payload;
|
||||||
m_downloaded_protocol += s.m_downloaded_protocol;
|
m_downloaded_protocol += s.m_downloaded_protocol;
|
||||||
|
@ -80,22 +84,26 @@ namespace libtorrent
|
||||||
|
|
||||||
void received_bytes(int bytes_payload, int bytes_protocol)
|
void received_bytes(int bytes_payload, int bytes_protocol)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
assert(bytes_payload >= 0);
|
assert(bytes_payload >= 0);
|
||||||
assert(bytes_protocol >= 0);
|
assert(bytes_protocol >= 0);
|
||||||
|
|
||||||
m_downloaded_payload += bytes_payload;
|
m_downloaded_payload += bytes_payload;
|
||||||
m_total_download_payload += bytes_payload;
|
m_total_download_payload += bytes_payload;
|
||||||
|
|
||||||
m_downloaded_protocol += bytes_protocol;
|
m_downloaded_protocol += bytes_protocol;
|
||||||
m_total_download_protocol += bytes_protocol;
|
m_total_download_protocol += bytes_protocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sent_bytes(int bytes_payload, int bytes_protocol)
|
void sent_bytes(int bytes_payload, int bytes_protocol)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
assert(bytes_payload >= 0);
|
assert(bytes_payload >= 0);
|
||||||
assert(bytes_protocol >= 0);
|
assert(bytes_protocol >= 0);
|
||||||
|
|
||||||
m_uploaded_payload += bytes_payload;
|
m_uploaded_payload += bytes_payload;
|
||||||
m_total_upload_payload += bytes_payload;
|
m_total_upload_payload += bytes_payload;
|
||||||
|
|
||||||
m_uploaded_protocol += bytes_protocol;
|
m_uploaded_protocol += bytes_protocol;
|
||||||
m_total_upload_protocol += bytes_protocol;
|
m_total_upload_protocol += bytes_protocol;
|
||||||
}
|
}
|
||||||
|
@ -119,7 +127,7 @@ namespace libtorrent
|
||||||
private:
|
private:
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
void check_invariant()
|
void check_invariant() const
|
||||||
{
|
{
|
||||||
assert(m_mean_upload_per_second >= 0);
|
assert(m_mean_upload_per_second >= 0);
|
||||||
assert(m_mean_download_per_second >= 0);
|
assert(m_mean_download_per_second >= 0);
|
||||||
|
@ -159,12 +167,12 @@ namespace libtorrent
|
||||||
size_type m_total_upload_protocol;
|
size_type m_total_upload_protocol;
|
||||||
|
|
||||||
// peak mean download/upload rates
|
// peak mean download/upload rates
|
||||||
int m_peak_downloaded_per_second;
|
float m_peak_downloaded_per_second;
|
||||||
int m_peak_uploaded_per_second;
|
float m_peak_uploaded_per_second;
|
||||||
|
|
||||||
// current mean download/upload rates
|
// current mean download/upload rates
|
||||||
int m_mean_download_per_second;
|
float m_mean_download_per_second;
|
||||||
int m_mean_upload_per_second;
|
float m_mean_upload_per_second;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,10 +36,19 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/limits.hpp>
|
#include <boost/limits.hpp>
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include "libtorrent/torrent_info.hpp"
|
#include "libtorrent/torrent_info.hpp"
|
||||||
#include "libtorrent/opaque_value_ptr.hpp"
|
#include "libtorrent/opaque_value_ptr.hpp"
|
||||||
|
|
||||||
|
@ -78,11 +87,14 @@ namespace libtorrent
|
||||||
|
|
||||||
void swap(storage&);
|
void swap(storage&);
|
||||||
|
|
||||||
size_type read(char* buf, int slot, size_type offset, size_type size);
|
// may throw file_error if storage for slot does not exist
|
||||||
void write(const char* buf, int slot, size_type offset, size_type size);
|
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:
|
private:
|
||||||
struct impl;
|
class impl;
|
||||||
opaque_value_ptr<impl> m_pimpl;
|
opaque_value_ptr<impl> m_pimpl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -110,8 +122,17 @@ namespace libtorrent
|
||||||
, const std::bitset<256>& bitmask);
|
, const std::bitset<256>& bitmask);
|
||||||
int slot_for_piece(int piece_index) const;
|
int slot_for_piece(int piece_index) const;
|
||||||
|
|
||||||
size_type read(char* buf, int piece_index, size_type offset, size_type size);
|
size_type read(
|
||||||
void write(const char* buf, int piece_index, size_type offset, size_type size);
|
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;
|
const boost::filesystem::path& save_path() const;
|
||||||
|
|
||||||
|
@ -122,7 +143,7 @@ namespace libtorrent
|
||||||
void export_piece_map(std::vector<int>& pieces) const;
|
void export_piece_map(std::vector<int>& pieces) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct impl;
|
class impl;
|
||||||
std::auto_ptr<impl> m_pimpl;
|
std::auto_ptr<impl> m_pimpl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -39,10 +39,18 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/limits.hpp>
|
#include <boost/limits.hpp>
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/torrent_handle.hpp"
|
#include "libtorrent/torrent_handle.hpp"
|
||||||
#include "libtorrent/entry.hpp"
|
#include "libtorrent/entry.hpp"
|
||||||
#include "libtorrent/torrent_info.hpp"
|
#include "libtorrent/torrent_info.hpp"
|
||||||
|
@ -151,7 +159,7 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
// the number of peers that belong to this torrent
|
// 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
|
// returns true if this torrent has a connection
|
||||||
// to a peer with the given peer_id
|
// to a peer with the given peer_id
|
||||||
|
|
|
@ -34,8 +34,17 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define TORRENT_TORRENT_HANDLE_HPP_INCLUDED
|
#define TORRENT_TORRENT_HANDLE_HPP_INCLUDED
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/peer_id.hpp"
|
#include "libtorrent/peer_id.hpp"
|
||||||
#include "libtorrent/peer_info.hpp"
|
#include "libtorrent/peer_info.hpp"
|
||||||
#include "libtorrent/piece_picker.hpp"
|
#include "libtorrent/piece_picker.hpp"
|
||||||
|
|
|
@ -36,8 +36,17 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/entry.hpp"
|
#include "libtorrent/entry.hpp"
|
||||||
#include "libtorrent/socket.hpp"
|
#include "libtorrent/socket.hpp"
|
||||||
#include "libtorrent/peer_id.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 rbegin_files() const { return m_files.rbegin(); }
|
||||||
reverse_file_iterator rend_files() const { return m_files.rend(); }
|
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 file_entry& file_at(int index) const { assert(index >= 0 && index < (int)m_files.size()); return m_files[index]; }
|
||||||
|
|
||||||
const std::vector<announce_entry>& trackers() const { return m_urls; }
|
const std::vector<announce_entry>& trackers() const { return m_urls; }
|
||||||
|
@ -116,8 +125,8 @@ namespace libtorrent
|
||||||
// the begining) and return the new index to the tracker.
|
// the begining) and return the new index to the tracker.
|
||||||
int prioritize_tracker(int index);
|
int prioritize_tracker(int index);
|
||||||
|
|
||||||
size_type total_size() const { assert(m_total_size>=0); return m_total_size; }
|
size_type total_size() const { return m_total_size; }
|
||||||
size_type piece_length() const { assert(m_piece_length>0); return m_piece_length; }
|
int piece_length() const { return m_piece_length; }
|
||||||
int num_pieces() const { return (int)m_piece_hash.size(); }
|
int num_pieces() const { return (int)m_piece_hash.size(); }
|
||||||
const sha1_hash& info_hash() const { return m_info_hash; }
|
const sha1_hash& info_hash() const { return m_info_hash; }
|
||||||
const std::string& name() const { return m_name; }
|
const std::string& name() const { return m_name; }
|
||||||
|
@ -125,12 +134,13 @@ namespace libtorrent
|
||||||
|
|
||||||
void convert_file_names();
|
void convert_file_names();
|
||||||
|
|
||||||
size_type piece_size(int index) const
|
int piece_size(int index) const
|
||||||
{
|
{
|
||||||
assert(index >= 0 && index < num_pieces());
|
assert(index >= 0 && index < num_pieces());
|
||||||
if (index == num_pieces()-1)
|
if (index == num_pieces()-1)
|
||||||
{
|
{
|
||||||
size_type s = total_size() - (size_type)(num_pieces() - 1)*piece_length();
|
int s = static_cast<int>(total_size()
|
||||||
|
- (size_type)(num_pieces() - 1) * piece_length());
|
||||||
assert(s > 0);
|
assert(s > 0);
|
||||||
assert(s <= piece_length());
|
assert(s <= piece_length());
|
||||||
return s;
|
return s;
|
||||||
|
@ -141,7 +151,8 @@ namespace libtorrent
|
||||||
|
|
||||||
const sha1_hash& hash_for_piece(int index) const
|
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];
|
return m_piece_hash[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +170,7 @@ namespace libtorrent
|
||||||
std::vector<announce_entry> m_urls;
|
std::vector<announce_entry> m_urls;
|
||||||
|
|
||||||
// the length of one piece
|
// the length of one piece
|
||||||
size_type m_piece_length;
|
int m_piece_length;
|
||||||
|
|
||||||
// the sha-1 hashes of each piece
|
// the sha-1 hashes of each piece
|
||||||
std::vector<sha1_hash> m_piece_hash;
|
std::vector<sha1_hash> m_piece_hash;
|
||||||
|
|
|
@ -30,9 +30,18 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <boost/optional.hpp>
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/identify_client.hpp"
|
#include "libtorrent/identify_client.hpp"
|
||||||
#include "libtorrent/fingerprint.hpp"
|
#include "libtorrent/fingerprint.hpp"
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/entry.hpp"
|
#include "libtorrent/entry.hpp"
|
||||||
#include "libtorrent/bencode.hpp"
|
#include "libtorrent/bencode.hpp"
|
||||||
#include "libtorrent/alert_types.hpp"
|
#include "libtorrent/alert_types.hpp"
|
||||||
|
#include "libtorrent/invariant_check.hpp"
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#define for if (false) {} else for
|
#define for if (false) {} else for
|
||||||
|
@ -82,8 +83,8 @@ namespace libtorrent
|
||||||
, m_timeout(120)
|
, m_timeout(120)
|
||||||
, m_packet_size(1)
|
, m_packet_size(1)
|
||||||
, m_recv_pos(0)
|
, m_recv_pos(0)
|
||||||
, m_last_receive(boost::gregorian::date(std::time(0)))
|
, m_last_receive(boost::posix_time::second_clock::local_time())
|
||||||
, m_last_sent(boost::gregorian::date(std::time(0)))
|
, m_last_sent(boost::posix_time::second_clock::local_time())
|
||||||
, m_selector(sel)
|
, m_selector(sel)
|
||||||
, m_socket(s)
|
, m_socket(s)
|
||||||
, m_torrent(t)
|
, m_torrent(t)
|
||||||
|
@ -102,10 +103,12 @@ namespace libtorrent
|
||||||
, m_send_quota_limit(100)
|
, m_send_quota_limit(100)
|
||||||
, m_trust_points(0)
|
, m_trust_points(0)
|
||||||
, m_num_invalid_requests(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_last_piece_time(boost::posix_time::seconds(0))
|
||||||
, m_disconnecting(false)
|
, m_disconnecting(false)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
assert(!m_socket->is_blocking());
|
assert(!m_socket->is_blocking());
|
||||||
assert(m_torrent != 0);
|
assert(m_torrent != 0);
|
||||||
|
|
||||||
|
@ -141,8 +144,8 @@ namespace libtorrent
|
||||||
, m_timeout(120)
|
, m_timeout(120)
|
||||||
, m_packet_size(1)
|
, m_packet_size(1)
|
||||||
, m_recv_pos(0)
|
, m_recv_pos(0)
|
||||||
, m_last_receive(boost::gregorian::date(std::time(0)))
|
, m_last_receive(boost::posix_time::second_clock::local_time())
|
||||||
, m_last_sent(boost::gregorian::date(std::time(0)))
|
, m_last_sent(boost::posix_time::second_clock::local_time())
|
||||||
, m_selector(sel)
|
, m_selector(sel)
|
||||||
, m_socket(s)
|
, m_socket(s)
|
||||||
, m_torrent(0)
|
, m_torrent(0)
|
||||||
|
@ -162,10 +165,12 @@ namespace libtorrent
|
||||||
, m_send_quota_limit(100)
|
, m_send_quota_limit(100)
|
||||||
, m_trust_points(0)
|
, m_trust_points(0)
|
||||||
, m_num_invalid_requests(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_last_piece_time(boost::posix_time::seconds(0))
|
||||||
, m_disconnecting(false)
|
, m_disconnecting(false)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
assert(!m_socket->is_blocking());
|
assert(!m_socket->is_blocking());
|
||||||
|
|
||||||
std::fill(m_peer_id.begin(), m_peer_id.end(), 0);
|
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)
|
void peer_connection::set_send_quota(int num_bytes)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
assert(num_bytes <= m_send_quota_limit || m_send_quota_limit == -1);
|
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;
|
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()
|
void peer_connection::send_handshake()
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
assert(m_send_buffer.size() == 0);
|
assert(m_send_buffer.size() == 0);
|
||||||
|
|
||||||
// add handshake to the send buffer
|
// add handshake to the send buffer
|
||||||
|
@ -312,6 +321,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void peer_connection::on_choke(int received)
|
void peer_connection::on_choke(int received)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (m_packet_size != 1)
|
if (m_packet_size != 1)
|
||||||
throw protocol_error("'choke' message size != 1");
|
throw protocol_error("'choke' message size != 1");
|
||||||
m_statistics.received_bytes(0, received);
|
m_statistics.received_bytes(0, received);
|
||||||
|
@ -343,6 +354,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void peer_connection::on_unchoke(int received)
|
void peer_connection::on_unchoke(int received)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (m_packet_size != 1)
|
if (m_packet_size != 1)
|
||||||
throw protocol_error("'unchoke' message size != 1");
|
throw protocol_error("'unchoke' message size != 1");
|
||||||
m_statistics.received_bytes(0, received);
|
m_statistics.received_bytes(0, received);
|
||||||
|
@ -361,6 +374,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void peer_connection::on_interested(int received)
|
void peer_connection::on_interested(int received)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (m_packet_size != 1)
|
if (m_packet_size != 1)
|
||||||
throw protocol_error("'interested' message size != 1");
|
throw protocol_error("'interested' message size != 1");
|
||||||
m_statistics.received_bytes(0, received);
|
m_statistics.received_bytes(0, received);
|
||||||
|
@ -379,6 +394,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void peer_connection::on_not_interested(int received)
|
void peer_connection::on_not_interested(int received)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (m_packet_size != 1)
|
if (m_packet_size != 1)
|
||||||
throw protocol_error("'not interested' message size != 1");
|
throw protocol_error("'not interested' message size != 1");
|
||||||
m_statistics.received_bytes(0, received);
|
m_statistics.received_bytes(0, received);
|
||||||
|
@ -400,6 +417,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void peer_connection::on_have(int received)
|
void peer_connection::on_have(int received)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (m_packet_size != 5)
|
if (m_packet_size != 5)
|
||||||
throw protocol_error("'have' message size != 5");
|
throw protocol_error("'have' message size != 5");
|
||||||
m_statistics.received_bytes(0, received);
|
m_statistics.received_bytes(0, received);
|
||||||
|
@ -408,7 +427,7 @@ namespace libtorrent
|
||||||
const char* ptr = &m_recv_buffer[1];
|
const char* ptr = &m_recv_buffer[1];
|
||||||
int index = detail::read_int32(ptr);
|
int index = detail::read_int32(ptr);
|
||||||
// if we got an invalid message, abort
|
// 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");
|
throw protocol_error("have message with higher index than the number of pieces");
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -442,6 +461,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void peer_connection::on_bitfield(int received)
|
void peer_connection::on_bitfield(int received)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (m_packet_size - 1 != (m_have_piece.size() + 7) / 8)
|
if (m_packet_size - 1 != (m_have_piece.size() + 7) / 8)
|
||||||
throw protocol_error("bitfield with invalid size");
|
throw protocol_error("bitfield with invalid size");
|
||||||
m_statistics.received_bytes(0, received);
|
m_statistics.received_bytes(0, received);
|
||||||
|
@ -452,9 +473,9 @@ namespace libtorrent
|
||||||
#endif
|
#endif
|
||||||
// build a vector of all pieces
|
// build a vector of all pieces
|
||||||
std::vector<int> piece_list;
|
std::vector<int> 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])
|
if (have && !m_have_piece[i])
|
||||||
{
|
{
|
||||||
m_have_piece[i] = true;
|
m_have_piece[i] = true;
|
||||||
|
@ -507,6 +528,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void peer_connection::on_request(int received)
|
void peer_connection::on_request(int received)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (m_packet_size != 13)
|
if (m_packet_size != 13)
|
||||||
throw protocol_error("'request' message size != 13");
|
throw protocol_error("'request' message size != 13");
|
||||||
m_statistics.received_bytes(0, received);
|
m_statistics.received_bytes(0, received);
|
||||||
|
@ -572,6 +595,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void peer_connection::on_piece(int received)
|
void peer_connection::on_piece(int received)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (m_recv_pos - received <= 9)
|
if (m_recv_pos - received <= 9)
|
||||||
{
|
{
|
||||||
m_last_piece = boost::posix_time::second_clock::local_time();
|
m_last_piece = boost::posix_time::second_clock::local_time();
|
||||||
|
@ -717,6 +742,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void peer_connection::on_cancel(int received)
|
void peer_connection::on_cancel(int received)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (m_packet_size != 13)
|
if (m_packet_size != 13)
|
||||||
throw protocol_error("'cancel' message size != 13");
|
throw protocol_error("'cancel' message size != 13");
|
||||||
m_statistics.received_bytes(0, received);
|
m_statistics.received_bytes(0, received);
|
||||||
|
@ -752,6 +779,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void peer_connection::on_extension_list(int received)
|
void peer_connection::on_extension_list(int received)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (m_packet_size > 100 * 1024)
|
if (m_packet_size > 100 * 1024)
|
||||||
{
|
{
|
||||||
// too big extension message, abort
|
// too big extension message, abort
|
||||||
|
@ -771,7 +800,7 @@ namespace libtorrent
|
||||||
extensions.find(extension_names[i]);
|
extensions.find(extension_names[i]);
|
||||||
if (f != extensions.end())
|
if (f != extensions.end())
|
||||||
{
|
{
|
||||||
m_extension_messages[i] = f->second.integer();
|
m_extension_messages[i] = (int)f->second.integer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -784,11 +813,11 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
catch(invalid_encoding& e)
|
catch(invalid_encoding&)
|
||||||
{
|
{
|
||||||
throw protocol_error("'extensions' packet contains invalid bencoding");
|
throw protocol_error("'extensions' packet contains invalid bencoding");
|
||||||
}
|
}
|
||||||
catch(type_error& e)
|
catch(type_error&)
|
||||||
{
|
{
|
||||||
throw protocol_error("'extensions' packet contains incorrect types");
|
throw protocol_error("'extensions' packet contains incorrect types");
|
||||||
}
|
}
|
||||||
|
@ -800,6 +829,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void peer_connection::on_extended(int received)
|
void peer_connection::on_extended(int received)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
m_statistics.received_bytes(0, received);
|
m_statistics.received_bytes(0, received);
|
||||||
if (m_packet_size < 5)
|
if (m_packet_size < 5)
|
||||||
throw protocol_error("'extended' message smaller than 5 bytes");
|
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");
|
throw protocol_error("invalid bencoding in CHAT message");
|
||||||
}
|
}
|
||||||
catch (type_error& e)
|
catch (type_error&)
|
||||||
{
|
{
|
||||||
throw protocol_error("invalid types in bencoded CHAT message");
|
throw protocol_error("invalid types in bencoded CHAT message");
|
||||||
}
|
}
|
||||||
|
@ -873,6 +904,8 @@ namespace libtorrent
|
||||||
|
|
||||||
bool peer_connection::dispatch_message(int received)
|
bool peer_connection::dispatch_message(int received)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
assert(m_recv_pos >= received);
|
assert(m_recv_pos >= received);
|
||||||
assert(m_recv_pos > 0);
|
assert(m_recv_pos > 0);
|
||||||
assert(m_torrent);
|
assert(m_torrent);
|
||||||
|
@ -898,6 +931,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void peer_connection::send_cancel(piece_block block)
|
void peer_connection::send_cancel(piece_block block)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
assert(block.piece_index >= 0);
|
assert(block.piece_index >= 0);
|
||||||
assert(block.piece_index < m_torrent->torrent_file().num_pieces());
|
assert(block.piece_index < m_torrent->torrent_file().num_pieces());
|
||||||
assert(m_torrent->picker().is_downloading(block));
|
assert(m_torrent->picker().is_downloading(block));
|
||||||
|
@ -944,6 +979,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void peer_connection::send_request(piece_block block)
|
void peer_connection::send_request(piece_block block)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
assert(block.piece_index >= 0);
|
assert(block.piece_index >= 0);
|
||||||
assert(block.piece_index < m_torrent->torrent_file().num_pieces());
|
assert(block.piece_index < m_torrent->torrent_file().num_pieces());
|
||||||
assert(!m_torrent->picker().is_downloading(block));
|
assert(!m_torrent->picker().is_downloading(block));
|
||||||
|
@ -995,6 +1032,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void peer_connection::send_chat_message(const std::string& msg)
|
void peer_connection::send_chat_message(const std::string& msg)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
assert(msg.length() <= 1 * 1024);
|
assert(msg.length() <= 1 * 1024);
|
||||||
if (m_extension_messages[extended_chat_message] == -1) return;
|
if (m_extension_messages[extended_chat_message] == -1) return;
|
||||||
|
|
||||||
|
@ -1005,7 +1044,7 @@ namespace libtorrent
|
||||||
bencode(std::back_inserter(message), e);
|
bencode(std::back_inserter(message), e);
|
||||||
std::back_insert_iterator<std::vector<char> > ptr(m_send_buffer);
|
std::back_insert_iterator<std::vector<char> > 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_uint8(msg_extended, ptr);
|
||||||
detail::write_int32(m_extension_messages[extended_chat_message], ptr);
|
detail::write_int32(m_extension_messages[extended_chat_message], ptr);
|
||||||
std::copy(message.begin(), message.end(), ptr);
|
std::copy(message.begin(), message.end(), ptr);
|
||||||
|
@ -1014,17 +1053,21 @@ namespace libtorrent
|
||||||
|
|
||||||
void peer_connection::send_bitfield()
|
void peer_connection::send_bitfield()
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
(*m_logger) << " ==> BITFIELD\n";
|
(*m_logger) << " ==> BITFIELD\n";
|
||||||
#endif
|
#endif
|
||||||
const int packet_size = (m_have_piece.size() + 7) / 8 + 5;
|
const int packet_size = ((int)m_have_piece.size() + 7) / 8 + 5;
|
||||||
const int old_size = m_send_buffer.size();
|
const int old_size = (int)m_send_buffer.size();
|
||||||
m_send_buffer.resize(old_size + packet_size);
|
m_send_buffer.resize(old_size + packet_size);
|
||||||
|
|
||||||
char* ptr = &m_send_buffer[old_size];
|
char* ptr = &m_send_buffer[old_size];
|
||||||
detail::write_int32(packet_size - 4, ptr);
|
detail::write_int32(packet_size - 4, ptr);
|
||||||
m_send_buffer[old_size+4] = msg_bitfield;
|
detail::write_uint8(msg_bitfield, ptr);
|
||||||
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)
|
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))
|
if (m_torrent->have_piece(i))
|
||||||
m_send_buffer[old_size + 5 + (i>>3)] |= 1 << (7 - (i&7));
|
m_send_buffer[old_size + 5 + (i>>3)] |= 1 << (7 - (i&7));
|
||||||
|
@ -1034,6 +1077,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void peer_connection::send_extensions()
|
void peer_connection::send_extensions()
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
(*m_logger) << " ==> EXTENSIONS\n";
|
(*m_logger) << " ==> EXTENSIONS\n";
|
||||||
#endif
|
#endif
|
||||||
|
@ -1047,7 +1092,7 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
// make room for message size
|
// 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.resize(msg_size_pos + 4);
|
||||||
|
|
||||||
m_send_buffer.push_back(msg_extension_list);
|
m_send_buffer.push_back(msg_extension_list);
|
||||||
|
@ -1056,13 +1101,15 @@ namespace libtorrent
|
||||||
|
|
||||||
// write the length of the message
|
// write the length of the message
|
||||||
char* ptr = &m_send_buffer[msg_size_pos];
|
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();
|
send_buffer_updated();
|
||||||
}
|
}
|
||||||
|
|
||||||
void peer_connection::send_choke()
|
void peer_connection::send_choke()
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (m_choked) return;
|
if (m_choked) return;
|
||||||
char msg[] = {0,0,0,1,msg_choke};
|
char msg[] = {0,0,0,1,msg_choke};
|
||||||
m_send_buffer.insert(m_send_buffer.end(), msg, msg+sizeof(msg));
|
m_send_buffer.insert(m_send_buffer.end(), msg, msg+sizeof(msg));
|
||||||
|
@ -1077,6 +1124,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void peer_connection::send_unchoke()
|
void peer_connection::send_unchoke()
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (!m_choked) return;
|
if (!m_choked) return;
|
||||||
char msg[] = {0,0,0,1,msg_unchoke};
|
char msg[] = {0,0,0,1,msg_unchoke};
|
||||||
m_send_buffer.insert(m_send_buffer.end(), msg, msg+sizeof(msg));
|
m_send_buffer.insert(m_send_buffer.end(), msg, msg+sizeof(msg));
|
||||||
|
@ -1089,6 +1138,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void peer_connection::send_interested()
|
void peer_connection::send_interested()
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (m_interesting) return;
|
if (m_interesting) return;
|
||||||
char msg[] = {0,0,0,1,msg_interested};
|
char msg[] = {0,0,0,1,msg_interested};
|
||||||
m_send_buffer.insert(m_send_buffer.end(), msg, msg+sizeof(msg));
|
m_send_buffer.insert(m_send_buffer.end(), msg, msg+sizeof(msg));
|
||||||
|
@ -1101,6 +1152,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void peer_connection::send_not_interested()
|
void peer_connection::send_not_interested()
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (!m_interesting) return;
|
if (!m_interesting) return;
|
||||||
char msg[] = {0,0,0,1,msg_not_interested};
|
char msg[] = {0,0,0,1,msg_not_interested};
|
||||||
m_send_buffer.insert(m_send_buffer.end(), msg, msg+sizeof(msg));
|
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)
|
void peer_connection::send_have(int index)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
// optimization, don't send have messages
|
// optimization, don't send have messages
|
||||||
// to peers that already have the piece
|
// to peers that already have the piece
|
||||||
if (m_have_piece[index]) return;
|
if (m_have_piece[index]) return;
|
||||||
|
@ -1128,7 +1183,7 @@ namespace libtorrent
|
||||||
send_buffer_updated();
|
send_buffer_updated();
|
||||||
}
|
}
|
||||||
|
|
||||||
int peer_connection::share_diff() const
|
size_type peer_connection::share_diff() const
|
||||||
{
|
{
|
||||||
float ratio = m_torrent->ratio();
|
float ratio = m_torrent->ratio();
|
||||||
|
|
||||||
|
@ -1137,12 +1192,14 @@ namespace libtorrent
|
||||||
if (ratio == 0.f) return std::numeric_limits<int>::max();
|
if (ratio == 0.f) return std::numeric_limits<int>::max();
|
||||||
|
|
||||||
return m_free_upload
|
return m_free_upload
|
||||||
+ static_cast<int>(m_statistics.total_payload_download() * ratio)
|
+ static_cast<size_type>(m_statistics.total_payload_download() * ratio)
|
||||||
- m_statistics.total_payload_upload();
|
- m_statistics.total_payload_upload();
|
||||||
}
|
}
|
||||||
|
|
||||||
void peer_connection::second_tick()
|
void peer_connection::second_tick()
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
m_statistics.second_tick();
|
m_statistics.second_tick();
|
||||||
m_send_quota_left = m_send_quota;
|
m_send_quota_left = m_send_quota;
|
||||||
if (m_send_quota > 0) send_buffer_updated();
|
if (m_send_quota > 0) send_buffer_updated();
|
||||||
|
@ -1154,7 +1211,7 @@ namespace libtorrent
|
||||||
// maintain the share ratio given by m_ratio
|
// maintain the share ratio given by m_ratio
|
||||||
// with all peers.
|
// with all peers.
|
||||||
|
|
||||||
int diff = share_diff();
|
size_type diff = share_diff();
|
||||||
|
|
||||||
enum { block_limit=2 }; // how many blocks difference is considered unfair
|
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
|
// throws exception when the client should be disconnected
|
||||||
void peer_connection::receive_data()
|
void peer_connection::receive_data()
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
assert(!m_socket->is_blocking());
|
assert(!m_socket->is_blocking());
|
||||||
assert(m_packet_size > 0);
|
assert(m_packet_size > 0);
|
||||||
assert(m_socket->is_readable());
|
assert(m_socket->is_readable());
|
||||||
|
@ -1466,6 +1525,8 @@ namespace libtorrent
|
||||||
// throws exception when the client should be disconnected
|
// throws exception when the client should be disconnected
|
||||||
void peer_connection::send_data()
|
void peer_connection::send_data()
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
assert(m_socket->is_writable());
|
assert(m_socket->is_writable());
|
||||||
assert(has_data());
|
assert(has_data());
|
||||||
|
|
||||||
|
@ -1475,19 +1536,22 @@ namespace libtorrent
|
||||||
// requested block. Have a limit of how much of the requested
|
// requested block. Have a limit of how much of the requested
|
||||||
// block is actually read at a time.
|
// block is actually read at a time.
|
||||||
while (!m_requests.empty()
|
while (!m_requests.empty()
|
||||||
&& (m_send_buffer.size() < m_torrent->block_size())
|
&& ((int)m_send_buffer.size() < m_torrent->block_size())
|
||||||
&& !m_choked)
|
&& !m_choked)
|
||||||
{
|
{
|
||||||
peer_request& r = m_requests.front();
|
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.start + r.length <= m_torrent->torrent_file().piece_size(r.piece));
|
||||||
assert(r.length > 0 && r.start >= 0);
|
assert(r.length > 0 && r.start >= 0);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// assert(m_torrent->verify_piece(r.piece) && "internal error");
|
// assert(m_torrent->verify_piece(r.piece) && "internal error");
|
||||||
#endif
|
#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;
|
const int packet_size = 4 + 5 + 4 + r.length;
|
||||||
m_send_buffer.resize(send_buffer_offset + packet_size);
|
m_send_buffer.resize(send_buffer_offset + packet_size);
|
||||||
char* ptr = &m_send_buffer[send_buffer_offset];
|
char* ptr = &m_send_buffer[send_buffer_offset];
|
||||||
|
@ -1539,7 +1603,7 @@ namespace libtorrent
|
||||||
if (!m_send_buffer.empty())
|
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);
|
assert(m_send_quota_left != 0);
|
||||||
if (m_send_quota_left > 0)
|
if (m_send_quota_left > 0)
|
||||||
amount_to_send = std::min(m_send_quota_left, amount_to_send);
|
amount_to_send = std::min(m_send_quota_left, amount_to_send);
|
||||||
|
@ -1615,22 +1679,19 @@ namespace libtorrent
|
||||||
|
|
||||||
assert(m_added_to_selector);
|
assert(m_added_to_selector);
|
||||||
send_buffer_updated();
|
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()
|
void peer_connection::keep_alive()
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
boost::posix_time::time_duration d;
|
boost::posix_time::time_duration d;
|
||||||
d = boost::posix_time::second_clock::local_time() - m_last_sent;
|
d = boost::posix_time::second_clock::local_time() - m_last_sent;
|
||||||
if (d.seconds() < m_timeout / 2) return;
|
if (d.seconds() < m_timeout / 2) return;
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace libtorrent
|
||||||
++i)
|
++i)
|
||||||
{
|
{
|
||||||
if (*i) continue;
|
if (*i) continue;
|
||||||
int index = i - pieces.begin();
|
int index = static_cast<int>(i - pieces.begin());
|
||||||
piece_list.push_back(index);
|
piece_list.push_back(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,14 +100,14 @@ namespace libtorrent
|
||||||
++i)
|
++i)
|
||||||
{
|
{
|
||||||
int index = *i;
|
int index = *i;
|
||||||
assert(index < m_piece_map.size());
|
assert(index < (int)m_piece_map.size());
|
||||||
assert(m_piece_map[index].index == 0xffffff);
|
assert(m_piece_map[index].index == 0xffffff);
|
||||||
|
|
||||||
int peer_count = m_piece_map[index].peer_count;
|
int peer_count = m_piece_map[index].peer_count;
|
||||||
assert(peer_count == 0);
|
assert(peer_count == 0);
|
||||||
assert(m_piece_info.size() == 2);
|
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);
|
m_piece_info[peer_count].push_back(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ namespace libtorrent
|
||||||
i != m_piece_map.end();
|
i != m_piece_map.end();
|
||||||
++i)
|
++i)
|
||||||
{
|
{
|
||||||
int index = i - m_piece_map.begin();
|
int index = static_cast<int>(i - m_piece_map.begin());
|
||||||
|
|
||||||
if (t != 0)
|
if (t != 0)
|
||||||
{
|
{
|
||||||
|
@ -249,8 +249,8 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
std::vector<std::vector<int> >& src_vec = (downloading)?m_downloading_piece_info:m_piece_info;
|
std::vector<std::vector<int> >& src_vec = (downloading)?m_downloading_piece_info:m_piece_info;
|
||||||
|
|
||||||
assert(src_vec.size() > peer_count);
|
assert((int)src_vec.size() > peer_count);
|
||||||
assert(src_vec[peer_count].size() > elem_index);
|
assert((int)src_vec[peer_count].size() > elem_index);
|
||||||
|
|
||||||
int index = src_vec[peer_count][elem_index];
|
int index = src_vec[peer_count][elem_index];
|
||||||
// update the piece_map
|
// update the piece_map
|
||||||
|
@ -266,7 +266,7 @@ namespace libtorrent
|
||||||
assert(dst_vec.size() > p.peer_count);
|
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);
|
dst_vec[p.peer_count].push_back(index);
|
||||||
assert(p.index < dst_vec[p.peer_count].size());
|
assert(p.index < dst_vec[p.peer_count].size());
|
||||||
assert(dst_vec[p.peer_count][p.index] == index);
|
assert(dst_vec[p.peer_count][p.index] == index);
|
||||||
|
@ -279,7 +279,7 @@ namespace libtorrent
|
||||||
// update the entry we moved from the back
|
// update the entry we moved from the back
|
||||||
m_piece_map[replace_index].index = elem_index;
|
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].peer_count == peer_count);
|
||||||
assert(m_piece_map[replace_index].index == elem_index);
|
assert(m_piece_map[replace_index].index == elem_index);
|
||||||
assert(src_vec[peer_count][elem_index] == replace_index);
|
assert(src_vec[peer_count][elem_index] == replace_index);
|
||||||
|
@ -297,8 +297,8 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
std::vector<std::vector<int> >& src_vec = (downloading)?m_downloading_piece_info:m_piece_info;
|
std::vector<std::vector<int> >& src_vec = (downloading)?m_downloading_piece_info:m_piece_info;
|
||||||
|
|
||||||
assert(src_vec.size() > peer_count);
|
assert((int)src_vec.size() > peer_count);
|
||||||
assert(src_vec[peer_count].size() > elem_index);
|
assert((int)src_vec[peer_count].size() > elem_index);
|
||||||
|
|
||||||
int index = src_vec[peer_count][elem_index];
|
int index = src_vec[peer_count][elem_index];
|
||||||
m_piece_map[index].index = 0xffffff;
|
m_piece_map[index].index = 0xffffff;
|
||||||
|
@ -318,7 +318,7 @@ namespace libtorrent
|
||||||
// preserving order
|
// preserving order
|
||||||
index = src_vec[peer_count][elem_index] = src_vec[peer_count].back();
|
index = src_vec[peer_count][elem_index] = src_vec[peer_count].back();
|
||||||
// update the entry we moved from the 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;
|
m_piece_map[index].index = elem_index;
|
||||||
src_vec[peer_count].pop_back();
|
src_vec[peer_count].pop_back();
|
||||||
|
|
||||||
|
@ -327,7 +327,7 @@ namespace libtorrent
|
||||||
void piece_picker::restore_piece(int index)
|
void piece_picker::restore_piece(int index)
|
||||||
{
|
{
|
||||||
assert(index >= 0);
|
assert(index >= 0);
|
||||||
assert(index < m_piece_map.size());
|
assert(index < (int)m_piece_map.size());
|
||||||
|
|
||||||
assert(m_piece_map[index].downloading == 1);
|
assert(m_piece_map[index].downloading == 1);
|
||||||
|
|
||||||
|
@ -349,7 +349,7 @@ namespace libtorrent
|
||||||
void piece_picker::inc_refcount(int i)
|
void piece_picker::inc_refcount(int i)
|
||||||
{
|
{
|
||||||
assert(i >= 0);
|
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 peer_count = m_piece_map[i].peer_count;
|
||||||
int index = m_piece_map[i].index;
|
int index = m_piece_map[i].index;
|
||||||
|
@ -371,7 +371,7 @@ namespace libtorrent
|
||||||
void piece_picker::dec_refcount(int i)
|
void piece_picker::dec_refcount(int i)
|
||||||
{
|
{
|
||||||
assert(i >= 0);
|
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 peer_count = m_piece_map[i].peer_count;
|
||||||
int index = m_piece_map[i].index;
|
int index = m_piece_map[i].index;
|
||||||
|
@ -385,7 +385,7 @@ namespace libtorrent
|
||||||
|
|
||||||
void piece_picker::we_have(int index)
|
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 info_index = m_piece_map[index].index;
|
||||||
int peer_count = m_piece_map[index].peer_count;
|
int peer_count = m_piece_map[index].peer_count;
|
||||||
|
|
||||||
|
@ -448,7 +448,7 @@ namespace libtorrent
|
||||||
i != piece_list.end();
|
i != piece_list.end();
|
||||||
++i)
|
++i)
|
||||||
{
|
{
|
||||||
assert(*i < m_piece_map.size());
|
assert(*i < (int)m_piece_map.size());
|
||||||
// if the peer doesn't have the piece
|
// if the peer doesn't have the piece
|
||||||
// skip it
|
// skip it
|
||||||
if (!pieces[*i]) continue;
|
if (!pieces[*i]) continue;
|
||||||
|
@ -496,14 +496,14 @@ namespace libtorrent
|
||||||
|
|
||||||
bool piece_picker::is_piece_finished(int index) const
|
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);
|
assert(index >= 0);
|
||||||
|
|
||||||
if (m_piece_map[index].downloading == 0) return false;
|
if (m_piece_map[index].downloading == 0) return false;
|
||||||
std::vector<downloading_piece>::const_iterator i
|
std::vector<downloading_piece>::const_iterator i
|
||||||
= std::find_if(m_downloads.begin(), m_downloads.end(), has_index(index));
|
= std::find_if(m_downloads.begin(), m_downloads.end(), has_index(index));
|
||||||
assert(i != m_downloads.end());
|
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);
|
int max_blocks = blocks_in_piece(index);
|
||||||
if (i->finished_blocks.count() != max_blocks) return false;
|
if (i->finished_blocks.count() != max_blocks) return false;
|
||||||
|
|
||||||
|
@ -513,7 +513,7 @@ namespace libtorrent
|
||||||
|
|
||||||
bool piece_picker::is_downloading(piece_block block) const
|
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);
|
assert(block.block_index < max_blocks_per_piece);
|
||||||
|
|
||||||
if (m_piece_map[block.piece_index].downloading == 0) return false;
|
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
|
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);
|
assert(block.block_index < max_blocks_per_piece);
|
||||||
|
|
||||||
if (m_piece_map[block.piece_index].index == 0xffffff) return true;
|
if (m_piece_map[block.piece_index].index == 0xffffff) return true;
|
||||||
|
@ -546,7 +546,7 @@ namespace libtorrent
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// integrity_check();
|
// integrity_check();
|
||||||
#endif
|
#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));
|
assert(block.block_index < blocks_in_piece(block.piece_index));
|
||||||
|
|
||||||
piece_pos& p = m_piece_map[block.piece_index];
|
piece_pos& p = m_piece_map[block.piece_index];
|
||||||
|
@ -580,7 +580,7 @@ namespace libtorrent
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// integrity_check();
|
// integrity_check();
|
||||||
#endif
|
#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));
|
assert(block.block_index < blocks_in_piece(block.piece_index));
|
||||||
|
|
||||||
piece_pos& p = m_piece_map[block.piece_index];
|
piece_pos& p = m_piece_map[block.piece_index];
|
||||||
|
@ -675,7 +675,7 @@ namespace libtorrent
|
||||||
// integrity_check();
|
// integrity_check();
|
||||||
#endif
|
#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);
|
assert(block.block_index < max_blocks_per_piece);
|
||||||
|
|
||||||
if (m_piece_map[block.piece_index].downloading == 0)
|
if (m_piece_map[block.piece_index].downloading == 0)
|
||||||
|
@ -716,7 +716,7 @@ namespace libtorrent
|
||||||
i != m_downloads.end();
|
i != m_downloads.end();
|
||||||
++i)
|
++i)
|
||||||
{
|
{
|
||||||
counter += i->finished_blocks.count();
|
counter += (int)i->finished_blocks.count();
|
||||||
}
|
}
|
||||||
return counter;
|
return counter;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,16 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/policy.hpp"
|
#include "libtorrent/policy.hpp"
|
||||||
#include "libtorrent/torrent.hpp"
|
#include "libtorrent/torrent.hpp"
|
||||||
#include "libtorrent/socket.hpp"
|
#include "libtorrent/socket.hpp"
|
||||||
|
@ -99,7 +107,7 @@ namespace
|
||||||
|
|
||||||
assert(desired_queue_size >= min_request_queue);
|
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
|
// if our request queue is already full, we
|
||||||
// don't have to make any new requests yet
|
// 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 start
|
||||||
, torrent::peer_iterator end)
|
, torrent::peer_iterator end)
|
||||||
{
|
{
|
||||||
int accumulator = 0;
|
size_type accumulator = 0;
|
||||||
for (torrent::peer_iterator i = start; i != end; ++i)
|
for (torrent::peer_iterator i = start; i != end; ++i)
|
||||||
{
|
{
|
||||||
// if the peer is interested in us, it means it may
|
// if the peer is interested in us, it means it may
|
||||||
// want to trade it's surplus uploads for downloads itself
|
// want to trade it's surplus uploads for downloads itself
|
||||||
// (and we should consider it free). If the share diff is
|
// (and we should consider it free). If the share diff is
|
||||||
// negative, there's no free download to get from this peer.
|
// 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)
|
if (i->second->is_peer_interested() || diff <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -214,14 +222,14 @@ namespace
|
||||||
|
|
||||||
// returns the amount of free upload left after
|
// returns the amount of free upload left after
|
||||||
// it has been distributed to the peers
|
// it has been distributed to the peers
|
||||||
int distribute_free_upload(
|
size_type distribute_free_upload(
|
||||||
torrent::peer_iterator start
|
torrent::peer_iterator start
|
||||||
, torrent::peer_iterator end
|
, torrent::peer_iterator end
|
||||||
, int free_upload)
|
, size_type free_upload)
|
||||||
{
|
{
|
||||||
if (free_upload <= 0) return free_upload;
|
if (free_upload <= 0) return free_upload;
|
||||||
int num_peers = 0;
|
int num_peers = 0;
|
||||||
int total_diff = 0;
|
size_type total_diff = 0;
|
||||||
for (torrent::peer_iterator i = start; i != end; ++i)
|
for (torrent::peer_iterator i = start; i != end; ++i)
|
||||||
{
|
{
|
||||||
total_diff += i->second->share_diff();
|
total_diff += i->second->share_diff();
|
||||||
|
@ -230,7 +238,7 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
if (num_peers == 0) return free_upload;
|
if (num_peers == 0) return free_upload;
|
||||||
int upload_share;
|
size_type upload_share;
|
||||||
if (total_diff >= 0)
|
if (total_diff >= 0)
|
||||||
{
|
{
|
||||||
upload_share = std::min(free_upload, total_diff) / num_peers;
|
upload_share = std::min(free_upload, total_diff) / num_peers;
|
||||||
|
@ -295,7 +303,7 @@ namespace libtorrent
|
||||||
policy::peer* policy::find_choke_candidate()
|
policy::peer* policy::find_choke_candidate()
|
||||||
{
|
{
|
||||||
peer* worst_peer = 0;
|
peer* worst_peer = 0;
|
||||||
int min_weight = std::numeric_limits<int>::max();
|
size_type min_weight = std::numeric_limits<int>::max();
|
||||||
|
|
||||||
// TODO: make this selection better
|
// TODO: make this selection better
|
||||||
|
|
||||||
|
@ -311,10 +319,10 @@ namespace libtorrent
|
||||||
if (!c->is_peer_interested())
|
if (!c->is_peer_interested())
|
||||||
return &(*i);
|
return &(*i);
|
||||||
|
|
||||||
int diff = i->total_download()
|
size_type diff = i->total_download()
|
||||||
- i->total_upload();
|
- i->total_upload();
|
||||||
|
|
||||||
int weight = static_cast<int>(c->statistics().download_rate() * 10.f)
|
size_type weight = static_cast<int>(c->statistics().download_rate() * 10.f)
|
||||||
+ diff
|
+ diff
|
||||||
+ (c->has_peer_choked()?-10:10)*1024;
|
+ (c->has_peer_choked()?-10:10)*1024;
|
||||||
|
|
||||||
|
@ -367,11 +375,10 @@ namespace libtorrent
|
||||||
policy::peer* policy::find_disconnect_candidate()
|
policy::peer* policy::find_disconnect_candidate()
|
||||||
{
|
{
|
||||||
peer *disconnect_peer = 0;
|
peer *disconnect_peer = 0;
|
||||||
double slowest_transfer_rate=std::numeric_limits<double>::max();
|
double slowest_transfer_rate = std::numeric_limits<double>::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<peer>::iterator i = m_peers.begin();
|
for (std::vector<peer>::iterator i = m_peers.begin();
|
||||||
i != m_peers.end();
|
i != m_peers.end();
|
||||||
|
@ -383,24 +390,24 @@ namespace libtorrent
|
||||||
if(c->is_disconnecting())
|
if(c->is_disconnecting())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
double transferred_amount;
|
double transferred_amount
|
||||||
|
= (double)c->statistics().total_payload_download();
|
||||||
|
|
||||||
if(is_seed)
|
boost::posix_time::time_duration connected_time
|
||||||
transferred_amount=c->statistics().total_payload_download();
|
= local_time - i->connected;
|
||||||
else
|
|
||||||
transferred_amount=c->statistics().total_payload_download();
|
|
||||||
|
|
||||||
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 transfer_rate
|
||||||
double connected_time_in_seconds=connected_time.seconds() + connected_time.minutes()*60.0 + connected_time.hours()*60.0*60.0;
|
= transferred_amount / (connected_time_in_seconds+1);
|
||||||
|
|
||||||
double transfer_rate=transferred_amount/(connected_time_in_seconds+1);
|
|
||||||
|
|
||||||
if (transfer_rate <= slowest_transfer_rate)
|
if (transfer_rate <= slowest_transfer_rate)
|
||||||
{
|
{
|
||||||
slowest_transfer_rate=transfer_rate;
|
slowest_transfer_rate = transfer_rate;
|
||||||
disconnect_peer=&*i;
|
disconnect_peer = &(*i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return disconnect_peer;
|
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 local_time=boost::posix_time::second_clock::local_time();
|
||||||
boost::posix_time::ptime ptime(local_time);
|
boost::posix_time::ptime ptime(local_time);
|
||||||
policy::peer *candidate=0;
|
policy::peer* candidate =0;
|
||||||
|
|
||||||
for (std::vector<peer>::iterator i = m_peers.begin();
|
for (std::vector<peer>::iterator i = m_peers.begin();
|
||||||
i != m_peers.end();
|
i != m_peers.end();
|
||||||
|
@ -422,12 +429,13 @@ namespace libtorrent
|
||||||
|
|
||||||
assert(i->connected <= local_time);
|
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)
|
if (next_connect <= ptime)
|
||||||
{
|
{
|
||||||
ptime=next_connect;
|
ptime = next_connect;
|
||||||
candidate=&*i;
|
candidate = &(*i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,7 +565,7 @@ namespace libtorrent
|
||||||
peer_connection* c = i->connection;
|
peer_connection* c = i->connection;
|
||||||
if (c == 0) continue;
|
if (c == 0) continue;
|
||||||
|
|
||||||
int diff = i->connection->share_diff();
|
size_type diff = i->connection->share_diff();
|
||||||
if (diff < -free_upload_amount
|
if (diff < -free_upload_amount
|
||||||
&& !c->is_choked())
|
&& !c->is_choked())
|
||||||
{
|
{
|
||||||
|
@ -796,7 +804,7 @@ namespace libtorrent
|
||||||
if (m_torrent->ratio() != 0.f)
|
if (m_torrent->ratio() != 0.f)
|
||||||
{
|
{
|
||||||
assert(c.share_diff() < std::numeric_limits<int>::max());
|
assert(c.share_diff() < std::numeric_limits<int>::max());
|
||||||
int diff = c.share_diff();
|
size_type diff = c.share_diff();
|
||||||
if (diff > 0 && c.is_seed())
|
if (diff > 0 && c.is_seed())
|
||||||
{
|
{
|
||||||
// the peer is a seed and has sent
|
// the peer is a seed and has sent
|
||||||
|
|
|
@ -40,12 +40,20 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/filesystem/convenience.hpp>
|
#include <boost/filesystem/convenience.hpp>
|
||||||
#include <boost/filesystem/exception.hpp>
|
#include <boost/filesystem/exception.hpp>
|
||||||
#include <boost/limits.hpp>
|
#include <boost/limits.hpp>
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/peer_id.hpp"
|
#include "libtorrent/peer_id.hpp"
|
||||||
#include "libtorrent/torrent_info.hpp"
|
#include "libtorrent/torrent_info.hpp"
|
||||||
#include "libtorrent/url_handler.hpp"
|
#include "libtorrent/url_handler.hpp"
|
||||||
|
@ -56,6 +64,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/fingerprint.hpp"
|
#include "libtorrent/fingerprint.hpp"
|
||||||
#include "libtorrent/entry.hpp"
|
#include "libtorrent/entry.hpp"
|
||||||
#include "libtorrent/alert_types.hpp"
|
#include "libtorrent/alert_types.hpp"
|
||||||
|
#include "libtorrent/invariant_check.hpp"
|
||||||
|
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1300
|
#if defined(_MSC_VER) && _MSC_VER < 1300
|
||||||
namespace std
|
namespace std
|
||||||
|
@ -208,7 +217,7 @@ namespace
|
||||||
// Rounds upwards to avoid trying to give 0 bandwidth to someone
|
// Rounds upwards to avoid trying to give 0 bandwidth to someone
|
||||||
// (may get caught in an endless loop otherwise)
|
// (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
|
int try_to_give_to_this_peer
|
||||||
= (quota_left_to_distribute + num_peers_left_to_share_quota - 1)
|
= (quota_left_to_distribute + num_peers_left_to_share_quota - 1)
|
||||||
/ num_peers_left_to_share_quota;
|
/ num_peers_left_to_share_quota;
|
||||||
|
@ -359,7 +368,7 @@ namespace libtorrent
|
||||||
|
|
||||||
// ---- generate a peer id ----
|
// ---- generate a peer id ----
|
||||||
|
|
||||||
std::srand(std::time(0));
|
std::srand((unsigned int)std::time(0));
|
||||||
|
|
||||||
std::string print = cl_fprint.to_string();
|
std::string print = cl_fprint.to_string();
|
||||||
assert(print.length() == 8);
|
assert(print.length() == 8);
|
||||||
|
@ -438,7 +447,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
assert_invariant("loops_per_second++");
|
check_invariant("loops_per_second++");
|
||||||
loops_per_second++;
|
loops_per_second++;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -479,7 +488,7 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
assert_invariant("before SEND SOCKETS");
|
check_invariant("before SEND SOCKETS");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ************************
|
// ************************
|
||||||
|
@ -527,7 +536,7 @@ namespace libtorrent
|
||||||
purge_connections();
|
purge_connections();
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
assert_invariant("after SEND SOCKETS");
|
check_invariant("after SEND SOCKETS");
|
||||||
#endif
|
#endif
|
||||||
// ************************
|
// ************************
|
||||||
// RECEIVE SOCKETS
|
// RECEIVE SOCKETS
|
||||||
|
@ -591,7 +600,7 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
purge_connections();
|
purge_connections();
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
assert_invariant("after RECEIVE SOCKETS");
|
check_invariant("after RECEIVE SOCKETS");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ************************
|
// ************************
|
||||||
|
@ -623,7 +632,7 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
assert_invariant("after ERROR SOCKETS");
|
check_invariant("after ERROR SOCKETS");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
boost::posix_time::time_duration d = boost::posix_time::second_clock::local_time() - timer;
|
boost::posix_time::time_duration d = boost::posix_time::second_clock::local_time() - timer;
|
||||||
|
@ -751,7 +760,7 @@ namespace libtorrent
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
void session_impl::assert_invariant(const char *place)
|
void session_impl::check_invariant(const char *place)
|
||||||
{
|
{
|
||||||
assert(place);
|
assert(place);
|
||||||
|
|
||||||
|
@ -763,7 +772,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
std::ofstream error_log("error.log", std::ios_base::app);
|
std::ofstream error_log("error.log", std::ios_base::app);
|
||||||
boost::shared_ptr<peer_connection> p = i->second;
|
boost::shared_ptr<peer_connection> 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";
|
"peer_connection::has_data() != is_writability_monitored()\n";
|
||||||
error_log << "peer_connection::has_data() " << p->has_data() << "\n";
|
error_log << "peer_connection::has_data() " << p->has_data() << "\n";
|
||||||
error_log << "peer_connection::send_quota_left " << p->send_quota_left() << "\n";
|
error_log << "peer_connection::send_quota_left " << p->send_quota_left() << "\n";
|
||||||
|
@ -982,7 +991,9 @@ namespace libtorrent
|
||||||
i != peer_list.end();
|
i != peer_list.end();
|
||||||
++i)
|
++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);
|
tmp_peers.push_back(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1001,14 +1012,14 @@ namespace libtorrent
|
||||||
i != slots.end();
|
i != slots.end();
|
||||||
++i)
|
++i)
|
||||||
{
|
{
|
||||||
int index = i->integer();
|
int index = (int)i->integer();
|
||||||
if (index >= info.num_pieces() || index < -2)
|
if (index >= info.num_pieces() || index < -2)
|
||||||
return;
|
return;
|
||||||
tmp_pieces.push_back(index);
|
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())
|
if (num_blocks_per_piece != info.piece_length() / torrent_ptr->block_size())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1024,7 +1035,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
piece_picker::downloading_piece p;
|
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())
|
if (p.index < 0 || p.index >= info.num_pieces())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1055,7 +1066,7 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(*slot_iter == p.index);
|
assert(*slot_iter == p.index);
|
||||||
int slot_index = slot_iter - tmp_pieces.begin();
|
int slot_index = static_cast<int>(slot_iter - tmp_pieces.begin());
|
||||||
unsigned long adler
|
unsigned long adler
|
||||||
= torrent_ptr->filesystem().piece_crc(
|
= torrent_ptr->filesystem().piece_crc(
|
||||||
slot_index
|
slot_index
|
||||||
|
|
|
@ -38,11 +38,14 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
#include "libtorrent/stat.hpp"
|
#include "libtorrent/stat.hpp"
|
||||||
|
#include "libtorrent/invariant_check.hpp"
|
||||||
|
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
|
|
||||||
void libtorrent::stat::second_tick()
|
void libtorrent::stat::second_tick()
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
std::copy(m_download_per_second_history,
|
std::copy(m_download_per_second_history,
|
||||||
m_download_per_second_history+history-1,
|
m_download_per_second_history+history-1,
|
||||||
m_download_per_second_history+1);
|
m_download_per_second_history+1);
|
||||||
|
@ -59,11 +62,11 @@ void libtorrent::stat::second_tick()
|
||||||
m_uploaded_protocol = 0;
|
m_uploaded_protocol = 0;
|
||||||
|
|
||||||
m_mean_download_per_second
|
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_download_per_second_history+history, 0) / history;
|
||||||
|
|
||||||
m_mean_upload_per_second
|
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;
|
m_upload_per_second_history+history, 0) / history;
|
||||||
|
|
||||||
if (m_mean_download_per_second > m_peak_downloaded_per_second)
|
if (m_mean_download_per_second > m_peak_downloaded_per_second)
|
||||||
|
|
415
src/storage.cpp
415
src/storage.cpp
|
@ -38,25 +38,35 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/filesystem/convenience.hpp>
|
#include <boost/filesystem/convenience.hpp>
|
||||||
#include <boost/filesystem/fstream.hpp>
|
#include <boost/filesystem/fstream.hpp>
|
||||||
#include <boost/thread/mutex.hpp>
|
#include <boost/thread/mutex.hpp>
|
||||||
#include <boost/ref.hpp>
|
#include <boost/ref.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/storage.hpp"
|
#include "libtorrent/storage.hpp"
|
||||||
#include "libtorrent/torrent.hpp"
|
#include "libtorrent/torrent.hpp"
|
||||||
#include "libtorrent/hasher.hpp"
|
#include "libtorrent/hasher.hpp"
|
||||||
#include "libtorrent/session.hpp"
|
#include "libtorrent/session.hpp"
|
||||||
#include "libtorrent/peer_id.hpp"
|
#include "libtorrent/peer_id.hpp"
|
||||||
#include "libtorrent/file.hpp"
|
#include "libtorrent/file.hpp"
|
||||||
|
#include "libtorrent/invariant_check.hpp"
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#define for if (false) {} else for
|
#define for if (false) {} else for
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace {
|
/*
|
||||||
|
namespace
|
||||||
|
{
|
||||||
struct lazy_hash
|
struct lazy_hash
|
||||||
{
|
{
|
||||||
mutable libtorrent::sha1_hash digest;
|
mutable libtorrent::sha1_hash digest;
|
||||||
|
@ -85,10 +95,12 @@ namespace {
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace unnamed
|
} // namespace unnamed
|
||||||
|
*/
|
||||||
|
|
||||||
namespace fs = boost::filesystem;
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
namespace {
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
void print_to_log(const std::string& s)
|
void print_to_log(const std::string& s)
|
||||||
{
|
{
|
||||||
|
@ -190,8 +202,9 @@ namespace libtorrent
|
||||||
int slot;
|
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)
|
impl(const torrent_info& info, const fs::path& path)
|
||||||
: thread_safe_storage(info.num_pieces())
|
: thread_safe_storage(info.num_pieces())
|
||||||
, info(info)
|
, info(info)
|
||||||
|
@ -222,10 +235,10 @@ namespace libtorrent
|
||||||
size_type storage::read(
|
size_type storage::read(
|
||||||
char* buf
|
char* buf
|
||||||
, int slot
|
, int slot
|
||||||
, size_type offset
|
, int offset
|
||||||
, size_type size)
|
, int size)
|
||||||
{
|
{
|
||||||
assert(buf);
|
assert(buf != 0);
|
||||||
assert(slot >= 0 && slot < m_pimpl->info.num_pieces());
|
assert(slot >= 0 && slot < m_pimpl->info.num_pieces());
|
||||||
assert(offset >= 0);
|
assert(offset >= 0);
|
||||||
assert(offset < m_pimpl->info.piece_size(slot));
|
assert(offset < m_pimpl->info.piece_size(slot));
|
||||||
|
@ -247,51 +260,53 @@ namespace libtorrent
|
||||||
file_offset -= file_iter->size;
|
file_offset -= file_iter->size;
|
||||||
++file_iter;
|
++file_iter;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
fs::ifstream in(
|
|
||||||
m_pimpl->save_path / file_iter->path / file_iter->filename
|
|
||||||
, std::ios_base::binary
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
file in(
|
file in(
|
||||||
m_pimpl->save_path / file_iter->path / file_iter->filename
|
m_pimpl->save_path / file_iter->path / file_iter->filename
|
||||||
, file::in);
|
, file::in);
|
||||||
|
|
||||||
assert(file_offset < file_iter->size);
|
assert(file_offset < file_iter->size);
|
||||||
|
|
||||||
// in.seekg(file_offset);
|
|
||||||
in.seek(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
|
#ifndef NDEBUG
|
||||||
size_type in_tell = in.tell();
|
size_type in_tell = in.tell();
|
||||||
assert(in_tell == file_offset);
|
assert(in_tell == file_offset);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_type left_to_read = size;
|
int left_to_read = size;
|
||||||
size_type slot_size = m_pimpl->info.piece_size(slot);
|
int slot_size = m_pimpl->info.piece_size(slot);
|
||||||
|
|
||||||
if (offset + left_to_read > slot_size)
|
if (offset + left_to_read > slot_size)
|
||||||
left_to_read = slot_size - offset;
|
left_to_read = slot_size - offset;
|
||||||
|
|
||||||
assert(left_to_read >= 0);
|
assert(left_to_read >= 0);
|
||||||
|
|
||||||
int result = left_to_read;
|
size_type result = left_to_read;
|
||||||
int buf_pos = 0;
|
int buf_pos = 0;
|
||||||
|
|
||||||
while (left_to_read > 0)
|
while (left_to_read > 0)
|
||||||
{
|
{
|
||||||
int read_bytes = left_to_read;
|
int read_bytes = left_to_read;
|
||||||
if (file_offset + read_bytes > file_iter->size)
|
if (file_offset + read_bytes > file_iter->size)
|
||||||
read_bytes = file_iter->size - file_offset;
|
read_bytes = static_cast<int>(file_iter->size - file_offset);
|
||||||
|
|
||||||
assert(read_bytes > 0);
|
assert(read_bytes > 0);
|
||||||
|
|
||||||
// in.read(buf + buf_pos, read_bytes);
|
// in.read(buf + buf_pos, read_bytes);
|
||||||
// int actual_read = in.gcount();
|
// 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;
|
left_to_read -= read_bytes;
|
||||||
buf_pos += 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;
|
fs::path path = m_pimpl->save_path / file_iter->path / file_iter->filename;
|
||||||
|
|
||||||
file_offset = 0;
|
file_offset = 0;
|
||||||
// in.close();
|
|
||||||
// in.clear();
|
|
||||||
// in.open(path, std::ios_base::binary);
|
|
||||||
in.open(path, file::in);
|
in.open(path, file::in);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,10 +326,15 @@ namespace libtorrent
|
||||||
return result;
|
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(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(offset >= 0);
|
||||||
assert(size > 0);
|
assert(size > 0);
|
||||||
|
|
||||||
|
@ -360,8 +377,8 @@ namespace libtorrent
|
||||||
assert(file_offset == out_tell);
|
assert(file_offset == out_tell);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_type left_to_write = size;
|
int left_to_write = size;
|
||||||
size_type slot_size = m_pimpl->info.piece_size(slot);
|
int slot_size = m_pimpl->info.piece_size(slot);
|
||||||
|
|
||||||
if (offset + left_to_write > slot_size)
|
if (offset + left_to_write > slot_size)
|
||||||
left_to_write = slot_size - offset;
|
left_to_write = slot_size - offset;
|
||||||
|
@ -378,7 +395,7 @@ namespace libtorrent
|
||||||
if (file_offset + write_bytes > file_iter->size)
|
if (file_offset + write_bytes > file_iter->size)
|
||||||
{
|
{
|
||||||
assert(file_iter->size > file_offset);
|
assert(file_iter->size > file_offset);
|
||||||
write_bytes = file_iter->size - file_offset;
|
write_bytes = static_cast<int>(file_iter->size - file_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(buf_pos >= 0);
|
assert(buf_pos >= 0);
|
||||||
|
@ -422,6 +439,7 @@ namespace libtorrent
|
||||||
|
|
||||||
class piece_manager::impl
|
class piece_manager::impl
|
||||||
{
|
{
|
||||||
|
friend class invariant_access;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
impl(
|
impl(
|
||||||
|
@ -442,8 +460,17 @@ namespace libtorrent
|
||||||
|
|
||||||
int slot_for_piece(int piece_index) const;
|
int slot_for_piece(int piece_index) const;
|
||||||
|
|
||||||
size_type read(char* buf, int piece_index, size_type offset, size_type size);
|
size_type read(
|
||||||
void write(const char* buf, int piece_index, size_type offset, size_type size);
|
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
|
const boost::filesystem::path& save_path() const
|
||||||
{ return m_save_path; }
|
{ return m_save_path; }
|
||||||
|
@ -454,6 +481,12 @@ namespace libtorrent
|
||||||
// returns the slot currently associated with the given
|
// returns the slot currently associated with the given
|
||||||
// piece or assigns the given piece_index to a free slot
|
// piece or assigns the given piece_index to a free slot
|
||||||
|
|
||||||
|
int identify_data(
|
||||||
|
const std::vector<char>& piece_data
|
||||||
|
, int current_slot
|
||||||
|
, std::vector<bool>& have_pieces
|
||||||
|
, const std::multimap<sha1_hash, int>& hash_to_piece);
|
||||||
|
|
||||||
int allocate_slot_for_piece(int piece_index);
|
int allocate_slot_for_piece(int piece_index);
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
void check_invariant() const;
|
void check_invariant() const;
|
||||||
|
@ -468,24 +501,28 @@ namespace libtorrent
|
||||||
|
|
||||||
const torrent_info& m_info;
|
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<int> m_piece_to_slot;
|
|
||||||
// slots that hasn't had any file storage allocated
|
// slots that hasn't had any file storage allocated
|
||||||
std::vector<int> m_unallocated_slots;
|
std::vector<int> m_unallocated_slots;
|
||||||
// slots that has file storage, but isn't assigned to a piece
|
// slots that has file storage, but isn't assigned to a piece
|
||||||
std::vector<int> m_free_slots;
|
std::vector<int> m_free_slots;
|
||||||
|
|
||||||
// index here is a slot number in the file
|
enum
|
||||||
// if index>=0, the slot is assigned to this piece
|
{
|
||||||
// otherwise it can have one of these values:
|
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<int> m_piece_to_slot;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
unallocated = -1, // the slot is unallocated
|
unallocated = -1, // the slot is unallocated
|
||||||
unassigned = -2 // the slot is allocated but not assigned to a piece
|
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<int> m_slot_to_piece;
|
std::vector<int> m_slot_to_piece;
|
||||||
|
|
||||||
boost::filesystem::path m_save_path;
|
boost::filesystem::path m_save_path;
|
||||||
|
@ -503,6 +540,7 @@ namespace libtorrent
|
||||||
: m_storage(info, save_path)
|
: m_storage(info, save_path)
|
||||||
, m_info(info)
|
, m_info(info)
|
||||||
, m_save_path(save_path)
|
, m_save_path(save_path)
|
||||||
|
, m_allocating(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -644,8 +682,8 @@ namespace libtorrent
|
||||||
size_type piece_manager::impl::read(
|
size_type piece_manager::impl::read(
|
||||||
char* buf
|
char* buf
|
||||||
, int piece_index
|
, int piece_index
|
||||||
, size_type offset
|
, int offset
|
||||||
, size_type size)
|
, int size)
|
||||||
{
|
{
|
||||||
assert(buf);
|
assert(buf);
|
||||||
assert(offset >= 0);
|
assert(offset >= 0);
|
||||||
|
@ -660,8 +698,8 @@ namespace libtorrent
|
||||||
size_type piece_manager::read(
|
size_type piece_manager::read(
|
||||||
char* buf
|
char* buf
|
||||||
, int piece_index
|
, int piece_index
|
||||||
, size_type offset
|
, int offset
|
||||||
, size_type size)
|
, int size)
|
||||||
{
|
{
|
||||||
return m_pimpl->read(buf, piece_index, offset, size);
|
return m_pimpl->read(buf, piece_index, offset, size);
|
||||||
}
|
}
|
||||||
|
@ -669,8 +707,8 @@ namespace libtorrent
|
||||||
void piece_manager::impl::write(
|
void piece_manager::impl::write(
|
||||||
const char* buf
|
const char* buf
|
||||||
, int piece_index
|
, int piece_index
|
||||||
, size_type offset
|
, int offset
|
||||||
, size_type size)
|
, int size)
|
||||||
{
|
{
|
||||||
assert(buf);
|
assert(buf);
|
||||||
assert(offset >= 0);
|
assert(offset >= 0);
|
||||||
|
@ -684,12 +722,12 @@ namespace libtorrent
|
||||||
void piece_manager::write(
|
void piece_manager::write(
|
||||||
const char* buf
|
const char* buf
|
||||||
, int piece_index
|
, int piece_index
|
||||||
, size_type offset
|
, int offset
|
||||||
, size_type size)
|
, int size)
|
||||||
{
|
{
|
||||||
m_pimpl->write(buf, piece_index, offset, size);
|
m_pimpl->write(buf, piece_index, offset, size);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
void piece_manager::impl::check_pieces(
|
void piece_manager::impl::check_pieces(
|
||||||
boost::mutex& mutex
|
boost::mutex& mutex
|
||||||
, detail::piece_checker_data& data
|
, detail::piece_checker_data& data
|
||||||
|
@ -787,7 +825,7 @@ namespace libtorrent
|
||||||
end_iter = m_info.end_files();
|
end_iter = m_info.end_files();
|
||||||
file_iter != end_iter;)
|
file_iter != end_iter;)
|
||||||
{
|
{
|
||||||
assert(current_slot>=0 && current_slot<m_info.num_pieces());
|
assert(current_slot >= 0 && current_slot < m_info.num_pieces());
|
||||||
|
|
||||||
// Update progress meter and check if we've been requested to abort
|
// 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);
|
m_unallocated_slots.push_back(current_slot);
|
||||||
++current_slot;
|
++current_slot;
|
||||||
assert(current_slot <= m_info.num_pieces());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
seek_into_next = pos - file_end;
|
seek_into_next = pos - file_end;
|
||||||
|
if (current_slot >= m_info.num_pieces())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
bytes_to_read = m_info.piece_size(current_slot);
|
bytes_to_read = m_info.piece_size(current_slot);
|
||||||
piece_offset = 0;
|
piece_offset = 0;
|
||||||
}
|
}
|
||||||
|
@ -952,7 +993,7 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
// dirty "fix" for a bug when file is corrupt
|
// 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
|
if(m_piece_to_slot[i] != has_no_slot
|
||||||
&& m_piece_to_slot[i] != i
|
&& m_piece_to_slot[i] != i
|
||||||
|
@ -1000,6 +1041,230 @@ namespace libtorrent
|
||||||
check_invariant();
|
check_invariant();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
int piece_manager::impl::identify_data(
|
||||||
|
const std::vector<char>& piece_data
|
||||||
|
, int current_slot
|
||||||
|
, std::vector<bool>& have_pieces
|
||||||
|
, const std::multimap<sha1_hash, int>& 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<sha1_hash, int>::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<int> 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<int>::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<bool>& 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<char> 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<sha1_hash, int> 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(
|
void piece_manager::check_pieces(
|
||||||
boost::mutex& mutex
|
boost::mutex& mutex
|
||||||
|
@ -1015,9 +1280,7 @@ namespace libtorrent
|
||||||
boost::recursive_mutex::scoped_lock lock(m_mutex);
|
boost::recursive_mutex::scoped_lock lock(m_mutex);
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
#ifndef NDEBUG
|
INVARIANT_CHECK;
|
||||||
check_invariant();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
assert(piece_index >= 0);
|
assert(piece_index >= 0);
|
||||||
assert(piece_index < (int)m_piece_to_slot.size());
|
assert(piece_index < (int)m_piece_to_slot.size());
|
||||||
|
@ -1029,11 +1292,6 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
assert(slot_index >= 0);
|
assert(slot_index >= 0);
|
||||||
assert(slot_index < (int)m_slot_to_piece.size());
|
assert(slot_index < (int)m_slot_to_piece.size());
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
check_invariant();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return slot_index;
|
return slot_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1080,7 +1338,8 @@ namespace libtorrent
|
||||||
if (slot_index != piece_index
|
if (slot_index != piece_index
|
||||||
&& m_slot_to_piece[piece_index] >= 0)
|
&& m_slot_to_piece[piece_index] >= 0)
|
||||||
{
|
{
|
||||||
#ifndef NDEBUG
|
|
||||||
|
#if !defined(NDEBUG) && defined(TORRENT_STORAGE_DEBUG)
|
||||||
std::stringstream s;
|
std::stringstream s;
|
||||||
|
|
||||||
s << "there is another piece at our slot, swapping..";
|
s << "there is another piece at our slot, swapping..";
|
||||||
|
@ -1092,15 +1351,14 @@ namespace libtorrent
|
||||||
s << "\n piece at our slot: ";
|
s << "\n piece at our slot: ";
|
||||||
s << m_slot_to_piece[piece_index];
|
s << m_slot_to_piece[piece_index];
|
||||||
s << "\n";
|
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());
|
print_to_log(s.str());
|
||||||
#ifdef TORRENT_STORAGE_DEBUG
|
|
||||||
debug_log();
|
debug_log();
|
||||||
#endif
|
#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(
|
std::swap(
|
||||||
m_slot_to_piece[piece_index]
|
m_slot_to_piece[piece_index]
|
||||||
, m_slot_to_piece[slot_index]);
|
, m_slot_to_piece[slot_index]);
|
||||||
|
@ -1117,6 +1375,7 @@ namespace libtorrent
|
||||||
assert(m_piece_to_slot[piece_index] == piece_index);
|
assert(m_piece_to_slot[piece_index] == piece_index);
|
||||||
|
|
||||||
slot_index = piece_index;
|
slot_index = piece_index;
|
||||||
|
|
||||||
#if !defined(NDEBUG) && defined(TORRENT_STORAGE_DEBUG)
|
#if !defined(NDEBUG) && defined(TORRENT_STORAGE_DEBUG)
|
||||||
debug_log();
|
debug_log();
|
||||||
#endif
|
#endif
|
||||||
|
@ -1124,16 +1383,12 @@ namespace libtorrent
|
||||||
|
|
||||||
assert(slot_index >= 0);
|
assert(slot_index >= 0);
|
||||||
assert(slot_index < (int)m_slot_to_piece.size());
|
assert(slot_index < (int)m_slot_to_piece.size());
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
check_invariant();
|
|
||||||
#endif
|
|
||||||
return slot_index;
|
return slot_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void piece_manager::impl::allocate_slots(int num_slots)
|
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);
|
boost::mutex::scoped_lock lock(m_allocating_monitor);
|
||||||
|
@ -1148,9 +1403,7 @@ namespace libtorrent
|
||||||
boost::recursive_mutex::scoped_lock lock(m_mutex);
|
boost::recursive_mutex::scoped_lock lock(m_mutex);
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
#ifndef NDEBUG
|
INVARIANT_CHECK;
|
||||||
check_invariant();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace fs = boost::filesystem;
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
|
@ -1159,7 +1412,7 @@ namespace libtorrent
|
||||||
std::vector<int>::iterator end_iter
|
std::vector<int>::iterator end_iter
|
||||||
= m_unallocated_slots.end();
|
= m_unallocated_slots.end();
|
||||||
|
|
||||||
const size_type piece_size = m_info.piece_length();
|
const int piece_size = m_info.piece_length();
|
||||||
|
|
||||||
std::vector<char> zeros(piece_size, 0);
|
std::vector<char> zeros(piece_size, 0);
|
||||||
|
|
||||||
|
@ -1185,7 +1438,15 @@ namespace libtorrent
|
||||||
m_slot_to_piece[new_free_slot] = unassigned;
|
m_slot_to_piece[new_free_slot] = unassigned;
|
||||||
m_free_slots.push_back(new_free_slot);
|
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);
|
m_unallocated_slots.erase(m_unallocated_slots.begin(), iter);
|
||||||
|
@ -1193,10 +1454,6 @@ namespace libtorrent
|
||||||
m_allocating = false;
|
m_allocating = false;
|
||||||
|
|
||||||
assert(m_free_slots.size()>0);
|
assert(m_free_slots.size()>0);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
check_invariant();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void piece_manager::allocate_slots(int num_slots)
|
void piece_manager::allocate_slots(int num_slots)
|
||||||
|
|
|
@ -39,9 +39,17 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/filesystem/convenience.hpp>
|
#include <boost/filesystem/convenience.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/torrent_handle.hpp"
|
#include "libtorrent/torrent_handle.hpp"
|
||||||
#include "libtorrent/session.hpp"
|
#include "libtorrent/session.hpp"
|
||||||
#include "libtorrent/torrent_info.hpp"
|
#include "libtorrent/torrent_info.hpp"
|
||||||
|
@ -219,7 +227,7 @@ namespace libtorrent
|
||||||
, m_policy(new policy(this))
|
, m_policy(new policy(this))
|
||||||
, m_ses(ses)
|
, m_ses(ses)
|
||||||
, m_picker(torrent_file.piece_length() / m_block_size,
|
, m_picker(torrent_file.piece_length() / m_block_size,
|
||||||
(torrent_file.total_size()+m_block_size-1)/m_block_size)
|
static_cast<int>((torrent_file.total_size()+m_block_size-1)/m_block_size))
|
||||||
, m_last_working_tracker(0)
|
, m_last_working_tracker(0)
|
||||||
, m_currently_trying_tracker(0)
|
, m_currently_trying_tracker(0)
|
||||||
, m_time_scaler(0)
|
, m_time_scaler(0)
|
||||||
|
@ -493,7 +501,7 @@ namespace libtorrent
|
||||||
i != pieces.end();
|
i != pieces.end();
|
||||||
++i)
|
++i)
|
||||||
{
|
{
|
||||||
if (*i) piece_list.push_back(i - pieces.begin());
|
if (*i) piece_list.push_back(static_cast<int>(i - pieces.begin()));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::random_shuffle(piece_list.begin(), piece_list.end());
|
std::random_shuffle(piece_list.begin(), piece_list.end());
|
||||||
|
@ -677,7 +685,7 @@ namespace libtorrent
|
||||||
assert(piece_index >= 0);
|
assert(piece_index >= 0);
|
||||||
assert(piece_index < m_torrent_file.num_pieces());
|
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<char> buffer(size);
|
std::vector<char> buffer(size);
|
||||||
assert(size > 0);
|
assert(size > 0);
|
||||||
m_storage.read(&buffer[0], piece_index, 0, size);
|
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.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;
|
st.pieces = &m_have_pieces;
|
||||||
|
|
||||||
|
|
|
@ -40,10 +40,18 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/filesystem/convenience.hpp>
|
#include <boost/filesystem/convenience.hpp>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/peer_id.hpp"
|
#include "libtorrent/peer_id.hpp"
|
||||||
#include "libtorrent/torrent_info.hpp"
|
#include "libtorrent/torrent_info.hpp"
|
||||||
#include "libtorrent/url_handler.hpp"
|
#include "libtorrent/url_handler.hpp"
|
||||||
|
@ -233,7 +241,7 @@ namespace libtorrent
|
||||||
ret.dict()["blocks per piece"] = num_blocks_per_piece;
|
ret.dict()["blocks per piece"] = num_blocks_per_piece;
|
||||||
|
|
||||||
// num unfinished pieces
|
// num unfinished pieces
|
||||||
int num_unfinished = q.size();
|
int num_unfinished = (int)q.size();
|
||||||
ret.dict()["unfinished"] = entry::list_type();
|
ret.dict()["unfinished"] = entry::list_type();
|
||||||
entry::list_type& up = ret.dict()["unfinished"].list();
|
entry::list_type& up = ret.dict()["unfinished"].list();
|
||||||
|
|
||||||
|
@ -436,8 +444,8 @@ namespace libtorrent
|
||||||
|
|
||||||
p.load_balancing = peer->total_free_upload();
|
p.load_balancing = peer->total_free_upload();
|
||||||
|
|
||||||
p.download_queue_length = peer->download_queue().size();
|
p.download_queue_length = (int)peer->download_queue().size();
|
||||||
p.upload_queue_length = peer->upload_queue().size();
|
p.upload_queue_length = (int)peer->upload_queue().size();
|
||||||
|
|
||||||
boost::optional<piece_block_progress> ret = peer->downloading_piece();
|
boost::optional<piece_block_progress> ret = peer->downloading_piece();
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -38,9 +38,17 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/date_time/time.hpp>
|
#include <boost/date_time/time.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/torrent_info.hpp"
|
#include "libtorrent/torrent_info.hpp"
|
||||||
#include "libtorrent/bencode.hpp"
|
#include "libtorrent/bencode.hpp"
|
||||||
#include "libtorrent/hasher.hpp"
|
#include "libtorrent/hasher.hpp"
|
||||||
|
@ -135,7 +143,9 @@ namespace libtorrent
|
||||||
i = dict.find("creation date");
|
i = dict.find("creation date");
|
||||||
if (i != dict.end() && i->second.type() == entry::int_t)
|
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
|
// extract comment
|
||||||
|
@ -153,7 +163,7 @@ namespace libtorrent
|
||||||
std::vector<char> buf;
|
std::vector<char> buf;
|
||||||
bencode(std::back_insert_iterator<std::vector<char> >(buf), info);
|
bencode(std::back_insert_iterator<std::vector<char> >(buf), info);
|
||||||
hasher h;
|
hasher h;
|
||||||
h.update(&buf[0], buf.size());
|
h.update(&buf[0], (int)buf.size());
|
||||||
m_info_hash = h.final();
|
m_info_hash = h.final();
|
||||||
|
|
||||||
// extract piece length
|
// extract piece length
|
||||||
|
@ -192,7 +202,7 @@ namespace libtorrent
|
||||||
// extract sha-1 hashes for all pieces
|
// extract sha-1 hashes for all pieces
|
||||||
// we want this division to round upwards, that's why we have the
|
// we want this division to round upwards, that's why we have the
|
||||||
// extra addition
|
// extra addition
|
||||||
size_type num_pieces = (m_total_size + m_piece_length - 1) / m_piece_length;
|
int num_pieces = static_cast<int>((m_total_size + m_piece_length - 1) / m_piece_length);
|
||||||
i = info.dict().find("pieces");
|
i = info.dict().find("pieces");
|
||||||
if (i == info.dict().end()) throw invalid_torrent_file();
|
if (i == info.dict().end()) throw invalid_torrent_file();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue