mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-18 15:16:17 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 83c32cea55 | |||
| ffaae64d83 |
@@ -10,6 +10,7 @@
|
||||
#include <torrent/utils/directory_events.h>
|
||||
|
||||
#include "core/dht_manager.h"
|
||||
#include "core/download_list.h"
|
||||
#include "core/http_queue.h"
|
||||
#include "core/manager.h"
|
||||
#include "core/view_manager.h"
|
||||
@@ -137,6 +138,15 @@ Control::handle_shutdown() {
|
||||
if (scgi_thread::thread()->is_active())
|
||||
scgi_thread::thread()->stop_thread_wait();
|
||||
|
||||
if (!m_shutdown_session_saved) {
|
||||
// Flush the latest state before stopped announces can consume the timeout. A shutdown hook may
|
||||
// already have queued these resume builds.
|
||||
m_core->download_list()->session_save();
|
||||
session_thread::manager()->flush_shutdown_saves();
|
||||
|
||||
m_shutdown_session_saved = true;
|
||||
}
|
||||
|
||||
if (!m_shutdown_quick) {
|
||||
torrent::runtime::network_manager()->listen_close();
|
||||
torrent::runtime::shutdown();
|
||||
|
||||
@@ -112,6 +112,8 @@ private:
|
||||
|
||||
int m_clear_requests_count{};
|
||||
|
||||
bool m_shutdown_session_saved{};
|
||||
|
||||
align_cacheline
|
||||
|
||||
std::atomic<bool> m_shutdown_received{};
|
||||
|
||||
@@ -405,42 +405,67 @@ SessionManager::process_finished_saves() {
|
||||
if (!m_active)
|
||||
throw torrent::internal_error("SessionManager::process_finished_saves() called while not active.");
|
||||
|
||||
for (auto& request : m_finished_saves) {
|
||||
try {
|
||||
request.first.get();
|
||||
|
||||
} catch (torrent::storage_error& e) {
|
||||
LT_LOG("error saving download : storage error :download:%p path:%s : %s", request.second.download, request.second.path.c_str(), e.what());
|
||||
|
||||
if (m_last_storage_error_message + std::chrono::minutes(5) > torrent::this_thread::cached_time()) {
|
||||
m_ignored_storage_error_count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
lt_log_print(torrent::LOG_ERRORS, "Storage errors saving session data for download: ignored:%u : %s", m_ignored_storage_error_count, e.what());
|
||||
|
||||
m_last_storage_error_message = torrent::this_thread::cached_time();
|
||||
m_ignored_storage_error_count = 0;
|
||||
|
||||
continue;
|
||||
|
||||
} catch (torrent::internal_error& e) {
|
||||
LT_LOG("error saving download : internal error : download:%p path:%s : %s", request.second.download, request.second.path.c_str(), e.what());
|
||||
throw;
|
||||
|
||||
} catch (...) {
|
||||
LT_LOG("error saving download : unknown error : download:%p path:%s", request.second.download, request.second.path.c_str());
|
||||
throw;
|
||||
}
|
||||
|
||||
LT_LOG("finished saving download : download:%p path:%s", request.second.download, request.second.path.c_str());
|
||||
}
|
||||
for (auto& request : m_finished_saves)
|
||||
consume_finished_save_unsafe(request);
|
||||
|
||||
m_finished_saves.clear();
|
||||
|
||||
callback_save_request();
|
||||
}
|
||||
|
||||
// Returns true when a storage error was suppressed.
|
||||
bool
|
||||
SessionManager::report_storage_error_unsafe(const std::string& msg) {
|
||||
if (m_last_storage_error_message + std::chrono::minutes(5) > torrent::this_thread::cached_time()) {
|
||||
m_ignored_storage_error_count++;
|
||||
return true;
|
||||
}
|
||||
|
||||
lt_log_print(torrent::LOG_ERRORS, "Storage errors saving session data for download: ignored:%u : %s", m_ignored_storage_error_count, msg.c_str());
|
||||
|
||||
m_last_storage_error_message = torrent::this_thread::cached_time();
|
||||
m_ignored_storage_error_count = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// The one policy for a finished save, on the session thread and in shutdown flushes: storage errors
|
||||
// go to report_storage_error_unsafe(), internal and unknown errors propagate.
|
||||
//
|
||||
// Returns true when a storage error was suppressed.
|
||||
bool
|
||||
SessionManager::consume_finished_save_unsafe(ProcessingSave& request) {
|
||||
try {
|
||||
request.first.get();
|
||||
|
||||
} catch (torrent::storage_error& e) {
|
||||
LT_LOG("error saving download : storage error :download:%p path:%s : %s", request.second.download, request.second.path.c_str(), e.what());
|
||||
return report_storage_error_unsafe(e.what());
|
||||
|
||||
} catch (torrent::internal_error& e) {
|
||||
LT_LOG("error saving download : internal error : download:%p path:%s : %s", request.second.download, request.second.path.c_str(), e.what());
|
||||
throw;
|
||||
|
||||
} catch (...) {
|
||||
LT_LOG("error saving download : unknown error : download:%p path:%s", request.second.download, request.second.path.c_str());
|
||||
throw;
|
||||
}
|
||||
|
||||
LT_LOG("finished saving download : download:%p path:%s", request.second.download, request.second.path.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
SessionManager::flush_shutdown_saves() {
|
||||
assert(torrent::this_thread::thread() == torrent::main_thread::thread());
|
||||
|
||||
flush_all_pending_builds();
|
||||
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
|
||||
flush_all_and_wait_unsafe(lock);
|
||||
}
|
||||
|
||||
void
|
||||
SessionManager::flush_all_and_wait_unsafe(std::unique_lock<std::mutex>& lock) {
|
||||
LT_LOG("flushing all pending saves", 0);
|
||||
@@ -459,11 +484,20 @@ SessionManager::flush_all_and_wait_unsafe(std::unique_lock<std::mutex>& lock) {
|
||||
while (!m_processing_saves.empty())
|
||||
m_finished_condition.wait(lock);
|
||||
|
||||
unsigned int suppressed = 0;
|
||||
|
||||
for (auto& request : m_finished_saves)
|
||||
LT_LOG("finished saving download : download:%p path:%s", request.second.download, request.second.path.c_str());
|
||||
suppressed += consume_finished_save_unsafe(request) ? 1 : 0;
|
||||
|
||||
m_finished_saves.clear();
|
||||
|
||||
if (m_ignored_storage_error_count != 0) {
|
||||
lt_log_print(torrent::LOG_ERRORS, "Storage errors flushing session data: ignored:%u previous:%u",
|
||||
suppressed, m_ignored_storage_error_count - suppressed);
|
||||
|
||||
m_ignored_storage_error_count = 0;
|
||||
}
|
||||
|
||||
LT_LOG("flushed all pending saves", 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -73,8 +73,10 @@ protected:
|
||||
void cleanup();
|
||||
|
||||
void flush_all_pending_builds();
|
||||
void flush_shutdown_saves();
|
||||
|
||||
private:
|
||||
|
||||
void callback_pending_builds();
|
||||
void callback_save_request();
|
||||
void callback_finished_saves();
|
||||
@@ -92,6 +94,9 @@ private:
|
||||
|
||||
using ProcessingSave = std::pair<std::future<void>, SaveRequest>;
|
||||
|
||||
bool consume_finished_save_unsafe(ProcessingSave& request);
|
||||
bool report_storage_error_unsafe(const std::string& msg);
|
||||
|
||||
torrent::system::Thread* m_thread;
|
||||
torrent::system::callback_id m_callback_id;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user