libtorrent add torrents in paused state sync

This commit is contained in:
Marcos Pinto 2007-08-22 07:17:21 +00:00
parent da43f105b8
commit ae37b3aa39
16 changed files with 308 additions and 151 deletions

View File

@ -0,0 +1,55 @@
/*
Copyright (c) 2007, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TORRENT_ASSERT_HPP_INCLUDED
#define TORRENT_ASSERT_HPP_INCLUDED
#ifndef NDEBUG
#if defined __linux__ && defined _GNUC
#ifdef assert
#undef assert
#endif
void assert_fail(int line, char const* file);
#define assert(x) if (!(x)) assert_fail(__LINE__, __FILE__)
#endif
#else
#ifndef assert
#define assert(x) (void)
#endif
#endif
#endif

View File

@ -244,8 +244,8 @@ namespace libtorrent
, fs::path const& save_path
, entry const& resume_data
, bool compact_mode
, int block_size
, storage_constructor_type sc);
, storage_constructor_type sc
, bool paused);
torrent_handle add_torrent(
char const* tracker_url
@ -254,8 +254,8 @@ namespace libtorrent
, fs::path const& save_path
, entry const& resume_data
, bool compact_mode
, int block_size
, storage_constructor_type sc);
, storage_constructor_type sc
, bool paused);
void remove_torrent(torrent_handle const& h);
@ -493,7 +493,7 @@ namespace libtorrent
// This implements a round robin.
int m_next_connect_torrent;
#ifndef NDEBUG
void check_invariant(const char *place = 0);
void check_invariant() const;
#endif
#ifdef TORRENT_STATS

View File

@ -80,3 +80,4 @@ namespace libtorrent
}
#endif // TORRENT_DEBUG_HPP_INCLUDED

View File

@ -56,10 +56,11 @@ namespace libtorrent
connecting = 0x80,
queued = 0x100,
on_parole = 0x200,
seed = 0x400
seed = 0x400,
optimistic_unchoke = 0x800
#ifndef TORRENT_DISABLE_ENCRYPTION
, rc4_encrypted = 0x800,
plaintext_encrypted = 0x1000
, rc4_encrypted = 0x100000,
plaintext_encrypted = 0x200000
#endif
};

View File

@ -141,23 +141,9 @@ namespace libtorrent
, fs::path const& save_path
, entry const& resume_data = entry()
, bool compact_mode = true
, int block_size = 16 * 1024
, bool paused = false
, storage_constructor_type sc = default_storage_constructor);
// ==== deprecated, this is for backwards compatibility only
// instead, use one of the other add_torrent overloads
torrent_handle add_torrent(
entry const& e
, fs::path const& save_path
, entry const& resume_data = entry()
, bool compact_mode = true
, int block_size = 16 * 1024
, storage_constructor_type sc = default_storage_constructor) TORRENT_DEPRECATED
{
return add_torrent(torrent_info(e), save_path, resume_data
, compact_mode, block_size, sc);
}
torrent_handle add_torrent(
char const* tracker_url
, sha1_hash const& info_hash
@ -165,7 +151,7 @@ namespace libtorrent
, fs::path const& save_path
, entry const& resume_data = entry()
, bool compact_mode = true
, int block_size = 16 * 1024
, bool paused = false
, storage_constructor_type sc = default_storage_constructor);
session_proxy abort() { return session_proxy(m_impl); }

View File

@ -102,8 +102,8 @@ namespace libtorrent
, tcp::endpoint const& net_interface
, bool compact_mode
, int block_size
, session_settings const& s
, storage_constructor_type sc);
, storage_constructor_type sc
, bool paused);
// used with metadata-less torrents
// (the metadata is downloaded from the peers)
@ -117,8 +117,8 @@ namespace libtorrent
, tcp::endpoint const& net_interface
, bool compact_mode
, int block_size
, session_settings const& s
, storage_constructor_type sc);
, storage_constructor_type sc
, bool paused);
~torrent();

60
libtorrent/src/assert.cpp Normal file
View File

@ -0,0 +1,60 @@
/*
Copyright (c) 2007, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NDEBUG
#include <execinfo.h>
void assert_fail(int line, char const* file)
{
fprintf(stderr, "assertion failed. Please file a bugreport at "
"http://code.rasterbar.com/libtorrent/newticket\n"
"Please include the following information:\n\n"
"file: '%s'\n"
"line: %d\n"
"stack:\n", file, line);
void* stacktrace[50];
int size = backtrace(stack, 50);
char** symbols = backtrace_symbols(stack, size);
for (int i = 0; i < size; ++i)
{
fprintf(stderr, "%d: %s\n", i, symbols[i]);
}
free(symbols);
}
#endif

View File

@ -523,7 +523,7 @@ namespace libtorrent { namespace
if (num_blocks < 1) num_blocks = 1;
assert(num_blocks <= 128);
int min_element = std::numeric_limits<int>::max();
int min_element = (std::numeric_limits<int>::max)();
int best_index = 0;
for (int i = 0; i < 256 - num_blocks + 1; ++i)
{

View File

@ -1480,7 +1480,7 @@ namespace libtorrent
assert(!m_have_piece.empty());
std::fill(m_have_piece.begin(), m_have_piece.end(), true);
m_num_pieces = m_have_piece.size();
m_num_pieces = m_have_piece.size();
t->peer_has_all();
if (!t->is_finished())
@ -1563,13 +1563,9 @@ namespace libtorrent
boost::shared_ptr<torrent> t = m_torrent.lock();
assert(t);
for (std::vector<int>::iterator i = m_allowed_fast.begin()
, end(m_allowed_fast.end()); i != end; ++i)
{
if (!t->have_piece(*i)) continue;
*i = m_allowed_fast.back();
m_allowed_fast.pop_back();
}
m_allowed_fast.erase(std::remove_if(m_allowed_fast.begin()
, m_allowed_fast.end(), bind(&torrent::have_piece, t, _1))
, m_allowed_fast.end());
// TODO: sort the allowed fast set in priority order
return m_allowed_fast;
@ -1683,6 +1679,8 @@ namespace libtorrent
{
INVARIANT_CHECK;
assert(!m_peer_info || !m_peer_info->optimistically_unchoked);
if (m_choked) return;
write_choke();
m_choked = true;
@ -1701,14 +1699,6 @@ namespace libtorrent
{
INVARIANT_CHECK;
#ifndef NDEBUG
// TODO: once the policy lowers the interval for optimistic
// unchoke, increase this value that interval
// this condition cannot be guaranteed since if peers disconnect
// a new one will be unchoked ignoring when it was last choked
//assert(time_now() - m_last_choke > seconds(9));
#endif
if (!m_choked) return;
write_unchoke();
m_choked = false;
@ -1904,7 +1894,7 @@ namespace libtorrent
void peer_connection::set_upload_limit(int limit)
{
assert(limit >= -1);
if (limit == -1) limit = std::numeric_limits<int>::max();
if (limit == -1) limit = (std::numeric_limits<int>::max)();
if (limit < 10) limit = 10;
m_upload_limit = limit;
m_bandwidth_limit[upload_channel].throttle(m_upload_limit);
@ -1913,7 +1903,7 @@ namespace libtorrent
void peer_connection::set_download_limit(int limit)
{
assert(limit >= -1);
if (limit == -1) limit = std::numeric_limits<int>::max();
if (limit == -1) limit = (std::numeric_limits<int>::max)();
if (limit < 10) limit = 10;
m_download_limit = limit;
m_bandwidth_limit[download_channel].throttle(m_download_limit);
@ -1931,7 +1921,7 @@ namespace libtorrent
// if we have an infinite ratio, just say we have downloaded
// much more than we have uploaded. And we'll keep uploading.
if (ratio == 0.f)
return std::numeric_limits<size_type>::max();
return (std::numeric_limits<size_type>::max)();
return m_free_upload
+ static_cast<size_type>(m_statistics.total_payload_download() * ratio)
@ -2013,6 +2003,7 @@ namespace libtorrent
p.failcount = peer_info_struct()->failcount;
p.num_hashfails = peer_info_struct()->hashfails;
p.flags |= peer_info_struct()->on_parole ? peer_info::on_parole : 0;
p.flags |= peer_info_struct()->optimistically_unchoked ? peer_info::optimistic_unchoke : 0;
p.remote_dl_rate = m_remote_dl_rate;
}
else
@ -2171,7 +2162,7 @@ namespace libtorrent
+ bias) / break_even_time, double(m_upload_limit));
upload_speed_limit = (std::min)(upload_speed_limit,
(double)std::numeric_limits<int>::max());
(double)(std::numeric_limits<int>::max)());
m_bandwidth_limit[upload_channel].throttle(
(std::min)((std::max)((int)upload_speed_limit, 20)
@ -2235,20 +2226,6 @@ namespace libtorrent
m_reading_bytes += r.length;
m_requests.erase(m_requests.begin());
/*
if (m_requests.empty()
&& m_num_invalid_requests > 0
&& is_peer_interested()
&& !is_seed())
{
// this will make the peer clear
// its download queue and re-request
// pieces. Hopefully it will not
// send invalid requests then
send_choke();
send_unchoke();
}
*/
}
}
@ -2789,9 +2766,14 @@ namespace libtorrent
void peer_connection::check_invariant() const
{
if (m_peer_info)
{
assert(m_peer_info->connection == this
|| m_peer_info->connection == 0);
if (m_peer_info->optimistically_unchoked)
assert(!is_choked());
}
boost::shared_ptr<torrent> t = m_torrent.lock();
if (!t)
{

View File

@ -394,6 +394,7 @@ namespace libtorrent
assert(!t->have_piece(index));
int prio = i->priority(m_sequenced_download_threshold);
assert(prio < int(m_piece_info.size()));
if (prio > 0)
{
const std::vector<int>& vec = m_piece_info[prio];
@ -739,6 +740,7 @@ namespace libtorrent
, end(m_piece_map.end()); i != end; ++i)
{
int prev_prio = i->priority(m_sequenced_download_threshold);
assert(prev_prio < int(m_piece_info.size()));
++i->peer_count;
// if the assumption that the priority would
// increase by 2 when increasing the availability
@ -828,6 +830,8 @@ namespace libtorrent
, end(m_piece_map.end()); i != end; ++i)
{
int prev_prio = i->priority(m_sequenced_download_threshold);
assert(prev_prio < int(m_piece_info.size()));
assert(pushed_out_index < int(m_piece_info.size()));
assert(i->peer_count > 0);
--i->peer_count;
// if the assumption that the priority would
@ -879,6 +883,7 @@ namespace libtorrent
piece_pos& p = m_piece_map[i];
int index = p.index;
int prev_priority = p.priority(m_sequenced_download_threshold);
assert(prev_priority < int(m_piece_info.size()));
assert(p.peer_count < piece_pos::max_peer_count);
p.peer_count++;
@ -913,6 +918,7 @@ namespace libtorrent
piece_pos& p = m_piece_map[i];
int prev_priority = p.priority(m_sequenced_download_threshold);
assert(prev_priority < int(m_piece_info.size()));
int index = p.index;
assert(p.peer_count > 0);
@ -937,6 +943,7 @@ namespace libtorrent
piece_pos& p = m_piece_map[index];
int info_index = p.index;
int priority = p.priority(m_sequenced_download_threshold);
assert(priority < int(m_piece_info.size()));
assert(p.downloading == 1);
assert(!p.have());
@ -980,6 +987,7 @@ namespace libtorrent
if (new_piece_priority == int(p.piece_priority)) return false;
int prev_priority = p.priority(m_sequenced_download_threshold);
assert(prev_priority < int(m_piece_info.size()));
bool ret = false;
if (new_piece_priority == piece_pos::filter_priority
@ -1003,6 +1011,7 @@ namespace libtorrent
p.piece_priority = new_piece_priority;
int new_priority = p.priority(m_sequenced_download_threshold);
assert(prev_priority < int(m_piece_info.size()));
if (new_priority == prev_priority) return false;
@ -1224,6 +1233,9 @@ namespace libtorrent
// skip it
if (!pieces[*i]) continue;
// skip the piece is the priority is 0
if (m_piece_map[*i].priority(m_sequenced_download_threshold) == 0) continue;
int num_blocks_in_piece = blocks_in_piece(*i);
if (m_piece_map[*i].downloading == 1)
@ -1419,6 +1431,7 @@ namespace libtorrent
if (p.downloading == 0)
{
int prio = p.priority(m_sequenced_download_threshold);
assert(prio < int(m_piece_info.size()));
assert(prio > 0);
p.downloading = 1;
move(prio, p.index);
@ -1530,6 +1543,7 @@ namespace libtorrent
assert(peer == 0);
int prio = p.priority(m_sequenced_download_threshold);
assert(prio < int(m_piece_info.size()));
p.downloading = 1;
if (prio > 0) move(prio, p.index);
else assert(p.priority(m_sequenced_download_threshold) == 0);
@ -1652,6 +1666,7 @@ namespace libtorrent
erase_download_piece(i);
piece_pos& p = m_piece_map[block.piece_index];
int prio = p.priority(m_sequenced_download_threshold);
assert(prio < int(m_piece_info.size()));
p.downloading = 0;
if (prio > 0) move(prio, p.index);

View File

@ -83,7 +83,7 @@ namespace
// (and we should not consider it free). If the share diff is
// negative, there's no free download to get from this peer.
size_type diff = i->second->share_diff();
assert(diff < std::numeric_limits<size_type>::max());
assert(diff < (std::numeric_limits<size_type>::max)());
if (i->second->is_peer_interested() || diff <= 0)
continue;
@ -110,7 +110,7 @@ namespace
for (torrent::peer_iterator i = start; i != end; ++i)
{
size_type d = i->second->share_diff();
assert(d < std::numeric_limits<size_type>::max());
assert(d < (std::numeric_limits<size_type>::max)());
total_diff += d;
if (!i->second->is_peer_interested() || i->second->share_diff() >= 0) continue;
++num_peers;
@ -120,7 +120,7 @@ namespace
size_type upload_share;
if (total_diff >= 0)
{
upload_share = std::min(free_upload, total_diff) / num_peers;
upload_share = (std::min)(free_upload, total_diff) / num_peers;
}
else
{
@ -280,6 +280,7 @@ namespace libtorrent
{
if (p.is_requested(*i))
{
if (num_requests <= 0) break;
// don't request pieces we already have in our request queue
const std::deque<piece_block>& dq = c.download_queue();
const std::deque<piece_block>& rq = c.request_queue();
@ -299,10 +300,9 @@ namespace libtorrent
assert(p.num_peers(*i) == 1);
assert(p.is_requested(*i));
num_requests--;
if (num_requests == 0) break;
}
if (busy_pieces.empty() || num_requests == 0)
if (busy_pieces.empty() || num_requests <= 0)
{
// in this case, we could not find any blocks
// that was free. If we couldn't find any busy
@ -385,7 +385,7 @@ namespace libtorrent
INVARIANT_CHECK;
iterator worst_peer = m_peers.end();
size_type min_weight = std::numeric_limits<int>::min();
size_type min_weight = (std::numeric_limits<int>::min)();
#ifndef NDEBUG
int unchoked_counter = m_num_unchoked;
@ -464,7 +464,7 @@ namespace libtorrent
INVARIANT_CHECK;
iterator disconnect_peer = m_peers.end();
double slowest_transfer_rate = std::numeric_limits<double>::max();
double slowest_transfer_rate = (std::numeric_limits<double>::max)();
ptime now = time_now();
@ -693,7 +693,7 @@ namespace libtorrent
++num_connected_peers;
}
if (m_torrent->max_connections() != std::numeric_limits<int>::max())
if (m_torrent->max_connections() != (std::numeric_limits<int>::max)())
{
int max_connections = m_torrent->max_connections();
@ -1215,7 +1215,7 @@ namespace libtorrent
if (m_torrent->ratio() != 0.f)
{
assert(c.share_diff() < std::numeric_limits<size_type>::max());
assert(c.share_diff() < (std::numeric_limits<size_type>::max)());
size_type diff = c.share_diff();
if (diff > 0 && c.is_seed())
{
@ -1320,14 +1320,16 @@ namespace libtorrent
INVARIANT_CHECK;
peer* p = c.peer_info_struct();
// if we couldn't find the connection in our list, just ignore it.
if (p == 0) return;
assert(std::find_if(
assert((std::find_if(
m_peers.begin()
, m_peers.end()
, match_peer_connection(c))
!= m_peers.end());
!= m_peers.end()) == (p != 0));
// if we couldn't find the connection in our list, just ignore it.
if (p == 0) return;
assert(p->connection == &c);
p->connection = 0;
@ -1347,7 +1349,7 @@ namespace libtorrent
if (m_torrent->ratio() != 0.f)
{
assert(c.associated_torrent().lock().get() == m_torrent);
assert(c.share_diff() < std::numeric_limits<size_type>::max());
assert(c.share_diff() < (std::numeric_limits<size_type>::max)());
m_available_free_upload += c.share_diff();
}
p->prev_amount_download += c.statistics().total_payload_download();
@ -1368,10 +1370,12 @@ namespace libtorrent
#ifndef NDEBUG
bool policy::has_connection(const peer_connection* c)
{
INVARIANT_CHECK;
// too expensive
// INVARIANT_CHECK;
assert(c);
assert(c->remote() == c->get_socket()->remote_endpoint());
try { assert(c->remote() == c->get_socket()->remote_endpoint()); }
catch (std::exception&) {}
return std::find_if(
m_peers.begin()
@ -1405,6 +1409,11 @@ namespace libtorrent
, boost::bind(std::equal_to<peer_connection*>(), _1, p.connection))
!= conns.end());
}
if (p.optimistically_unchoked)
{
assert(p.connection);
assert(!p.connection->is_choked());
}
assert(p.connection->peer_info_struct() == 0
|| p.connection->peer_info_struct() == &p);
++nonempty_connections;

View File

@ -179,11 +179,11 @@ namespace libtorrent
, fs::path const& save_path
, entry const& resume_data
, bool compact_mode
, int block_size
, bool paused
, storage_constructor_type sc)
{
return m_impl->add_torrent(ti, save_path, resume_data
, compact_mode, block_size, sc);
, compact_mode, sc, paused);
}
torrent_handle session::add_torrent(
@ -193,11 +193,11 @@ namespace libtorrent
, fs::path const& save_path
, entry const& e
, bool compact_mode
, int block_size
, bool paused
, storage_constructor_type sc)
{
return m_impl->add_torrent(tracker_url, info_hash, name, save_path, e
, compact_mode, block_size, sc);
, compact_mode, sc, paused);
}
void session::remove_torrent(const torrent_handle& h)

View File

@ -624,6 +624,9 @@ namespace detail
void session_impl::set_ip_filter(ip_filter const& f)
{
mutex_t::scoped_lock l(m_mutex);
INVARIANT_CHECK;
m_ip_filter = f;
// Close connections whose endpoint is filtered
@ -636,6 +639,9 @@ namespace detail
void session_impl::set_settings(session_settings const& s)
{
mutex_t::scoped_lock l(m_mutex);
INVARIANT_CHECK;
assert(s.connection_speed > 0);
assert(s.file_pool_size > 0);
@ -802,6 +808,9 @@ namespace detail
#endif
{
mutex_t::scoped_lock l(m_mutex);
// too expensive
// INVARIANT_CHECK;
connection_map::iterator p = m_connections.find(s);
@ -833,6 +842,9 @@ namespace detail
{
mutex_t::scoped_lock l(m_mutex);
// too expensive
// INVARIANT_CHECK;
assert(p->is_disconnecting());
connection_map::iterator i = m_connections.find(p->get_socket());
if (i != m_connections.end())
@ -858,6 +870,8 @@ namespace detail
{
session_impl::mutex_t::scoped_lock l(m_mutex);
INVARIANT_CHECK;
if (e)
{
#if defined(TORRENT_LOGGING)
@ -1106,8 +1120,11 @@ namespace detail
}
else
{
assert(p->peer_info_struct());
if (!p->is_choked() && !p->peer_info_struct()->optimistically_unchoked)
t->choke_peer(*p);
if (!p->is_choked())
++m_num_unchoked;
}
}
@ -1135,6 +1152,7 @@ namespace detail
if (pi->optimistically_unchoked)
{
assert(!p->is_choked());
assert(current_optimistic_unchoke == m_connections.end());
current_optimistic_unchoke = i;
}
@ -1158,8 +1176,12 @@ namespace detail
{
torrent* t = current_optimistic_unchoke->second->associated_torrent().lock().get();
assert(t);
t->choke_peer(*current_optimistic_unchoke->second);
current_optimistic_unchoke->second->peer_info_struct()->optimistically_unchoked = false;
t->choke_peer(*current_optimistic_unchoke->second);
}
else
{
++m_num_unchoked;
}
torrent* t = optimistic_unchoke_candidate->second->associated_torrent().lock().get();
@ -1168,9 +1190,6 @@ namespace detail
assert(ret);
optimistic_unchoke_candidate->second->peer_info_struct()->optimistically_unchoked = true;
}
if (optimistic_unchoke_candidate != m_connections.end())
++m_num_unchoked;
}
}
@ -1428,25 +1447,12 @@ namespace detail
, fs::path const& save_path
, entry const& resume_data
, bool compact_mode
, int block_size
, storage_constructor_type sc)
, storage_constructor_type sc
, bool paused)
{
// if you get this assert, you haven't managed to
// open a listen port. call listen_on() first.
assert(m_external_listen_port > 0);
// make sure the block_size is an even power of 2
#ifndef NDEBUG
for (int i = 0; i < 32; ++i)
{
if (block_size & (1 << i))
{
assert((block_size & ~(1 << i)) == 0);
break;
}
}
#endif
assert(!save_path.empty());
if (ti.begin_files() == ti.end_files())
@ -1456,6 +1462,8 @@ namespace detail
mutex_t::scoped_lock l(m_mutex);
mutex::scoped_lock l2(m_checker_impl.m_mutex);
INVARIANT_CHECK;
if (is_aborted())
throw std::runtime_error("session is closing");
@ -1472,8 +1480,8 @@ namespace detail
// the thread
boost::shared_ptr<torrent> torrent_ptr(
new torrent(*this, m_checker_impl, ti, save_path
, m_listen_interface, compact_mode, block_size
, settings(), sc));
, m_listen_interface, compact_mode, 16 * 1024
, sc, paused));
torrent_ptr->start();
#ifndef TORRENT_DISABLE_EXTENSIONS
@ -1519,20 +1527,9 @@ namespace detail
, fs::path const& save_path
, entry const&
, bool compact_mode
, int block_size
, storage_constructor_type sc)
, storage_constructor_type sc
, bool paused)
{
// make sure the block_size is an even power of 2
#ifndef NDEBUG
for (int i = 0; i < 32; ++i)
{
if (block_size & (1 << i))
{
assert((block_size & ~(1 << i)) == 0);
break;
}
}
#endif
// TODO: support resume data in this case
assert(!save_path.empty());
@ -1548,6 +1545,8 @@ namespace detail
// lock the session
session_impl::mutex_t::scoped_lock l(m_mutex);
INVARIANT_CHECK;
// is the torrent already active?
if (!find_torrent(info_hash).expired())
throw duplicate_torrent();
@ -1560,8 +1559,8 @@ namespace detail
// the thread
boost::shared_ptr<torrent> torrent_ptr(
new torrent(*this, m_checker_impl, tracker_url, info_hash, name
, save_path, m_listen_interface, compact_mode, block_size
, settings(), sc));
, save_path, m_listen_interface, compact_mode, 16 * 1024
, sc, paused));
torrent_ptr->start();
#ifndef TORRENT_DISABLE_EXTENSIONS
@ -1586,6 +1585,9 @@ namespace detail
assert(h.m_ses != 0);
mutex_t::scoped_lock l(m_mutex);
INVARIANT_CHECK;
session_impl::torrent_map::iterator i =
m_torrents.find(h.m_info_hash);
if (i != m_torrents.end())
@ -1648,6 +1650,8 @@ namespace detail
{
session_impl::mutex_t::scoped_lock l(m_mutex);
INVARIANT_CHECK;
tcp::endpoint new_interface;
if (net_interface && std::strlen(net_interface) > 0)
new_interface = tcp::endpoint(address::from_string(net_interface), port_range.first);
@ -1727,6 +1731,8 @@ namespace detail
{
mutex_t::scoped_lock l(m_mutex);
INVARIANT_CHECK;
boost::shared_ptr<torrent> t = find_torrent(ih).lock();
if (!t) return;
// don't add peers from lsd to private torrents
@ -1781,6 +1787,9 @@ namespace detail
session_status session_impl::status() const
{
mutex_t::scoped_lock l(m_mutex);
INVARIANT_CHECK;
session_status s;
s.has_incoming_connections = m_incoming_connection;
s.num_peers = (int)m_connections.size();
@ -1822,6 +1831,9 @@ namespace detail
void session_impl::start_dht(entry const& startup_state)
{
mutex_t::scoped_lock l(m_mutex);
INVARIANT_CHECK;
if (m_dht)
{
m_dht->stop();
@ -1981,7 +1993,10 @@ namespace detail
{
assert(limit > 0 || limit == -1);
mutex_t::scoped_lock l(m_mutex);
if (limit <= 0) limit = std::numeric_limits<int>::max();
INVARIANT_CHECK;
if (limit <= 0) limit = (std::numeric_limits<int>::max)();
m_max_uploads = limit;
}
@ -1989,7 +2004,10 @@ namespace detail
{
assert(limit > 0 || limit == -1);
mutex_t::scoped_lock l(m_mutex);
if (limit <= 0) limit = std::numeric_limits<int>::max();
INVARIANT_CHECK;
if (limit <= 0) limit = (std::numeric_limits<int>::max)();
m_max_connections = limit;
}
@ -1997,7 +2015,10 @@ namespace detail
{
assert(limit > 0 || limit == -1);
mutex_t::scoped_lock l(m_mutex);
if (limit <= 0) limit = std::numeric_limits<int>::max();
INVARIANT_CHECK;
if (limit <= 0) limit = (std::numeric_limits<int>::max)();
m_half_open.limit(limit);
}
@ -2005,6 +2026,9 @@ namespace detail
{
assert(bytes_per_second > 0 || bytes_per_second == -1);
mutex_t::scoped_lock l(m_mutex);
INVARIANT_CHECK;
if (bytes_per_second <= 0) bytes_per_second = bandwidth_limit::inf;
m_bandwidth_manager[peer_connection::download_channel]->throttle(bytes_per_second);
}
@ -2013,6 +2037,9 @@ namespace detail
{
assert(bytes_per_second > 0 || bytes_per_second == -1);
mutex_t::scoped_lock l(m_mutex);
INVARIANT_CHECK;
if (bytes_per_second <= 0) bytes_per_second = bandwidth_limit::inf;
m_bandwidth_manager[peer_connection::upload_channel]->throttle(bytes_per_second);
}
@ -2020,6 +2047,10 @@ namespace detail
std::auto_ptr<alert> session_impl::pop_alert()
{
mutex_t::scoped_lock l(m_mutex);
// too expensive
// INVARIANT_CHECK;
if (m_alerts.pending())
return m_alerts.get();
return std::auto_ptr<alert>(0);
@ -2034,20 +2065,26 @@ namespace detail
int session_impl::upload_rate_limit() const
{
mutex_t::scoped_lock l(m_mutex);
INVARIANT_CHECK;
int ret = m_bandwidth_manager[peer_connection::upload_channel]->throttle();
return ret == std::numeric_limits<int>::max() ? -1 : ret;
return ret == (std::numeric_limits<int>::max)() ? -1 : ret;
}
int session_impl::download_rate_limit() const
{
mutex_t::scoped_lock l(m_mutex);
int ret = m_bandwidth_manager[peer_connection::download_channel]->throttle();
return ret == std::numeric_limits<int>::max() ? -1 : ret;
return ret == (std::numeric_limits<int>::max)() ? -1 : ret;
}
void session_impl::start_lsd()
{
mutex_t::scoped_lock l(m_mutex);
INVARIANT_CHECK;
m_lsd.reset(new lsd(m_io_service
, m_listen_interface.address()
, bind(&session_impl::on_lsd_peer, this, _1, _2)));
@ -2056,6 +2093,9 @@ namespace detail
void session_impl::start_natpmp()
{
mutex_t::scoped_lock l(m_mutex);
INVARIANT_CHECK;
m_natpmp.reset(new natpmp(m_io_service
, m_listen_interface.address()
, bind(&session_impl::on_port_mapping
@ -2071,6 +2111,9 @@ namespace detail
void session_impl::start_upnp()
{
mutex_t::scoped_lock l(m_mutex);
INVARIANT_CHECK;
m_upnp.reset(new upnp(m_io_service, m_half_open
, m_listen_interface.address()
, m_settings.user_agent
@ -2108,14 +2151,13 @@ namespace detail
#ifndef NDEBUG
void session_impl::check_invariant(const char *place)
void session_impl::check_invariant() const
{
assert(m_max_connections > 0);
assert(m_max_uploads > 0);
assert(place);
int unchokes = 0;
int num_optimistic = 0;
for (connection_map::iterator i = m_connections.begin();
for (connection_map::const_iterator i = m_connections.begin();
i != m_connections.end(); ++i)
{
assert(i->second);
@ -2124,14 +2166,20 @@ namespace detail
if (!i->second->is_choked()) ++unchokes;
if (i->second->peer_info_struct()
&& i->second->peer_info_struct()->optimistically_unchoked)
{
++num_optimistic;
if (t)
assert(!i->second->is_choked());
}
if (t && i->second->peer_info_struct())
{
assert(t->get_policy().has_connection(boost::get_pointer(i->second)));
}
}
assert(num_optimistic == 0 || num_optimistic == 1);
assert(m_num_unchoked == unchokes);
if (m_num_unchoked != unchokes)
{
assert(false);
}
}
#endif

View File

@ -155,11 +155,11 @@ namespace libtorrent
, tcp::endpoint const& net_interface
, bool compact_mode
, int block_size
, session_settings const& s
, storage_constructor_type sc)
, storage_constructor_type sc
, bool paused)
: m_torrent_file(tf)
, m_abort(false)
, m_paused(false)
, m_paused(paused)
, m_just_paused(false)
, m_event(tracker_request::started)
, m_block_size(0)
@ -197,11 +197,11 @@ namespace libtorrent
, m_compact_mode(compact_mode)
, m_default_block_size(block_size)
, m_connections_initialized(true)
, m_settings(s)
, m_settings(ses.settings())
, m_storage_constructor(sc)
, m_max_uploads(std::numeric_limits<int>::max())
, m_max_uploads((std::numeric_limits<int>::max)())
, m_num_uploads(0)
, m_max_connections(std::numeric_limits<int>::max())
, m_max_connections((std::numeric_limits<int>::max)())
{
#ifndef NDEBUG
m_initial_done = 0;
@ -219,11 +219,11 @@ namespace libtorrent
, tcp::endpoint const& net_interface
, bool compact_mode
, int block_size
, session_settings const& s
, storage_constructor_type sc)
, storage_constructor_type sc
, bool paused)
: m_torrent_file(info_hash)
, m_abort(false)
, m_paused(false)
, m_paused(paused)
, m_just_paused(false)
, m_event(tracker_request::started)
, m_block_size(0)
@ -260,11 +260,11 @@ namespace libtorrent
, m_compact_mode(compact_mode)
, m_default_block_size(block_size)
, m_connections_initialized(false)
, m_settings(s)
, m_settings(ses.settings())
, m_storage_constructor(sc)
, m_max_uploads(std::numeric_limits<int>::max())
, m_max_uploads((std::numeric_limits<int>::max)())
, m_num_uploads(0)
, m_max_connections(std::numeric_limits<int>::max())
, m_max_connections((std::numeric_limits<int>::max)())
{
#ifndef NDEBUG
m_initial_done = 0;
@ -2459,14 +2459,14 @@ namespace libtorrent
void torrent::set_max_uploads(int limit)
{
assert(limit >= -1);
if (limit <= 0) limit = std::numeric_limits<int>::max();
if (limit <= 0) limit = (std::numeric_limits<int>::max)();
m_max_uploads = limit;
}
void torrent::set_max_connections(int limit)
{
assert(limit >= -1);
if (limit <= 0) limit = std::numeric_limits<int>::max();
if (limit <= 0) limit = (std::numeric_limits<int>::max)();
m_max_connections = limit;
}
@ -2489,7 +2489,7 @@ namespace libtorrent
void torrent::set_upload_limit(int limit)
{
assert(limit >= -1);
if (limit <= 0) limit = std::numeric_limits<int>::max();
if (limit <= 0) limit = (std::numeric_limits<int>::max)();
if (limit < num_peers() * 10) limit = num_peers() * 10;
m_bandwidth_limit[peer_connection::upload_channel].throttle(limit);
}
@ -2497,14 +2497,14 @@ namespace libtorrent
int torrent::upload_limit() const
{
int limit = m_bandwidth_limit[peer_connection::upload_channel].throttle();
if (limit == std::numeric_limits<int>::max()) limit = -1;
if (limit == (std::numeric_limits<int>::max)()) limit = -1;
return limit;
}
void torrent::set_download_limit(int limit)
{
assert(limit >= -1);
if (limit <= 0) limit = std::numeric_limits<int>::max();
if (limit <= 0) limit = (std::numeric_limits<int>::max)();
if (limit < num_peers() * 10) limit = num_peers() * 10;
m_bandwidth_limit[peer_connection::download_channel].throttle(limit);
}
@ -2512,7 +2512,7 @@ namespace libtorrent
int torrent::download_limit() const
{
int limit = m_bandwidth_limit[peer_connection::download_channel].throttle();
if (limit == std::numeric_limits<int>::max()) limit = -1;
if (limit == (std::numeric_limits<int>::max)()) limit = -1;
return limit;
}

View File

@ -674,7 +674,7 @@ namespace libtorrent
{
assert(m_piece_length > 0);
if ((m_urls.empty() && m_nodes.empty()) || m_files.empty())
if (m_files.empty())
{
// TODO: throw something here
// throw

View File

@ -510,7 +510,7 @@ namespace libtorrent
// m_piece as buffer.
int piece_size = int(m_piece.size());
int copy_size = (std::min)(std::min(front_request.length - piece_size
int copy_size = (std::min)((std::min)(front_request.length - piece_size
, recv_buffer.left()), int(range_end - range_start - m_received_body));
m_piece.resize(piece_size + copy_size);
assert(copy_size > 0);
@ -568,7 +568,7 @@ namespace libtorrent
&& (m_received_body + recv_buffer.left() >= range_end - range_start))
{
int piece_size = int(m_piece.size());
int copy_size = (std::min)(std::min(m_requests.front().length - piece_size
int copy_size = (std::min)((std::min)(m_requests.front().length - piece_size
, recv_buffer.left()), int(range_end - range_start - m_received_body));
assert(copy_size >= 0);
if (copy_size > 0)