remove explicit ticking of storage from the torrent. instead make the disk_io_thread do it automatically
This commit is contained in:
parent
c72053a75c
commit
3ff89f29d7
|
@ -79,8 +79,6 @@ namespace libtorrent
|
|||
virtual void async_set_file_priority(piece_manager* storage
|
||||
, std::vector<std::uint8_t> const& prio
|
||||
, std::function<void(disk_io_job const*)> handler) = 0;
|
||||
virtual void async_tick_torrent(piece_manager* storage
|
||||
, std::function<void(disk_io_job const*)> handler) = 0;
|
||||
|
||||
virtual void async_clear_piece(piece_manager* storage, int index
|
||||
, std::function<void(disk_io_job const*)> handler) = 0;
|
||||
|
|
|
@ -92,7 +92,6 @@ namespace libtorrent
|
|||
, trim_cache
|
||||
, file_priority
|
||||
, clear_piece
|
||||
, tick_storage
|
||||
, resolve_links
|
||||
|
||||
, num_job_ids
|
||||
|
|
|
@ -317,8 +317,6 @@ namespace libtorrent
|
|||
void async_set_file_priority(piece_manager* storage
|
||||
, std::vector<std::uint8_t> const& prio
|
||||
, std::function<void(disk_io_job const*)> handler) override;
|
||||
void async_tick_torrent(piece_manager* storage
|
||||
, std::function<void(disk_io_job const*)> handler) override;
|
||||
|
||||
void async_clear_piece(piece_manager* storage, int index
|
||||
, std::function<void(disk_io_job const*)> handler) override;
|
||||
|
@ -400,7 +398,6 @@ namespace libtorrent
|
|||
int do_trim_cache(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
int do_file_priority(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
int do_clear_piece(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
int do_tick(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
int do_resolve_links(disk_io_job* j, jobqueue_t& completed_jobs);
|
||||
|
||||
void call_job_handlers();
|
||||
|
@ -598,6 +595,10 @@ namespace libtorrent
|
|||
std::mutex m_completed_jobs_mutex;
|
||||
jobqueue_t m_completed_jobs;
|
||||
|
||||
// storages that have had write activity recently and will get ticked
|
||||
// soon, for deferred actions (say, flushing partfile metadata)
|
||||
std::vector<std::pair<time_point, std::weak_ptr<piece_manager>>> m_need_tick;
|
||||
|
||||
// this is protected by the completed_jobs_mutex. It's true whenever
|
||||
// there's a call_job_handlers message in-flight to the network thread. We
|
||||
// only ever keep one such message in flight at a time, and coalesce
|
||||
|
|
|
@ -560,6 +560,19 @@ namespace libtorrent
|
|||
|
||||
storage_interface* get_storage_impl() { return m_storage.get(); }
|
||||
|
||||
bool set_need_tick()
|
||||
{
|
||||
bool const prev = m_need_tick;
|
||||
m_need_tick = true;
|
||||
return prev;
|
||||
}
|
||||
|
||||
void tick()
|
||||
{
|
||||
m_need_tick = false;
|
||||
m_storage->tick();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// if error is set and return value is 'no_error' or 'need_full_check'
|
||||
|
@ -579,6 +592,8 @@ namespace libtorrent
|
|||
#endif
|
||||
file_storage const& m_files;
|
||||
|
||||
bool m_need_tick = false;
|
||||
|
||||
std::unique_ptr<storage_interface> m_storage;
|
||||
|
||||
// the reason for this to be a void pointer
|
||||
|
|
|
@ -381,8 +381,6 @@ namespace libtorrent
|
|||
, peer_request p);
|
||||
void on_disk_tick_done(disk_io_job const* j);
|
||||
|
||||
void schedule_storage_tick();
|
||||
|
||||
void set_progress_ppm(int p) { m_progress_ppm = p; }
|
||||
struct read_piece_struct
|
||||
{
|
||||
|
@ -1537,14 +1535,6 @@ namespace libtorrent
|
|||
// the number of bytes of padding files
|
||||
std::uint32_t m_padding:24;
|
||||
|
||||
// this is a second count-down to when we should tick the
|
||||
// storage for this torrent. Ticking the storage is used
|
||||
// to periodically flush the partfile metadata and possibly
|
||||
// other deferred flushing. Any disk operation starts this
|
||||
// counter (unless it's already counting down). 0 means no
|
||||
// ticking is needed.
|
||||
std::uint32_t m_storage_tick:8;
|
||||
|
||||
// ----
|
||||
|
||||
// the scrape data from the tracker response, this
|
||||
|
|
|
@ -201,7 +201,6 @@ const char* const job_action_name[] =
|
|||
"trim_cache",
|
||||
"set_file_priority",
|
||||
"clear_piece",
|
||||
"tick_storage",
|
||||
"resolve_links"
|
||||
};
|
||||
|
||||
|
|
|
@ -638,7 +638,7 @@ namespace libtorrent
|
|||
for (int i = 1; i <= num_blocks; ++i)
|
||||
{
|
||||
if (i < num_blocks && flushing[i] == flushing[i - 1] + 1) continue;
|
||||
int ret = pe->storage->get_storage_impl()->writev(
|
||||
int const ret = pe->storage->get_storage_impl()->writev(
|
||||
iov_start.first(i - flushing_start)
|
||||
, piece + flushing[flushing_start] / blocks_in_piece
|
||||
, (flushing[flushing_start] % blocks_in_piece) * block_size
|
||||
|
@ -650,6 +650,9 @@ namespace libtorrent
|
|||
|
||||
m_stats_counters.inc_stats_counter(counters::num_writing_threads, -1);
|
||||
|
||||
if (!pe->storage->set_need_tick())
|
||||
m_need_tick.push_back({aux::time_now() + minutes(2), pe->storage});
|
||||
|
||||
if (!failed)
|
||||
{
|
||||
TORRENT_PIECE_ASSERT(!error, pe);
|
||||
|
@ -1028,8 +1031,7 @@ namespace libtorrent
|
|||
&disk_io_thread::do_flush_storage,
|
||||
&disk_io_thread::do_trim_cache,
|
||||
&disk_io_thread::do_file_priority,
|
||||
&disk_io_thread::do_clear_piece,
|
||||
&disk_io_thread::do_tick,
|
||||
&disk_io_thread::do_clear_piece
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
@ -1431,7 +1433,7 @@ namespace libtorrent
|
|||
m_stats_counters.inc_stats_counter(counters::num_writing_threads, 1);
|
||||
|
||||
// the actual write operation
|
||||
int ret = j->storage->get_storage_impl()->writev(b
|
||||
int const ret = j->storage->get_storage_impl()->writev(b
|
||||
, j->piece, j->d.io.offset, file_flags, j->error);
|
||||
|
||||
m_stats_counters.inc_stats_counter(counters::num_writing_threads, -1);
|
||||
|
@ -1447,6 +1449,9 @@ namespace libtorrent
|
|||
m_stats_counters.inc_stats_counter(counters::disk_job_time, write_time);
|
||||
}
|
||||
|
||||
if (!j->storage->set_need_tick())
|
||||
m_need_tick.push_back({aux::time_now() + minutes(2), j->storage});
|
||||
|
||||
m_disk_cache.free_buffer(j->buffer.disk_block);
|
||||
j->buffer.disk_block = nullptr;
|
||||
|
||||
|
@ -1934,16 +1939,6 @@ namespace libtorrent
|
|||
add_fence_job(storage, j);
|
||||
}
|
||||
|
||||
void disk_io_thread::async_tick_torrent(piece_manager* storage
|
||||
, std::function<void(disk_io_job const*)> handler)
|
||||
{
|
||||
disk_io_job* j = allocate_job(disk_io_job::tick_storage);
|
||||
j->storage = storage->shared_from_this();
|
||||
j->callback = std::move(handler);
|
||||
|
||||
add_job(j);
|
||||
}
|
||||
|
||||
void disk_io_thread::async_clear_piece(piece_manager* storage, int index
|
||||
, std::function<void(disk_io_job const*)> handler)
|
||||
{
|
||||
|
@ -2752,13 +2747,6 @@ namespace libtorrent
|
|||
return retry_job;
|
||||
}
|
||||
|
||||
int disk_io_thread::do_tick(disk_io_job* j, jobqueue_t& /* completed_jobs */ )
|
||||
{
|
||||
// true means this storage wants more ticks, false
|
||||
// disables ticking (until it's enabled again)
|
||||
return j->storage->get_storage_impl()->tick();
|
||||
}
|
||||
|
||||
void disk_io_thread::add_fence_job(piece_manager* storage, disk_io_job* j
|
||||
, bool user_add)
|
||||
{
|
||||
|
@ -3019,6 +3007,14 @@ namespace libtorrent
|
|||
{
|
||||
// there's no need for all threads to be doing this
|
||||
maybe_flush_write_blocks();
|
||||
|
||||
time_point const now = aux::time_now();
|
||||
while (!m_need_tick.empty() && m_need_tick.front().first < now)
|
||||
{
|
||||
std::shared_ptr<piece_manager> st = m_need_tick.front().second.lock();
|
||||
m_need_tick.erase(m_need_tick.begin());
|
||||
if (st) st->tick();
|
||||
}
|
||||
}
|
||||
|
||||
execute_job(j);
|
||||
|
|
|
@ -2994,8 +2994,6 @@ namespace libtorrent
|
|||
return;
|
||||
}
|
||||
|
||||
t->schedule_storage_tick();
|
||||
|
||||
// in case the outstanding bytes just dropped down
|
||||
// to allow to receive more data
|
||||
setup_receive();
|
||||
|
|
|
@ -206,7 +206,6 @@ namespace libtorrent
|
|||
, m_apply_ip_filter((p.flags & add_torrent_params::flag_apply_ip_filter) != 0)
|
||||
, m_pending_active_change(false)
|
||||
, m_padding(0)
|
||||
, m_storage_tick(0)
|
||||
, m_incomplete(0xffffff)
|
||||
, m_announce_to_dht((p.flags & add_torrent_params::flag_paused) == 0)
|
||||
, m_in_state_updates(false)
|
||||
|
@ -1321,21 +1320,11 @@ namespace libtorrent
|
|||
picker().dec_refcount(piece, nullptr);
|
||||
}
|
||||
|
||||
void torrent::schedule_storage_tick()
|
||||
{
|
||||
// schedule a disk tick in 2 minutes or so
|
||||
if (m_storage_tick != 0) return;
|
||||
m_storage_tick = 120 + random(60);
|
||||
update_want_tick();
|
||||
}
|
||||
|
||||
void torrent::on_disk_write_complete(disk_io_job const* j
|
||||
, peer_request p) try
|
||||
{
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
|
||||
schedule_storage_tick();
|
||||
|
||||
m_stats_counters.inc_stats_counter(counters::queued_write_bytes, -p.length);
|
||||
|
||||
// std::fprintf(stderr, "torrent::on_disk_write_complete ret:%d piece:%d block:%d\n"
|
||||
|
@ -1370,16 +1359,6 @@ namespace libtorrent
|
|||
}
|
||||
catch (...) { handle_exception(); }
|
||||
|
||||
void torrent::on_disk_tick_done(disk_io_job const* j) try
|
||||
{
|
||||
if (j->ret && m_storage_tick == 0)
|
||||
{
|
||||
m_storage_tick = 120 + random(20);
|
||||
update_want_tick();
|
||||
}
|
||||
}
|
||||
catch (...) { handle_exception(); }
|
||||
|
||||
bool torrent::add_merkle_nodes(std::map<int, sha1_hash> const& nodes, int piece)
|
||||
{
|
||||
return m_torrent_file->add_merkle_nodes(nodes, piece);
|
||||
|
@ -7167,10 +7146,6 @@ namespace libtorrent
|
|||
|
||||
if (!m_connections.empty()) return true;
|
||||
|
||||
// there's a deferred storage tick waiting
|
||||
// to happen
|
||||
if (m_storage_tick) return true;
|
||||
|
||||
// we might want to connect web seeds
|
||||
if (!is_finished() && !m_web_seeds.empty() && m_files_checked)
|
||||
return true;
|
||||
|
@ -9129,18 +9104,6 @@ namespace libtorrent
|
|||
set_upload_mode(false);
|
||||
}
|
||||
|
||||
if (m_storage_tick > 0)
|
||||
{
|
||||
--m_storage_tick;
|
||||
if (m_storage_tick == 0 && m_storage)
|
||||
{
|
||||
m_ses.disk_thread().async_tick_torrent(&storage()
|
||||
, std::bind(&torrent::on_disk_tick_done
|
||||
, shared_from_this(), _1));
|
||||
update_want_tick();
|
||||
}
|
||||
}
|
||||
|
||||
if (is_paused() && !m_graceful_pause_mode)
|
||||
{
|
||||
// let the stats fade out to 0
|
||||
|
|
Loading…
Reference in New Issue