From bc3c0fa93622e498d07cd01f6f40e3d5a9120c05 Mon Sep 17 00:00:00 2001 From: Tom Date: Sun, 3 Jan 2021 10:08:51 -0700 Subject: [PATCH] LibCore: Allow caching and reusing the ProcFS file descriptors Because ProcFS will refresh the data upon seek to 0, we can re-use the same file descriptor. This saves us from having to open it every time, but it also reduces the odds that we are unable to open a new file descriptor due to low memory conditions. --- Libraries/LibCore/ProcessStatisticsReader.cpp | 25 ++++++++++++++----- Libraries/LibCore/ProcessStatisticsReader.h | 2 ++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/Libraries/LibCore/ProcessStatisticsReader.cpp b/Libraries/LibCore/ProcessStatisticsReader.cpp index 53312872af..566053d3af 100644 --- a/Libraries/LibCore/ProcessStatisticsReader.cpp +++ b/Libraries/LibCore/ProcessStatisticsReader.cpp @@ -37,17 +37,24 @@ namespace Core { HashMap ProcessStatisticsReader::s_usernames; -Optional> ProcessStatisticsReader::get_all() +Optional> ProcessStatisticsReader::get_all(RefPtr& proc_all_file) { - auto file = Core::File::construct("/proc/all"); - if (!file->open(Core::IODevice::ReadOnly)) { - fprintf(stderr, "ProcessStatisticsReader: Failed to open /proc/all: %s\n", file->error_string()); - return {}; + if (proc_all_file) { + if (!proc_all_file->seek(0, Core::File::SeekMode::SetPosition)) { + fprintf(stderr, "ProcessStatisticsReader: Failed to refresh /proc/all: %s\n", proc_all_file->error_string()); + return {}; + } + } else { + proc_all_file = Core::File::construct("/proc/all"); + if (!proc_all_file->open(Core::IODevice::ReadOnly)) { + fprintf(stderr, "ProcessStatisticsReader: Failed to open /proc/all: %s\n", proc_all_file->error_string()); + return {}; + } } HashMap map; - auto file_contents = file->read_all(); + auto file_contents = proc_all_file->read_all(); auto json = JsonValue::from_string(file_contents); if (!json.has_value()) return {}; @@ -112,6 +119,12 @@ Optional> ProcessStatisticsReader::get_a return map; } +Optional> ProcessStatisticsReader::get_all() +{ + RefPtr proc_all_file; + return get_all(proc_all_file); +} + String ProcessStatisticsReader::username_from_uid(uid_t uid) { if (s_usernames.is_empty()) { diff --git a/Libraries/LibCore/ProcessStatisticsReader.h b/Libraries/LibCore/ProcessStatisticsReader.h index 02519e83f6..b6e506cd9d 100644 --- a/Libraries/LibCore/ProcessStatisticsReader.h +++ b/Libraries/LibCore/ProcessStatisticsReader.h @@ -28,6 +28,7 @@ #include #include +#include #include namespace Core { @@ -86,6 +87,7 @@ struct ProcessStatistics { class ProcessStatisticsReader { public: + static Optional> get_all(RefPtr&); static Optional> get_all(); private: