mirror of
https://github.com/kunkunsh/kunkun-ext-neohtop.git
synced 2025-04-11 17:29:45 +00:00
fix tokio dead lock
This commit is contained in:
parent
98e99db260
commit
6cc3657e85
@ -43,28 +43,67 @@ struct SystemStats {
|
|||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn get_processes(state: State<'_, AppState>) -> Result<(Vec<ProcessInfo>, SystemStats), String> {
|
async fn get_processes(state: State<'_, AppState>) -> Result<(Vec<ProcessInfo>, SystemStats), String> {
|
||||||
let mut sys = state.sys.lock().map_err(|_| "Failed to lock system state")?;
|
let processes_data;
|
||||||
let mut process_cache = state.process_cache.lock().map_err(|_| "Failed to lock process cache")?;
|
let system_stats;
|
||||||
|
|
||||||
// Batch refresh system information
|
// Scope for system lock
|
||||||
sys.refresh_all();
|
{
|
||||||
|
let mut sys = state.sys.lock().map_err(|_| "Failed to lock system state")?;
|
||||||
|
sys.refresh_all();
|
||||||
|
|
||||||
|
// Collect all the process data we need while holding sys lock
|
||||||
|
processes_data = sys
|
||||||
|
.processes()
|
||||||
|
.iter()
|
||||||
|
.map(|(pid, process)| {
|
||||||
|
(
|
||||||
|
pid.as_u32(),
|
||||||
|
process.name().to_string(),
|
||||||
|
process.cmd().to_vec(),
|
||||||
|
process.user_id().map(|uid| uid.to_string()),
|
||||||
|
process.cpu_usage(),
|
||||||
|
process.memory(),
|
||||||
|
process.status(),
|
||||||
|
process.parent().map(|p| p.as_u32()),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let processes = sys.processes()
|
// Get system stats while we still have the sys lock
|
||||||
.iter()
|
let cpu_usage: Vec<f32> = sys.cpus().iter().map(|cpu| cpu.cpu_usage()).collect();
|
||||||
.map(|(pid, process)| {
|
let load_avg = sys.load_average();
|
||||||
let pid_u32 = pid.as_u32();
|
let memory_total = sys.total_memory();
|
||||||
|
let memory_used = sys.used_memory();
|
||||||
// Get or update cache for static process info
|
let memory_free = memory_total - memory_used;
|
||||||
let static_info = process_cache.entry(pid_u32).or_insert_with(|| {
|
let memory_cached = memory_total - (memory_used + memory_free); // Estimated
|
||||||
|
|
||||||
|
system_stats = SystemStats {
|
||||||
|
cpu_usage,
|
||||||
|
memory_total,
|
||||||
|
memory_used,
|
||||||
|
memory_free,
|
||||||
|
memory_cached,
|
||||||
|
uptime: sys.uptime(),
|
||||||
|
load_avg: [load_avg.one, load_avg.five, load_avg.fifteen],
|
||||||
|
};
|
||||||
|
} // sys lock is automatically dropped here
|
||||||
|
|
||||||
|
// Now lock the process cache
|
||||||
|
let mut process_cache = state.process_cache.lock().map_err(|_| "Failed to lock process cache")?;
|
||||||
|
|
||||||
|
// Build the process info list
|
||||||
|
let processes = processes_data
|
||||||
|
.into_iter()
|
||||||
|
.map(|(pid, name, cmd, user_id, cpu_usage, memory, status, ppid)| {
|
||||||
|
let static_info = process_cache.entry(pid).or_insert_with(|| {
|
||||||
ProcessStaticInfo {
|
ProcessStaticInfo {
|
||||||
name: process.name().to_string(),
|
name: name.clone(),
|
||||||
command: process.cmd().join(" "),
|
command: cmd.join(" "),
|
||||||
user: process.user_id()
|
user: user_id.unwrap_or_else(|| "-".to_string()),
|
||||||
.map_or_else(|| "-".to_string(), |uid| uid.to_string()),
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let status = match process.status() {
|
let status_str = match status {
|
||||||
ProcessStatus::Run => "Running",
|
ProcessStatus::Run => "Running",
|
||||||
ProcessStatus::Sleep => "Sleeping",
|
ProcessStatus::Sleep => "Sleeping",
|
||||||
ProcessStatus::Idle => "Idle",
|
ProcessStatus::Idle => "Idle",
|
||||||
@ -72,12 +111,12 @@ async fn get_processes(state: State<'_, AppState>) -> Result<(Vec<ProcessInfo>,
|
|||||||
};
|
};
|
||||||
|
|
||||||
ProcessInfo {
|
ProcessInfo {
|
||||||
pid: pid_u32,
|
pid,
|
||||||
ppid: process.parent().unwrap_or(sysinfo::Pid::from(0)).as_u32(),
|
ppid: ppid.unwrap_or(0),
|
||||||
name: static_info.name.clone(),
|
name: static_info.name.clone(),
|
||||||
cpu_usage: process.cpu_usage(),
|
cpu_usage,
|
||||||
memory_usage: process.memory(),
|
memory_usage: memory,
|
||||||
status: status.to_string(),
|
status: status_str.to_string(),
|
||||||
user: static_info.user.clone(),
|
user: static_info.user.clone(),
|
||||||
command: static_info.command.clone(),
|
command: static_info.command.clone(),
|
||||||
threads: None,
|
threads: None,
|
||||||
@ -85,19 +124,6 @@ async fn get_processes(state: State<'_, AppState>) -> Result<(Vec<ProcessInfo>,
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let memory_cached = sys.available_memory() - sys.free_memory();
|
|
||||||
|
|
||||||
let load_avg = sys.load_average();
|
|
||||||
let system_stats = SystemStats {
|
|
||||||
cpu_usage: sys.cpus().iter().map(|cpu| cpu.cpu_usage()).collect(),
|
|
||||||
memory_total: sys.total_memory(),
|
|
||||||
memory_used: sys.used_memory(),
|
|
||||||
memory_free: sys.available_memory(),
|
|
||||||
memory_cached,//FIXME: get accurate value
|
|
||||||
uptime: sys.uptime(),
|
|
||||||
load_avg: [load_avg.one, load_avg.five, load_avg.fifteen],
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok((processes, system_stats))
|
Ok((processes, system_stats))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import AppInfo from "./AppInfo.svelte";
|
import AppInfo from "./AppInfo.svelte";
|
||||||
import { statusMap } from "$lib/utils";
|
import { statusMap } from "$lib/utils";
|
||||||
|
|
||||||
export let searchTerm: string;
|
export let searchTerm: string;
|
||||||
export let statusFilter: string = "all";
|
export let statusFilter: string = "all";
|
||||||
export let itemsPerPage: number;
|
export let itemsPerPage: number;
|
||||||
@ -155,7 +154,9 @@
|
|||||||
disabled={isFrozen}
|
disabled={isFrozen}
|
||||||
>
|
>
|
||||||
{#each refreshRateOptions as option}
|
{#each refreshRateOptions as option}
|
||||||
<option value={option.value}>{option.label} refresh</option>
|
<option value={option.value}>
|
||||||
|
{option.label}
|
||||||
|
</option>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
<button
|
<button
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
let processToKill: Process | null = null;
|
let processToKill: Process | null = null;
|
||||||
let isKilling = false;
|
let isKilling = false;
|
||||||
let statusFilter = "all";
|
let statusFilter = "all";
|
||||||
let refreshRate = 5000;
|
let refreshRate = 1000;
|
||||||
let isFrozen = false;
|
let isFrozen = false;
|
||||||
|
|
||||||
let columns: Column[] = [
|
let columns: Column[] = [
|
||||||
|
Loading…
x
Reference in New Issue
Block a user