added upload mode
This commit is contained in:
@@ -2374,7 +2374,7 @@ namespace libtorrent
|
||||
++m_queued_time_critical;
|
||||
}
|
||||
|
||||
void peer_connection::add_request(piece_block const& block, bool time_critical)
|
||||
bool peer_connection::add_request(piece_block const& block, bool time_critical)
|
||||
{
|
||||
// INVARIANT_CHECK;
|
||||
|
||||
@@ -2393,6 +2393,8 @@ namespace libtorrent
|
||||
TORRENT_ASSERT(std::find(m_request_queue.begin(), m_request_queue.end()
|
||||
, block) == m_request_queue.end());
|
||||
|
||||
if (t->upload_mode()) return false;
|
||||
|
||||
piece_picker::piece_state_t state;
|
||||
peer_speed_t speed = peer_speed();
|
||||
char const* speedmsg = 0;
|
||||
@@ -2413,7 +2415,7 @@ namespace libtorrent
|
||||
}
|
||||
|
||||
if (!t->picker().mark_as_downloading(block, peer_info_struct(), state))
|
||||
return;
|
||||
return false;
|
||||
|
||||
if (t->alerts().should_post<block_downloading_alert>())
|
||||
{
|
||||
@@ -2431,6 +2433,53 @@ namespace libtorrent
|
||||
{
|
||||
m_request_queue.push_back(block);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void peer_connection::cancel_all_requests()
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||
// this peer might be disconnecting
|
||||
if (!t) return;
|
||||
|
||||
TORRENT_ASSERT(t->valid_metadata());
|
||||
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
(*m_logger) << time_now_string() << " *** CANCEL ALL REQUESTS\n";
|
||||
#endif
|
||||
|
||||
while (!m_request_queue.empty())
|
||||
{
|
||||
t->picker().abort_download(m_request_queue.back());
|
||||
m_request_queue.pop_back();
|
||||
}
|
||||
|
||||
for (std::vector<pending_block>::iterator i = m_download_queue.begin()
|
||||
, end(m_download_queue.end()); i != end; ++i)
|
||||
{
|
||||
piece_block b = i->block;
|
||||
|
||||
int block_offset = b.block_index * t->block_size();
|
||||
int block_size
|
||||
= (std::min)(t->torrent_file().piece_size(b.piece_index)-block_offset,
|
||||
t->block_size());
|
||||
TORRENT_ASSERT(block_size > 0);
|
||||
TORRENT_ASSERT(block_size <= t->block_size());
|
||||
|
||||
peer_request r;
|
||||
r.piece = b.piece_index;
|
||||
r.start = block_offset;
|
||||
r.length = block_size;
|
||||
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
(*m_logger) << time_now_string()
|
||||
<< " ==> CANCEL [ piece: " << b.piece_index << " | s: "
|
||||
<< block_offset << " | l: " << block_size << " | " << b.block_index << " ]\n";
|
||||
#endif
|
||||
write_cancel(r);
|
||||
}
|
||||
}
|
||||
|
||||
void peer_connection::cancel_request(piece_block const& block)
|
||||
@@ -2588,7 +2637,8 @@ namespace libtorrent
|
||||
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||
TORRENT_ASSERT(t);
|
||||
|
||||
if ((int)m_download_queue.size() >= m_desired_queue_size) return;
|
||||
if ((int)m_download_queue.size() >= m_desired_queue_size
|
||||
|| t->upload_mode()) return;
|
||||
|
||||
bool empty_download_queue = m_download_queue.empty();
|
||||
|
||||
|
@@ -193,6 +193,7 @@ namespace libtorrent
|
||||
{
|
||||
if (t.is_seed()) return;
|
||||
if (c.no_download()) return;
|
||||
if (t.upload_mode()) return;
|
||||
|
||||
TORRENT_ASSERT(t.valid_metadata());
|
||||
TORRENT_ASSERT(c.peer_info_struct() != 0 || !dynamic_cast<bt_peer_connection*>(&c));
|
||||
@@ -313,7 +314,7 @@ namespace libtorrent
|
||||
// ok, we found a piece that's not being downloaded
|
||||
// by somebody else. request it from this peer
|
||||
// and return
|
||||
c.add_request(*i);
|
||||
if (!c.add_request(*i)) continue;
|
||||
TORRENT_ASSERT(p.num_peers(*i) == 1);
|
||||
TORRENT_ASSERT(p.is_requested(*i));
|
||||
num_requests--;
|
||||
|
@@ -144,6 +144,7 @@ namespace libtorrent
|
||||
, m_total_downloaded(0)
|
||||
, m_started(time_now())
|
||||
, m_last_scrape(min_time())
|
||||
, m_upload_mode_time(time_now())
|
||||
, m_torrent_file(p.ti ? p.ti : new torrent_info(p.info_hash))
|
||||
, m_storage(0)
|
||||
, m_host_resolver(ses.m_io_service)
|
||||
@@ -180,6 +181,7 @@ namespace libtorrent
|
||||
, m_time_scaler(0)
|
||||
, m_abort(false)
|
||||
, m_paused(p.paused)
|
||||
, m_upload_mode(p.upload_mode)
|
||||
, m_auto_managed(p.auto_managed)
|
||||
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
||||
, m_resolving_country(false)
|
||||
@@ -341,6 +343,36 @@ namespace libtorrent
|
||||
}
|
||||
}
|
||||
|
||||
void torrent::set_upload_mode(bool b)
|
||||
{
|
||||
if (b == m_upload_mode) return;
|
||||
|
||||
m_upload_mode = b;
|
||||
|
||||
if (m_upload_mode)
|
||||
{
|
||||
// clear request queues of all peers
|
||||
for (std::set<peer_connection*>::iterator i = m_connections.begin()
|
||||
, end(m_connections.end()); i != end; ++i)
|
||||
{
|
||||
peer_connection* p = (*i);
|
||||
p->cancel_all_requests();
|
||||
}
|
||||
// this is used to try leaving upload only mode periodically
|
||||
m_upload_mode_time = time_now();
|
||||
}
|
||||
else
|
||||
{
|
||||
// send_block_requests on all peers
|
||||
for (std::set<peer_connection*>::iterator i = m_connections.begin()
|
||||
, end(m_connections.end()); i != end; ++i)
|
||||
{
|
||||
peer_connection* p = (*i);
|
||||
p->send_block_requests();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void torrent::handle_disk_error(disk_io_job const& j, peer_connection* c)
|
||||
{
|
||||
if (!j.error) return;
|
||||
@@ -389,20 +421,8 @@ namespace libtorrent
|
||||
// and the filesystem doesn't support sparse files, only zero the priorities
|
||||
// of the pieces that are at the tails of all files, leaving everything
|
||||
// up to the highest written piece in each file
|
||||
if (m_ses.settings().adjust_priority_on_disk_failure
|
||||
&& has_picker())
|
||||
{
|
||||
bool filter_updated = false;
|
||||
bool was_finished = is_finished();
|
||||
const int num_pieces = m_torrent_file->num_pieces();
|
||||
for (int i = 0; i < num_pieces; ++i)
|
||||
{
|
||||
filter_updated |= m_picker->set_piece_priority(i, 0);
|
||||
TORRENT_ASSERT(num_have() >= m_picker->num_have_filtered());
|
||||
}
|
||||
if (filter_updated) update_peer_interest(was_finished);
|
||||
return;
|
||||
}
|
||||
set_upload_mode(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// put the torrent in an error-state
|
||||
@@ -4897,6 +4917,8 @@ namespace libtorrent
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
ptime now = time_now();
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
for (extension_list_t::iterator i = m_extensions.begin()
|
||||
, end(m_extensions.end()); i != end; ++i)
|
||||
@@ -4932,6 +4954,15 @@ namespace libtorrent
|
||||
m_policy.pulse();
|
||||
}
|
||||
|
||||
// if we're in upload only mode and we're auto-managed
|
||||
// leave upload mode every 10 minutes hoping that the error
|
||||
// condition has been fixed
|
||||
if (m_upload_mode && m_auto_managed && now - m_upload_mode_time
|
||||
> seconds(m_settings.optimistic_disk_retry))
|
||||
{
|
||||
set_upload_mode(false);
|
||||
}
|
||||
|
||||
if (is_paused())
|
||||
{
|
||||
// let the stats fade out to 0
|
||||
@@ -4965,8 +4996,6 @@ namespace libtorrent
|
||||
if (is_seed()) m_seeding_time += since_last_tick;
|
||||
m_active_time += since_last_tick;
|
||||
|
||||
ptime now = time_now();
|
||||
|
||||
// ---- TIME CRITICAL PIECES ----
|
||||
|
||||
if (!m_time_critical_pieces.empty())
|
||||
@@ -5437,6 +5466,7 @@ namespace libtorrent
|
||||
{
|
||||
st.last_scrape = total_seconds(now - m_last_scrape);
|
||||
}
|
||||
st.upload_mode = m_upload_mode;
|
||||
st.up_bandwidth_queue = 0;
|
||||
st.down_bandwidth_queue = 0;
|
||||
|
||||
|
@@ -290,6 +290,12 @@ namespace libtorrent
|
||||
TORRENT_FORWARD(pause());
|
||||
}
|
||||
|
||||
void torrent_handle::set_upload_mode(bool b) const
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
TORRENT_FORWARD(set_upload_mode(b));
|
||||
}
|
||||
|
||||
void torrent_handle::save_resume_data() const
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
Reference in New Issue
Block a user