Skip to content

Commit

Permalink
refactor: decouple tr_verify_worker from tr_torrent (transmission#6123)
Browse files Browse the repository at this point in the history
  • Loading branch information
ckerr authored Oct 19, 2023
1 parent bb125b5 commit 4bdb306
Show file tree
Hide file tree
Showing 9 changed files with 270 additions and 204 deletions.
2 changes: 1 addition & 1 deletion libtransmission/rpcimpl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ char const* torrentStop(tr_session* session, tr_variant* args_in, tr_variant* /*
{
for (auto* tor : getTorrents(session, args_in))
{
if (tor->is_running() || tor->is_queued() || tor->verify_state() != TR_VERIFY_NONE)
if (tor->activity() != TR_STATUS_STOPPED)
{
tor->is_stopping_ = true;
session->rpcNotify(TR_RPC_TORRENT_STOPPED, tor);
Expand Down
20 changes: 18 additions & 2 deletions libtransmission/session.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2004,6 +2004,24 @@ size_t tr_session::countQueueFreeSlots(tr_direction dir) const noexcept

// ---

void tr_session::verify_remove(tr_torrent const* const tor)
{
if (verifier_)
{
verifier_->remove(tor->info_hash());
}
}

void tr_session::verify_add(tr_torrent* const tor)
{
if (verifier_)
{
verifier_->add(std::make_unique<tr_torrent::VerifyMediator>(tor), tor->get_priority());
}
}

// ---

void tr_session::closeTorrentFiles(tr_torrent* tor) noexcept
{
this->cache->flush_torrent(tor);
Expand Down Expand Up @@ -2122,8 +2140,6 @@ tr_session::tr_session(std::string_view config_dir, tr_variant const& settings_d
stats().save();
});
save_timer_->start_repeating(SaveIntervalSecs);

verifier_->add_callback(tr_torrentOnVerifyDone);
}

void tr_session::addIncoming(tr_peer_socket&& socket)
Expand Down
17 changes: 2 additions & 15 deletions libtransmission/session.h
Original file line number Diff line number Diff line change
Expand Up @@ -888,21 +888,8 @@ struct tr_session
return settings_.ratio_limit;
}

void verifyRemove(tr_torrent* tor)
{
if (verifier_)
{
verifier_->remove(tor);
}
}

void verifyAdd(tr_torrent* tor)
{
if (verifier_)
{
verifier_->add(tor);
}
}
void verify_add(tr_torrent* tor);
void verify_remove(tr_torrent const* tor);

void fetch(tr_web::FetchOptions&& options) const
{
Expand Down
16 changes: 16 additions & 0 deletions libtransmission/torrent-ctor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ struct tr_ctor

std::vector<char> contents;

tr_torrent::VerifyDoneCallback verify_done_callback_;

explicit tr_ctor(tr_session const* session_in)
: session{ session_in }
{
Expand All @@ -68,6 +70,20 @@ struct tr_ctor

// ---

void tr_ctorSetVerifyDoneCallback(tr_ctor* ctor, tr_torrent::VerifyDoneCallback&& callback)
{
ctor->verify_done_callback_ = std::move(callback);
}

tr_torrent::VerifyDoneCallback tr_ctorStealVerifyDoneCallback(tr_ctor* ctor)
{
auto tmp = tr_torrent::VerifyDoneCallback{};
std::swap(ctor->verify_done_callback_, tmp);
return tmp;
}

// ---

bool tr_ctorSetMetainfoFromFile(tr_ctor* ctor, std::string_view filename, tr_error** error)
{
if (std::empty(filename))
Expand Down
96 changes: 79 additions & 17 deletions libtransmission/torrent.cc
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,7 @@ void removeTorrentInSessionThread(tr_torrent* tor, bool delete_flag, tr_fileFunc
{
// ensure the files are all closed and idle before moving
tor->session->closeTorrentFiles(tor);
tor->session->verifyRemove(tor);
tor->session->verify_remove(tor);

if (delete_func == nullptr)
{
Expand Down Expand Up @@ -829,7 +829,7 @@ void torrentStop(tr_torrent* const tor)
tr_logAddInfoTor(tor, _("Pausing torrent"));
}

tor->session->verifyRemove(tor);
tor->session->verify_remove(tor);

tor->stopped_.emit(tor);
tor->session->announcer_->stopTorrent(tor);
Expand Down Expand Up @@ -1172,6 +1172,7 @@ tr_torrent* tr_torrentNew(tr_ctor* ctor, tr_torrent** setme_duplicate_of)
}

auto* const tor = new tr_torrent{ std::move(metainfo) };
tor->verify_done_callback_ = tr_ctorStealVerifyDoneCallback(ctor);
torrentInit(tor, ctor);
return tor;
}
Expand Down Expand Up @@ -1202,7 +1203,7 @@ void setLocationInSessionThread(

// ensure the files are all closed and idle before moving
tor->session->closeTorrentFiles(tor);
tor->session->verifyRemove(tor);
tor->session->verify_remove(tor);

tr_error* error = nullptr;
ok = tor->metainfo_.files().move(tor->current_dir(), path, setme_progress, tor->name(), &error);
Expand Down Expand Up @@ -1689,7 +1690,7 @@ void verifyTorrent(tr_torrent* const tor, bool force)
}

/* if the torrent's already being verified, stop it */
tor->session->verifyRemove(tor);
tor->session->verify_remove(tor);

if (!tor->has_metainfo())
{
Expand All @@ -1703,38 +1704,99 @@ void verifyTorrent(tr_torrent* const tor, bool force)

if (force || !setLocalErrorIfFilesDisappeared(tor))
{
tor->session->verifyAdd(tor);
tor->session->verify_add(tor);
}
}
} // namespace verify_helpers
} // namespace

void tr_torrentOnVerifyDone(tr_torrent* tor, bool aborted)
void tr_torrentVerify(tr_torrent* tor, bool force)
{
using namespace verify_helpers;

if (aborted || tor->is_deleting_)
tor->session->runInSessionThread(verifyTorrent, tor, force);
}

void tr_torrent::set_verify_state(VerifyState const state)
{
TR_ASSERT(state == VerifyState::None || state == VerifyState::Queued || state == VerifyState::Active);

verify_state_ = state;
verify_progress_ = {};
mark_changed();
}

tr_torrent_metainfo const& tr_torrent::VerifyMediator::metainfo() const
{
return tor_->metainfo_;
}

std::optional<std::string> tr_torrent::VerifyMediator::find_file(tr_file_index_t const file_index) const
{
if (auto const found = tor_->find_file(file_index); found)
{
return;
return std::string{ found->filename().sv() };
}

tor->session->runInSessionThread(onVerifyDoneThreadFunc, tor);
return {};
}

void tr_torrentVerify(tr_torrent* tor, bool force)
void tr_torrent::VerifyMediator::on_verify_queued()
{
using namespace verify_helpers;
tr_logAddTraceTor(tor_, "Queued for verification");
tor_->set_verify_state(VerifyState::Queued);
}

tor->session->runInSessionThread(verifyTorrent, tor, force);
void tr_torrent::VerifyMediator::on_verify_started()
{
tr_logAddDebugTor(tor_, "Verifying torrent");
time_started_ = tr_time();
tor_->set_verify_state(VerifyState::Active);
}

void tr_torrent::set_verify_state(tr_verify_state state)
void tr_torrent::VerifyMediator::on_piece_checked(tr_piece_index_t const piece, bool const has_piece)
{
TR_ASSERT(state == TR_VERIFY_NONE || state == TR_VERIFY_WAIT || state == TR_VERIFY_NOW);
auto const had_piece = tor_->has_piece(piece);

this->verify_state_ = state;
this->verify_progress_ = {};
this->mark_changed();
if (has_piece || had_piece)
{
tor_->set_has_piece(piece, has_piece);
tor_->set_dirty();
}

tor_->checked_pieces_.set(piece, true);
tor_->mark_changed();
tor_->verify_progress_ = std::clamp(static_cast<float>(piece + 1U) / tor_->metainfo_.piece_count(), 0.0F, 1.0F);
}

void tr_torrent::VerifyMediator::on_verify_done(bool const aborted)
{
using namespace verify_helpers;

if (time_started_.has_value())
{
auto const total_size = tor_->total_size();
auto const duration_secs = tr_time() - *time_started_;
tr_logAddDebugTor(
tor_,
fmt::format(
"Verification is done. It took {} seconds to verify {} bytes ({} bytes per second)",
duration_secs,
total_size,
total_size / (1 + duration_secs)));
}

tor_->set_verify_state(VerifyState::None);

if (!aborted && !tor_->is_deleting_)
{
tor_->session->runInSessionThread(onVerifyDoneThreadFunc, tor_);
}

if (tor_->verify_done_callback_)
{
tor_->verify_done_callback_(tor_);
}
}

// ---
Expand Down
Loading

0 comments on commit 4bdb306

Please sign in to comment.