diff --git a/src/manager.cc b/src/manager.cc index 64457ccd9..e89bde202 100644 --- a/src/manager.cc +++ b/src/manager.cc @@ -110,6 +110,7 @@ Manager::receive_tick() { m_resource_manager->receive_tick(); m_chunk_manager->periodic_sync(); + m_file_manager->periodic_close_idle(); // To ensure the downloads get equal chance over time at using // various limited resources, like sockets for handshakes, cycle the diff --git a/src/torrent/data/file_manager.cc b/src/torrent/data/file_manager.cc index fcd4fe46d..12d644806 100644 --- a/src/torrent/data/file_manager.cc +++ b/src/torrent/data/file_manager.cc @@ -227,4 +227,30 @@ FileManager::evict_least_active_from_cache(unsigned int count) { return count; } +void +FileManager::periodic_close_idle() { + if (m_close_idle == 0 || empty()) + return; + + auto now = this_thread::cached_time(); + auto idle = std::chrono::seconds(m_close_idle); + + std::vector files; + + for (auto* file : *this) { + if (!file->is_open()) + continue; + + auto touched = std::chrono::microseconds(file->last_touched()); + + if (touched <= now && now - touched >= idle) + files.push_back(file); + } + + if (files.empty()) + return; + + close_files(files); +} + } // namespace torrent diff --git a/src/torrent/data/file_manager.h b/src/torrent/data/file_manager.h index 4732594cd..54b1c30b4 100644 --- a/src/torrent/data/file_manager.h +++ b/src/torrent/data/file_manager.h @@ -42,6 +42,10 @@ class LIBTORRENT_EXPORT FileManager : private std::vector { bool advise_random_hashing() const { return m_advise_random_hashing; } void set_advise_random_hashing(bool state) { m_advise_random_hashing = state; } + // Idle seconds before closing open FDs; 0 disables. + uint32_t close_idle() const { return m_close_idle; } + void set_close_idle(uint32_t seconds) { m_close_idle = seconds; } + bool open(File* file, bool hashing, int prot, int flags); void close(File* file); @@ -52,6 +56,8 @@ class LIBTORRENT_EXPORT FileManager : private std::vector { // void close_least_active(); + void periodic_close_idle(); + // Statistics: uint64_t files_opened_counter() const { return m_files_opened_counter; } uint64_t files_closed_counter() const { return m_files_closed_counter; } @@ -74,6 +80,7 @@ class LIBTORRENT_EXPORT FileManager : private std::vector { unsigned int evict_least_active_from_cache(unsigned int count); size_type m_max_open_files{}; + uint32_t m_close_idle{60}; bool m_advise_random{}; bool m_advise_random_hashing{};