refactor: use a condition_variable when removing a torrent from the verifier thread (#4166)

This commit is contained in:
Charles Kerr 2022-11-13 23:11:48 -06:00 committed by GitHub
parent 855b782604
commit f9a6df6f41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 16 deletions

View File

@ -56,7 +56,7 @@ int tr_verify_worker::Node::compare(tr_verify_worker::Node const& that) const
return 0; return 0;
} }
bool tr_verify_worker::verifyTorrent(tr_torrent* tor, bool const* stop_flag) bool tr_verify_worker::verifyTorrent(tr_torrent* tor, std::atomic<bool>& stop_flag)
{ {
auto const begin = tr_time(); auto const begin = tr_time();
@ -74,7 +74,7 @@ bool tr_verify_worker::verifyTorrent(tr_torrent* tor, bool const* stop_flag)
tr_logAddDebugTor(tor, "verifying torrent..."); tr_logAddDebugTor(tor, "verifying torrent...");
while (!*stop_flag && piece < tor->pieceCount()) while (!stop_flag && piece < tor->pieceCount())
{ {
auto const file_length = tor->fileSize(file_index); auto const file_length = tor->fileSize(file_index);
@ -184,7 +184,12 @@ void tr_verify_worker::verifyThreadFunc()
{ {
auto const lock = std::lock_guard(verify_mutex_); auto const lock = std::lock_guard(verify_mutex_);
stop_current_ = false; if (stop_current_)
{
stop_current_ = false;
stop_current_cv_.notify_one();
}
if (std::empty(todo_)) if (std::empty(todo_))
{ {
current_node_.reset(); current_node_.reset();
@ -200,7 +205,7 @@ void tr_verify_worker::verifyThreadFunc()
auto* const tor = current_node_->torrent; auto* const tor = current_node_->torrent;
tr_logAddTraceTor(tor, "Verifying torrent"); tr_logAddTraceTor(tor, "Verifying torrent");
tor->setVerifyState(TR_VERIFY_NOW); tor->setVerifyState(TR_VERIFY_NOW);
auto const changed = verifyTorrent(tor, &stop_current_); auto const changed = verifyTorrent(tor, stop_current_);
tor->setVerifyState(TR_VERIFY_NONE); tor->setVerifyState(TR_VERIFY_NONE);
TR_ASSERT(tr_isTorrent(tor)); TR_ASSERT(tr_isTorrent(tor));
@ -238,18 +243,12 @@ void tr_verify_worker::remove(tr_torrent* tor)
{ {
TR_ASSERT(tr_isTorrent(tor)); TR_ASSERT(tr_isTorrent(tor));
verify_mutex_.lock(); auto lock = std::unique_lock(verify_mutex_);
if (current_node_ && current_node_->torrent == tor) if (current_node_ && current_node_->torrent == tor)
{ {
stop_current_ = true; stop_current_ = true;
stop_current_cv_.wait(lock, [this]() { return !stop_current_; });
while (stop_current_)
{
verify_mutex_.unlock();
tr_wait_msec(100);
verify_mutex_.lock();
}
} }
else else
{ {
@ -266,8 +265,6 @@ void tr_verify_worker::remove(tr_torrent* tor)
todo_.erase(iter); todo_.erase(iter);
} }
} }
verify_mutex_.unlock();
} }
tr_verify_worker::~tr_verify_worker() tr_verify_worker::~tr_verify_worker()

View File

@ -9,6 +9,8 @@
#error only libtransmission should #include this header. #error only libtransmission should #include this header.
#endif #endif
#include <atomic>
#include <condition_variable>
#include <cstdint> #include <cstdint>
#include <functional> #include <functional>
#include <list> #include <list>
@ -59,7 +61,7 @@ private:
} }
void verifyThreadFunc(); void verifyThreadFunc();
[[nodiscard]] static bool verifyTorrent(tr_torrent* tor, bool const* stop_flag); [[nodiscard]] static bool verifyTorrent(tr_torrent* tor, std::atomic<bool>& stop_flag);
std::list<callback_func> callbacks_; std::list<callback_func> callbacks_;
std::mutex verify_mutex_; std::mutex verify_mutex_;
@ -68,5 +70,7 @@ private:
std::optional<Node> current_node_; std::optional<Node> current_node_;
std::optional<std::thread::id> verify_thread_id_; std::optional<std::thread::id> verify_thread_id_;
bool stop_current_ = false;
std::atomic<bool> stop_current_ = false;
std::condition_variable stop_current_cv_;
}; };