fix race condition in storage tick handling in disk_io_thread
This commit is contained in:
parent
a9044e4d97
commit
e79a7a08b9
|
@ -571,6 +571,7 @@ namespace aux {
|
||||||
// storages that have had write activity recently and will get ticked
|
// storages that have had write activity recently and will get ticked
|
||||||
// soon, for deferred actions (say, flushing partfile metadata)
|
// soon, for deferred actions (say, flushing partfile metadata)
|
||||||
std::vector<std::pair<time_point, std::weak_ptr<storage_interface>>> m_need_tick;
|
std::vector<std::pair<time_point, std::weak_ptr<storage_interface>>> m_need_tick;
|
||||||
|
std::mutex m_need_tick_mutex;
|
||||||
|
|
||||||
// this is protected by the completed_jobs_mutex. It's true whenever
|
// 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
|
// there's a call_job_handlers message in-flight to the network thread. We
|
||||||
|
|
|
@ -689,8 +689,11 @@ namespace libtorrent {
|
||||||
|
|
||||||
m_stats_counters.inc_stats_counter(counters::num_writing_threads, -1);
|
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});
|
std::lock_guard<std::mutex> l(m_need_tick_mutex);
|
||||||
|
if (!pe->storage->set_need_tick())
|
||||||
|
m_need_tick.push_back({aux::time_now() + minutes(2), pe->storage});
|
||||||
|
}
|
||||||
|
|
||||||
if (!failed)
|
if (!failed)
|
||||||
{
|
{
|
||||||
|
@ -1128,7 +1131,7 @@ namespace libtorrent {
|
||||||
|
|
||||||
std::shared_ptr<storage_interface> storage = j->storage;
|
std::shared_ptr<storage_interface> storage = j->storage;
|
||||||
|
|
||||||
// TODO: instead of doing this. pass in the settings to each storage_interface
|
// TODO: 4 instead of doing this. pass in the settings to each storage_interface
|
||||||
// call. Each disk thread could hold its most recent understanding of the settings
|
// call. Each disk thread could hold its most recent understanding of the settings
|
||||||
// in a shared_ptr, and update it every time it wakes up from a job. That way
|
// in a shared_ptr, and update it every time it wakes up from a job. That way
|
||||||
// each access to the settings won't require a std::mutex to be held.
|
// each access to the settings won't require a std::mutex to be held.
|
||||||
|
@ -1493,8 +1496,11 @@ namespace libtorrent {
|
||||||
m_stats_counters.inc_stats_counter(counters::disk_job_time, write_time);
|
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});
|
std::lock_guard<std::mutex> l(m_need_tick_mutex);
|
||||||
|
if (!j->storage->set_need_tick())
|
||||||
|
m_need_tick.push_back({aux::time_now() + minutes(2), j->storage});
|
||||||
|
}
|
||||||
|
|
||||||
return ret != j->d.io.buffer_size
|
return ret != j->d.io.buffer_size
|
||||||
? status_t::fatal_disk_error : status_t::no_error;
|
? status_t::fatal_disk_error : status_t::no_error;
|
||||||
|
@ -3100,11 +3106,19 @@ namespace libtorrent {
|
||||||
maybe_flush_write_blocks();
|
maybe_flush_write_blocks();
|
||||||
|
|
||||||
time_point const now = aux::time_now();
|
time_point const now = aux::time_now();
|
||||||
while (!m_need_tick.empty() && m_need_tick.front().first < now)
|
|
||||||
{
|
{
|
||||||
std::shared_ptr<storage_interface> st = m_need_tick.front().second.lock();
|
std::unique_lock<std::mutex> l2(m_need_tick_mutex);
|
||||||
m_need_tick.erase(m_need_tick.begin());
|
while (!m_need_tick.empty() && m_need_tick.front().first < now)
|
||||||
if (st) st->tick();
|
{
|
||||||
|
std::shared_ptr<storage_interface> st = m_need_tick.front().second.lock();
|
||||||
|
m_need_tick.erase(m_need_tick.begin());
|
||||||
|
if (st)
|
||||||
|
{
|
||||||
|
l2.unlock();
|
||||||
|
st->tick();
|
||||||
|
l2.lock();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (now > m_next_close_oldest_file)
|
if (now > m_next_close_oldest_file)
|
||||||
|
|
Loading…
Reference in New Issue