mirror of
https://github.com/aristocratos/btop.git
synced 2024-10-31 21:01:03 +01:00
Merge pull request #633 from crestfallnatwork/main
[fix] Made disks statvfs logic asynchronous.
This commit is contained in:
commit
1f72e56c7d
@ -29,6 +29,7 @@ tab-size = 4
|
|||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <arpa/inet.h> // for inet_ntop()
|
#include <arpa/inet.h> // for inet_ntop()
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <future>
|
||||||
|
|
||||||
#if !(defined(STATIC_BUILD) && defined(__GLIBC__))
|
#if !(defined(STATIC_BUILD) && defined(__GLIBC__))
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
@ -48,12 +49,17 @@ using std::numeric_limits;
|
|||||||
using std::round;
|
using std::round;
|
||||||
using std::streamsize;
|
using std::streamsize;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
using std::future;
|
||||||
|
using std::async;
|
||||||
|
using std::pair;
|
||||||
|
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
namespace rng = std::ranges;
|
namespace rng = std::ranges;
|
||||||
|
|
||||||
using namespace Tools;
|
using namespace Tools;
|
||||||
using namespace std::literals; // for operator""s
|
using namespace std::literals; // for operator""s
|
||||||
|
using namespace std::chrono_literals;
|
||||||
//? --------------------------------------------------- FUNCTIONS -----------------------------------------------------
|
//? --------------------------------------------------- FUNCTIONS -----------------------------------------------------
|
||||||
|
|
||||||
namespace Cpu {
|
namespace Cpu {
|
||||||
@ -939,6 +945,7 @@ namespace Mem {
|
|||||||
auto only_physical = Config::getB("only_physical");
|
auto only_physical = Config::getB("only_physical");
|
||||||
auto zfs_hide_datasets = Config::getB("zfs_hide_datasets");
|
auto zfs_hide_datasets = Config::getB("zfs_hide_datasets");
|
||||||
auto& disks = mem.disks;
|
auto& disks = mem.disks;
|
||||||
|
static unordered_flat_map<string, future<pair<disk_info, int>>> disks_stats_promises;
|
||||||
ifstream diskread;
|
ifstream diskread;
|
||||||
|
|
||||||
vector<string> filter;
|
vector<string> filter;
|
||||||
@ -1078,31 +1085,47 @@ namespace Mem {
|
|||||||
diskread.close();
|
diskread.close();
|
||||||
|
|
||||||
//? Get disk/partition stats
|
//? Get disk/partition stats
|
||||||
bool new_ignored = false;
|
for (auto it = disks.begin(); it != disks.end(); ) {
|
||||||
for (auto& [mountpoint, disk] : disks) {
|
auto &[mountpoint, disk] = *it;
|
||||||
if (std::error_code ec; not fs::exists(mountpoint, ec) or v_contains(ignore_list, mountpoint)) continue;
|
if (v_contains(ignore_list, mountpoint)) {
|
||||||
struct statvfs vfs;
|
it = disks.erase(it);
|
||||||
if (statvfs(mountpoint.c_str(), &vfs) < 0) {
|
|
||||||
Logger::warning("Failed to get disk/partition stats for mount \""+ mountpoint + "\" with statvfs error code: " + to_string(errno) + ". Ignoring...");
|
|
||||||
ignore_list.push_back(mountpoint);
|
|
||||||
new_ignored = true;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if(auto promises_it = disks_stats_promises.find(mountpoint); promises_it != disks_stats_promises.end()){
|
||||||
|
auto& promise = promises_it->second;
|
||||||
|
if(promise.valid() &&
|
||||||
|
promise.wait_for(0s) == std::future_status::timeout) {
|
||||||
|
++it;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto promise_res = promises_it->second.get();
|
||||||
|
if(promise_res.second != -1){
|
||||||
|
ignore_list.push_back(mountpoint);
|
||||||
|
Logger::warning("Failed to get disk/partition stats for mount \""+ mountpoint + "\" with statvfs error code: " + to_string(promise_res.second) + ". Ignoring...");
|
||||||
|
it = disks.erase(it);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto &updated_stats = promise_res.first;
|
||||||
|
disk.total = updated_stats.total;
|
||||||
|
disk.free = updated_stats.free;
|
||||||
|
disk.used = updated_stats.used;
|
||||||
|
disk.used_percent = updated_stats.used_percent;
|
||||||
|
disk.free_percent = updated_stats.free_percent;
|
||||||
|
}
|
||||||
|
disks_stats_promises[mountpoint] = async(std::launch::async, [mountpoint, &free_priv]() -> pair<disk_info, int> {
|
||||||
|
struct statvfs vfs;
|
||||||
|
disk_info disk;
|
||||||
|
if (statvfs(mountpoint.c_str(), &vfs) < 0) {
|
||||||
|
return pair{disk, errno};
|
||||||
|
}
|
||||||
disk.total = vfs.f_blocks * vfs.f_frsize;
|
disk.total = vfs.f_blocks * vfs.f_frsize;
|
||||||
disk.free = (free_priv ? vfs.f_bfree : vfs.f_bavail) * vfs.f_frsize;
|
disk.free = (free_priv ? vfs.f_bfree : vfs.f_bavail) * vfs.f_frsize;
|
||||||
disk.used = disk.total - disk.free;
|
disk.used = disk.total - disk.free;
|
||||||
disk.used_percent = round((double)disk.used * 100 / disk.total);
|
disk.used_percent = round((double)disk.used * 100 / disk.total);
|
||||||
disk.free_percent = 100 - disk.used_percent;
|
disk.free_percent = 100 - disk.used_percent;
|
||||||
}
|
return pair{disk, -1};
|
||||||
|
});
|
||||||
//? Remove any problematic disks added to the ignore_list
|
++it;
|
||||||
if (new_ignored) {
|
|
||||||
for (auto it = disks.begin(); it != disks.end();) {
|
|
||||||
if (v_contains(ignore_list, it->first))
|
|
||||||
it = disks.erase(it);
|
|
||||||
else
|
|
||||||
it++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//? Setup disks order in UI and add swap if enabled
|
//? Setup disks order in UI and add swap if enabled
|
||||||
|
Loading…
Reference in New Issue
Block a user