added a setting for max outstanding requests, and a limit for BitComet since it's known to have a very low limit, also added an extension header to specify it. Fixed another unnecessary delay spotted by Tianhao Qiu. Cleaned up the logging class a bit. Fixed a bug that would cause an assert when removing a torrent queued for checking.

This commit is contained in:
Arvid Norberg 2006-05-14 22:30:05 +00:00
parent 73b1c5c9b8
commit 0b529e8f96
18 changed files with 318 additions and 124 deletions

View File

@ -3,10 +3,130 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.3.9: http://docutils.sourceforge.net/" />
<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
<title></title>
<meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com Ludvig Strigeus, ludde&#64;utorrent.com" />
<link rel="stylesheet" href="style.css" type="text/css" />
<style type="text/css">
body
{
background-color: white;
color: black;
margin: 1em 2em 1em 2em;
}
h1 { font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold; text-align: left; font-size: 140%; }
h2 { font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold; text-align: left; font-size: 110%; }
h3 { font-family: "courier new", courier, monospace; font-weight: bold; text-align: left; font-size: 100%; }
pre
{
border: gray 1pt solid;
padding: 2pt;
display: block;
font-family: "courier new", courier, monospace;
background-color: #eeeeee;
color: black;
font-size: small
}
code
{
white-space: pre;
border: gray 1pt solid;
padding: 2pt;
display: block;
font-family: "courier new", courier, monospace;
color: black;
font-size: small
}
tt
{
display: inline;
font-family: "Courier New", Courier, monospace;
}
p
{
text-align: justify;
font-family: Georgia, "Times New Roman", Times, serif
}
ul
{
font-family: Georgia, "Times New Roman", Times, serif
}
ol
{
font-family: Georgia, "Times New Roman", Times, serif
}
a:link
{
font-weight: bold;
color: #003366;
text-decoration: none;
}
a:visited
{
font-weight: bold;
color: #003366;
text-decoration: none;
}
table
{
border: 1px solid black;
border-collapse: collapse;
}
table td
{
padding: 6px;
}
table th
{
border: 3px solid black;
padding: 6px;
}
table.menu
{
border-style: none;
}
table.menu td
{
padding-left: 15px;
padding-right: 15px;
padding-top: 7px;
padding-bottom: 7px;
}
td
{
border: 1px solid black
}
div.warning, div.note, div.important {
width: 80%;
margin: 1.5em auto;
background: #C1E5F6;
background: #F1FFF5;
border: solid 1px #D1DFD5;
padding: 5px 10px 5px 10px;
}
</style>
</head>
<body>
<div class="document">
@ -19,8 +139,8 @@
Ludvig Strigeus, <a class="last reference" href="mailto:ludde&#64;utorrent.com">ludde&#64;utorrent.com</a></td></tr>
</tbody>
</table>
<div class="section" id="extension-protocol-for-bittorrent">
<h1><a name="extension-protocol-for-bittorrent">extension protocol for bittorrent</a></h1>
<div class="section">
<h1><a id="extension-protocol-for-bittorrent" name="extension-protocol-for-bittorrent">extension protocol for bittorrent</a></h1>
<p>The intention of this protocol is to provide a simple and thin transport
for extensions to the bittorrent protocol. Supporting this protocol makes
it easy to add new extensions without interfering with the standard
@ -88,8 +208,8 @@ message as specified by the handshake.</td>
</tr>
</tbody>
</table>
<div class="section" id="handshake-message">
<h2><a name="handshake-message">handshake message</a></h2>
<div class="section">
<h2><a id="handshake-message" name="handshake-message">handshake message</a></h2>
<p>The payload of the handshake message is a bencoded dictionary. All items
in the dictionary are optional. Any unknown names should be ignored
by the client. All parts of the dictionary are case sensitive.
@ -140,6 +260,11 @@ known.</td>
This is a much more reliable way of identifying the
client than relying on the peer id encoding.</td>
</tr>
<tr><td>reqq</td>
<td>An integer, the number of outstanding request messages
this client supports without dropping any. The default in
in libtorrent is 250.</td>
</tr>
</tbody>
</table>
<p>The handshake dictionary could also include extended handshake
@ -214,8 +339,8 @@ for the actual extensions to the bittorrent protocol and the extensions
named in the example above (such as <tt class="docutils literal"><span class="pre">p</span></tt>) are just examples of possible
extensions.</p>
</div>
<div class="section" id="rationale">
<h2><a name="rationale">rationale</a></h2>
<div class="section">
<h2><a id="rationale" name="rationale">rationale</a></h2>
<p>The reason why the extension messages' IDs would be defined in the handshake
is to avoid having a global registry somewhere, where ID's are assigned
global identifiers. Now the extensions have unique names.</p>

View File

@ -87,6 +87,10 @@ Here are two other items that an implementation may choose to support:
| | This is a much more reliable way of identifying the |
| | client than relying on the peer id encoding. |
+-------+-----------------------------------------------------------+
| reqq | An integer, the number of outstanding request messages |
| | this client supports without dropping any. The default in |
| | in libtorrent is 250. |
+-------+-----------------------------------------------------------+
The handshake dictionary could also include extended handshake
information, such as support for encrypted headers or anything

View File

@ -229,60 +229,61 @@ div.warning, div.note, div.important {
<li><a class="reference" href="#fingerprint" id="id96" name="id96">fingerprint</a></li>
<li><a class="reference" href="#free-functions" id="id97" name="id97">free functions</a><ul>
<li><a class="reference" href="#identify-client" id="id98" name="id98">identify_client()</a></li>
<li><a class="reference" href="#bdecode-bencode" id="id99" name="id99">bdecode() bencode()</a></li>
<li><a class="reference" href="#client-fingerprint" id="id99" name="id99">client_fingerprint()</a></li>
<li><a class="reference" href="#bdecode-bencode" id="id100" name="id100">bdecode() bencode()</a></li>
</ul>
</li>
<li><a class="reference" href="#alerts" id="id100" name="id100">alerts</a><ul>
<li><a class="reference" href="#listen-failed-alert" id="id101" name="id101">listen_failed_alert</a></li>
<li><a class="reference" href="#file-error-alert" id="id102" name="id102">file_error_alert</a></li>
<li><a class="reference" href="#tracker-announce-alert" id="id103" name="id103">tracker_announce_alert</a></li>
<li><a class="reference" href="#tracker-alert" id="id104" name="id104">tracker_alert</a></li>
<li><a class="reference" href="#tracker-reply-alert" id="id105" name="id105">tracker_reply_alert</a></li>
<li><a class="reference" href="#tracker-warning-alert" id="id106" name="id106">tracker_warning_alert</a></li>
<li><a class="reference" href="#url-seed-alert" id="id107" name="id107">url_seed_alert</a></li>
<li><a class="reference" href="#hash-failed-alert" id="id108" name="id108">hash_failed_alert</a></li>
<li><a class="reference" href="#peer-ban-alert" id="id109" name="id109">peer_ban_alert</a></li>
<li><a class="reference" href="#peer-error-alert" id="id110" name="id110">peer_error_alert</a></li>
<li><a class="reference" href="#invalid-request-alert" id="id111" name="id111">invalid_request_alert</a></li>
<li><a class="reference" href="#torrent-finished-alert" id="id112" name="id112">torrent_finished_alert</a></li>
<li><a class="reference" href="#metadata-failed-alert" id="id113" name="id113">metadata_failed_alert</a></li>
<li><a class="reference" href="#metadata-received-alert" id="id114" name="id114">metadata_received_alert</a></li>
<li><a class="reference" href="#fastresume-rejected-alert" id="id115" name="id115">fastresume_rejected_alert</a></li>
<li><a class="reference" href="#dispatcher" id="id116" name="id116">dispatcher</a></li>
<li><a class="reference" href="#alerts" id="id101" name="id101">alerts</a><ul>
<li><a class="reference" href="#listen-failed-alert" id="id102" name="id102">listen_failed_alert</a></li>
<li><a class="reference" href="#file-error-alert" id="id103" name="id103">file_error_alert</a></li>
<li><a class="reference" href="#tracker-announce-alert" id="id104" name="id104">tracker_announce_alert</a></li>
<li><a class="reference" href="#tracker-alert" id="id105" name="id105">tracker_alert</a></li>
<li><a class="reference" href="#tracker-reply-alert" id="id106" name="id106">tracker_reply_alert</a></li>
<li><a class="reference" href="#tracker-warning-alert" id="id107" name="id107">tracker_warning_alert</a></li>
<li><a class="reference" href="#url-seed-alert" id="id108" name="id108">url_seed_alert</a></li>
<li><a class="reference" href="#hash-failed-alert" id="id109" name="id109">hash_failed_alert</a></li>
<li><a class="reference" href="#peer-ban-alert" id="id110" name="id110">peer_ban_alert</a></li>
<li><a class="reference" href="#peer-error-alert" id="id111" name="id111">peer_error_alert</a></li>
<li><a class="reference" href="#invalid-request-alert" id="id112" name="id112">invalid_request_alert</a></li>
<li><a class="reference" href="#torrent-finished-alert" id="id113" name="id113">torrent_finished_alert</a></li>
<li><a class="reference" href="#metadata-failed-alert" id="id114" name="id114">metadata_failed_alert</a></li>
<li><a class="reference" href="#metadata-received-alert" id="id115" name="id115">metadata_received_alert</a></li>
<li><a class="reference" href="#fastresume-rejected-alert" id="id116" name="id116">fastresume_rejected_alert</a></li>
<li><a class="reference" href="#dispatcher" id="id117" name="id117">dispatcher</a></li>
</ul>
</li>
<li><a class="reference" href="#exceptions" id="id117" name="id117">exceptions</a><ul>
<li><a class="reference" href="#invalid-handle" id="id118" name="id118">invalid_handle</a></li>
<li><a class="reference" href="#duplicate-torrent" id="id119" name="id119">duplicate_torrent</a></li>
<li><a class="reference" href="#invalid-encoding" id="id120" name="id120">invalid_encoding</a></li>
<li><a class="reference" href="#type-error" id="id121" name="id121">type_error</a></li>
<li><a class="reference" href="#invalid-torrent-file" id="id122" name="id122">invalid_torrent_file</a></li>
<li><a class="reference" href="#exceptions" id="id118" name="id118">exceptions</a><ul>
<li><a class="reference" href="#invalid-handle" id="id119" name="id119">invalid_handle</a></li>
<li><a class="reference" href="#duplicate-torrent" id="id120" name="id120">duplicate_torrent</a></li>
<li><a class="reference" href="#invalid-encoding" id="id121" name="id121">invalid_encoding</a></li>
<li><a class="reference" href="#type-error" id="id122" name="id122">type_error</a></li>
<li><a class="reference" href="#invalid-torrent-file" id="id123" name="id123">invalid_torrent_file</a></li>
</ul>
</li>
<li><a class="reference" href="#examples" id="id123" name="id123">examples</a><ul>
<li><a class="reference" href="#dump-torrent" id="id124" name="id124">dump_torrent</a></li>
<li><a class="reference" href="#simple-client" id="id125" name="id125">simple client</a></li>
<li><a class="reference" href="#make-torrent" id="id126" name="id126">make_torrent</a></li>
<li><a class="reference" href="#examples" id="id124" name="id124">examples</a><ul>
<li><a class="reference" href="#dump-torrent" id="id125" name="id125">dump_torrent</a></li>
<li><a class="reference" href="#simple-client" id="id126" name="id126">simple client</a></li>
<li><a class="reference" href="#make-torrent" id="id127" name="id127">make_torrent</a></li>
</ul>
</li>
<li><a class="reference" href="#fast-resume" id="id127" name="id127">fast resume</a><ul>
<li><a class="reference" href="#file-format" id="id128" name="id128">file format</a></li>
<li><a class="reference" href="#fast-resume" id="id128" name="id128">fast resume</a><ul>
<li><a class="reference" href="#file-format" id="id129" name="id129">file format</a></li>
</ul>
</li>
<li><a class="reference" href="#threads" id="id129" name="id129">threads</a></li>
<li><a class="reference" href="#storage-allocation" id="id130" name="id130">storage allocation</a><ul>
<li><a class="reference" href="#full-allocation" id="id131" name="id131">full allocation</a></li>
<li><a class="reference" href="#compact-allocation" id="id132" name="id132">compact allocation</a></li>
<li><a class="reference" href="#threads" id="id130" name="id130">threads</a></li>
<li><a class="reference" href="#storage-allocation" id="id131" name="id131">storage allocation</a><ul>
<li><a class="reference" href="#full-allocation" id="id132" name="id132">full allocation</a></li>
<li><a class="reference" href="#compact-allocation" id="id133" name="id133">compact allocation</a></li>
</ul>
</li>
<li><a class="reference" href="#extensions" id="id133" name="id133">extensions</a><ul>
<li><a class="reference" href="#chat-messages" id="id134" name="id134">chat messages</a></li>
<li><a class="reference" href="#metadata-from-peers" id="id135" name="id135">metadata from peers</a></li>
<li><a class="reference" href="#http-seeding" id="id136" name="id136">HTTP seeding</a></li>
<li><a class="reference" href="#extensions" id="id134" name="id134">extensions</a><ul>
<li><a class="reference" href="#chat-messages" id="id135" name="id135">chat messages</a></li>
<li><a class="reference" href="#metadata-from-peers" id="id136" name="id136">metadata from peers</a></li>
<li><a class="reference" href="#http-seeding" id="id137" name="id137">HTTP seeding</a></li>
</ul>
</li>
<li><a class="reference" href="#filename-checks" id="id137" name="id137">filename checks</a></li>
<li><a class="reference" href="#acknowledgements" id="id138" name="id138">acknowledgements</a></li>
<li><a class="reference" href="#filename-checks" id="id138" name="id138">filename checks</a></li>
<li><a class="reference" href="#acknowledgements" id="id139" name="id139">acknowledgements</a></li>
</ul>
</div>
<div class="section">
@ -2459,6 +2460,18 @@ to extract a string describing a client version from its peer-id. It will recogn
that have this kind of identification in the peer-id.</p>
</div>
<div class="section">
<h2><a id="client-fingerprint" name="client-fingerprint">client_fingerprint()</a></h2>
<blockquote>
<pre class="literal-block">
boost::optional&lt;fingerprint&gt; client_fingerprint(peer_id const&amp; p);
</pre>
</blockquote>
<p>Returns an optional fingerprint if any can be identified from the peer id. This can be used
to automate the identification of clients. It will not be able to identifiy peers with non-
standard encodings. Only Azureus style, Shadow's style and Mainline style. This function is
declared in the header <tt class="docutils literal"><span class="pre">&lt;libtorrent/identify_client.hpp&gt;</span></tt>.</p>
</div>
<div class="section">
<h2><a id="bdecode-bencode" name="bdecode-bencode">bdecode() bencode()</a></h2>
<blockquote>
<pre class="literal-block">

View File

@ -2346,6 +2346,20 @@ This function is declared in the header ``<libtorrent/identify_client.hpp>``. It
to extract a string describing a client version from its peer-id. It will recognize most clients
that have this kind of identification in the peer-id.
client_fingerprint()
--------------------
::
boost::optional<fingerprint> client_fingerprint(peer_id const& p);
Returns an optional fingerprint if any can be identified from the peer id. This can be used
to automate the identification of clients. It will not be able to identifiy peers with non-
standard encodings. Only Azureus style, Shadow's style and Mainline style. This function is
declared in the header ``<libtorrent/identify_client.hpp>``.
bdecode() bencode()
-------------------

View File

@ -67,63 +67,22 @@ namespace libtorrent
struct logger
{
logger& operator<<(const char* t)
{ assert(t); log(t); return *this; }
logger& operator<<(const std::string& t)
{ log(t.c_str()); return *this; }
logger& operator<<(int i)
{
log(boost::lexical_cast<std::string>(i).c_str());
return *this;
}
logger& operator<<(unsigned int i)
{
log(boost::lexical_cast<std::string>(i).c_str());
return *this;
}
logger& operator<<(float i)
{
log(boost::lexical_cast<std::string>(i).c_str());
return *this;
}
logger& operator<<(char i)
{
char c[2];
c[0] = i;
c[1] = 0;
log(c);
return *this;
}
virtual void log(const char*) = 0;
virtual ~logger() {}
};
struct null_logger: libtorrent::logger
{
public:
virtual void log(const char*) {}
};
struct cout_logger: libtorrent::logger
{
public:
virtual void log(const char* text) { std::cout << text; }
};
struct file_logger: libtorrent::logger
{
public:
file_logger(boost::filesystem::path const& filename, bool append = true)
logger(boost::filesystem::path const& filename, bool append = true)
{
using namespace boost::filesystem;
path dir(complete("libtorrent_logs"));
if (!exists(dir)) create_directories(dir);
m_file.open(dir / filename, std::ios_base::out | (append ? std::ios_base::app : std::ios_base::out));
log("\n\n\n*** starting log ***\n");
*this << "\n\n\n*** starting log ***\n";
}
template <class T>
logger& operator<<(T const& v)
{
m_file << v;
m_file.flush();
return *this;
}
virtual void log(const char* text) { assert(text); m_file << text; m_file.flush(); }
boost::filesystem::ofstream m_file;
};

View File

@ -34,12 +34,14 @@ POSSIBILITY OF SUCH DAMAGE.
#define TORRENT_IDENTIFY_CLIENT_HPP_INCLUDED
#include "libtorrent/peer_id.hpp"
#include "libtorrent/fingerprint.hpp"
#include "libtorrent/config.hpp"
namespace libtorrent
{
TORRENT_EXPORT std::string identify_client(const peer_id& p);
TORRENT_EXPORT boost::optional<fingerprint> client_fingerprint(peer_id const& p);
}

View File

@ -261,6 +261,7 @@ namespace libtorrent
// adds a block to the request queue
void add_request(piece_block const& b);
void cancel_request(piece_block const& b);
void send_block_requests();
// how much bandwidth we're using, how much we want,
// and how much we are allowed to use.
@ -360,10 +361,16 @@ namespace libtorrent
void on_receive_data(asio::error const& error
, std::size_t bytes_transferred);
// this is the limit on the number of outstanding requests
// we have to this peer. This is initialized to the settings
// in the session_settings structure. But it may be lowered
// if the peer is known to require a smaller limit (like BitComet).
// or if the extended handshake sets a limit.
int m_max_out_request_queue;
private:
void fill_send_buffer();
void send_block_requests();
// the timeout in seconds
int m_timeout;
@ -386,7 +393,6 @@ namespace libtorrent
// buffer, the other is used to write data to
// be queued up.
std::vector<char> m_send_buffer[2];
// buffer m_send_buffer[2];
// the current send buffer is the one to write to.
// (m_current_send_buffer + 1) % 2 is the
// buffer we're currently waiting for.
@ -394,7 +400,7 @@ namespace libtorrent
// if the sending buffer doesn't finish in one send
// operation, this is the position within that buffer
// wher the next operation should continue
// where the next operation should continue
int m_write_pos;
// timeouts

View File

@ -51,6 +51,7 @@ namespace libtorrent
// the number of bytes of the number
enum { number_size = 20 };
public:
enum { size = number_size };
big_number() {}

View File

@ -62,7 +62,6 @@ namespace libtorrent
enum
{
// the limits of the download queue size
max_request_queue = 48,
min_request_queue = 2,
// the amount of free upload allowed before

View File

@ -42,8 +42,10 @@ namespace libtorrent
: piece_timeout(120)
, request_queue_time(3.f)
, sequenced_download_threshold(7)
, max_allowed_request_queue(200)
{}
, max_allowed_in_request_queue(250)
, max_out_request_queue(200)
, whole_pieces_threshold(20)
{}
// the number of seconds from a request is sent until
// it times out if no piece response is returned.
@ -70,7 +72,20 @@ namespace libtorrent
// been sent) the last request will be dropped.
// the higher this is, the faster upload speeds the
// client can get to a single peer.
int max_allowed_request_queue;
int max_allowed_in_request_queue;
// the maximum number of outstanding requests to
// send to a peer. This limit takes precedence over
// request_queue_time.
int max_out_request_queue;
// if a whole piece can be downloaded in this number
// of seconds, or less, the peer_connection will prefer
// to request whole pieces at a time from this peer.
// The benefit of this is to better utilize disk caches by
// doing localized accesses and also to make it easier
// to identify bad peers if a piece fails the hash check.
int whole_pieces_threshold;
};
}

View File

@ -133,6 +133,8 @@ namespace libtorrent
// by the checker thread.
bool is_allocating() const;
session_settings const& settings() const;
// is called every second by session. This will
// caclulate the upload/download and number
// of connections this torrent needs. And prepare

View File

@ -724,6 +724,14 @@ namespace libtorrent
if (client_info->type() == entry::string_t)
m_client_version = client_info->string();
}
if (entry* reqq = root.find_key("reqq"))
{
if (reqq->type() == entry::int_t)
m_max_out_request_queue = reqq->integer();
if (m_max_out_request_queue < 1)
m_max_out_request_queue = 1;
}
}
catch (std::exception& exc)
{
@ -1113,6 +1121,7 @@ namespace libtorrent
handshake["m"] = extension_list;
handshake["p"] = m_ses.m_listen_interface.port();
handshake["v"] = m_ses.m_http_settings.user_agent;
handshake["reqq"] = m_ses.m_settings.max_allowed_in_request_queue;
std::vector<char> msg;
bencode(std::back_inserter(msg), handshake);
@ -1395,12 +1404,18 @@ namespace libtorrent
set_pid(pid);
m_client_version = identify_client(pid);
boost::optional<fingerprint> f = client_fingerprint(pid);
if (f && std::equal(f->name, f->name + 2, "BC"))
{
// if this is a bitcomet client, lower the request queue size limit
if (m_max_out_request_queue > 50) m_max_out_request_queue = 50;
}
// disconnect if the peer has the same peer-id as ourself
// since it most likely is ourself then
if (pid == m_ses.get_peer_id())
throw std::runtime_error("closing connection to ourself");
if (m_supports_extensions) write_extensions();
/*
if (!m_active)

View File

@ -247,6 +247,7 @@ namespace libtorrent
{
throw_exception("file::seek");
}
return offs.QuadPart;
}
size_type tell()
@ -264,8 +265,8 @@ namespace libtorrent
throw_exception("file::tell");
}
size_type pos=offs.QuadPart;
assert(pos>=0);
size_type pos = offs.QuadPart;
assert(pos >= 0);
return pos;
}
/*

View File

@ -226,7 +226,24 @@ namespace
namespace libtorrent
{
std::string identify_client(const peer_id& p)
boost::optional<fingerprint> client_fingerprint(peer_id const& p)
{
// look for azureus style id
boost::optional<fingerprint> f;
f = parse_az_style(p);
if (f) return f;
// look for shadow style id
f = parse_shadow_style(p);
if (f) return f;
// look for mainline style id
f = parse_mainline_style(p);
if (f) return f;
return f;
}
std::string identify_client(peer_id const& p)
{
peer_id::const_iterator PID = p.begin();
boost::optional<fingerprint> f;

View File

@ -82,6 +82,7 @@ namespace libtorrent
,
#endif
m_ses(ses)
, m_max_out_request_queue(m_ses.m_settings.max_out_request_queue)
, m_timeout(120)
, m_last_piece(second_clock::universal_time())
, m_packet_size(0)
@ -172,6 +173,7 @@ namespace libtorrent
,
#endif
m_ses(ses)
, m_max_out_request_queue(m_ses.m_settings.max_out_request_queue)
, m_timeout(120)
, m_last_piece(second_clock::universal_time())
, m_packet_size(0)
@ -792,7 +794,7 @@ namespace libtorrent
return;
}
if (int(m_requests.size()) > m_ses.m_settings.max_allowed_request_queue)
if (int(m_requests.size()) > m_ses.m_settings.max_allowed_in_request_queue)
{
// don't allow clients to abuse our
// memory consumption.
@ -830,7 +832,7 @@ namespace libtorrent
return;
m_requests.push_back(r);
setup_send();
fill_send_buffer();
#ifdef TORRENT_VERBOSE_LOGGING
using namespace boost::posix_time;
(*m_logger) << to_simple_string(second_clock::universal_time())
@ -1093,7 +1095,6 @@ namespace libtorrent
t->picker().mark_as_downloading(block, m_remote);
m_request_queue.push_back(block);
send_block_requests();
}
void peer_connection::cancel_request(piece_block const& block)
@ -1410,10 +1411,10 @@ namespace libtorrent
m_desired_queue_size = static_cast<int>(queue_time
* statistics().download_rate() / block_size);
if (m_desired_queue_size > max_request_queue) m_desired_queue_size
= max_request_queue;
if (m_desired_queue_size < min_request_queue) m_desired_queue_size
= min_request_queue;
if (m_desired_queue_size > m_max_out_request_queue)
m_desired_queue_size = m_max_out_request_queue;
if (m_desired_queue_size < min_request_queue)
m_desired_queue_size = min_request_queue;
if (!m_download_queue.empty()
&& now - m_last_piece > seconds(m_ses.m_settings.piece_timeout))
@ -1550,8 +1551,6 @@ namespace libtorrent
{
INVARIANT_CHECK;
if (!can_write()) return;
boost::shared_ptr<torrent> t = m_torrent.lock();
if (!t) return;
@ -1778,8 +1777,7 @@ namespace libtorrent
// if we have requests or pending data to be sent or announcements to be made
// we want to send data
return ((!m_requests.empty() && !m_choked)
|| !m_send_buffer[m_current_send_buffer].empty()
return (!m_send_buffer[m_current_send_buffer].empty()
|| !m_send_buffer[(m_current_send_buffer + 1) & 1].empty())
&& m_ul_bandwidth_quota.left() > 0
&& !m_connecting;

View File

@ -94,7 +94,8 @@ namespace
// for this peer. If we're downloading one piece in 20 seconds
// then use this mode.
// TODO: 20 seconds has to be customizable
bool prefer_whole_pieces = c.statistics().download_payload_rate() * 20.f
bool prefer_whole_pieces = c.statistics().download_payload_rate()
* t.settings().whole_pieces_threshold
> t.torrent_file().piece_length();
// if we prefer whole pieces, the piece picker will pick at least
@ -131,6 +132,8 @@ namespace
num_requests--;
}
c.send_block_requests();
// in this case, we could not find any blocks
// that was free. If we couldn't find any busy
// blocks as well, we cannot download anything
@ -222,6 +225,7 @@ namespace
if (weight <= min_weight) break;
}
c.send_block_requests();
}

View File

@ -372,6 +372,7 @@ namespace libtorrent { namespace detail
for (std::deque<boost::shared_ptr<piece_checker_data> >::iterator i
= m_processing.begin(); i != m_processing.end(); ++i)
{
if ((*i)->info_hash == info_hash) return i->get();
}
@ -390,6 +391,17 @@ namespace libtorrent { namespace detail
return;
}
}
for (std::deque<boost::shared_ptr<piece_checker_data> >::iterator i
= m_processing.begin(); i != m_processing.end(); ++i)
{
if ((*i)->info_hash == info_hash)
{
assert((*i)->processing == false);
m_torrents.erase(i);
return;
}
}
assert(false);
}
@ -839,6 +851,9 @@ namespace libtorrent { namespace detail
for (std::map<sha1_hash, boost::shared_ptr<torrent> >::iterator i
= m_torrents.begin(); i != m_torrents.end(); ++i)
{
#ifndef DEBUG
i->second->check_invariant();
#endif
i->second->distribute_resources();
}
}
@ -955,7 +970,7 @@ namespace libtorrent { namespace detail
boost::shared_ptr<logger> session_impl::create_log(std::string const& name, bool append)
{
// current options are file_logger, cout_logger and null_logger
return boost::shared_ptr<logger>(new file_logger(name + ".log", append));
return boost::shared_ptr<logger>(new logger(name + ".log", append));
}
#endif

View File

@ -1322,7 +1322,10 @@ namespace libtorrent
return torrent_handle(&m_ses, 0, m_torrent_file.info_hash());
}
session_settings const& torrent::settings() const
{
return m_ses.m_settings;
}
#ifndef NDEBUG
void torrent::check_invariant() const
@ -1599,6 +1602,7 @@ namespace libtorrent
{
bencode(std::back_inserter(m_metadata)
, m_torrent_file.create_info_metadata());
assert(hasher(&m_metadata[0], m_metadata.size()).final()
== m_torrent_file.info_hash());
}