refactor: improve code readability and consistency across multiple files

This commit is contained in:
asepharyana
2026-07-20 12:02:50 +07:00
parent 4ced6681c2
commit 1ec2aa136a
17 changed files with 117 additions and 41 deletions
@@ -18,7 +18,15 @@ impl BashControl {
jobs: Mutex::new(HashMap::new()),
}
}
}
impl Default for BashControl {
fn default() -> Self {
Self::new()
}
}
impl BashControl {
/// Register a new background job.
pub fn register(&self, job: Arc<BashJob>) {
if let Ok(mut guard) = self.jobs.lock() {
+30 -12
View File
@@ -33,18 +33,38 @@ pub fn spawn_bash_job(cmd: String) -> Arc<BashJob> {
cancelled: AtomicBool::new(false),
});
// Spawn a monitor thread (in production this would use an async task)
// Spawn a monitor thread using try_wait() polling so the lock is never
// held across a blocking wait, allowing cancel() to acquire the lock.
let job_clone = Arc::clone(&job);
std::thread::spawn(move || {
let mut guard = match job_clone.process.lock() {
Ok(g) => g,
Err(poisoned) => {
error!("bgbash job mutex poisoned, recovering");
poisoned.into_inner()
loop {
let mut exited = false;
{
let mut guard = match job_clone.process.lock() {
Ok(g) => g,
Err(poisoned) => {
error!("bgbash job mutex poisoned, recovering");
poisoned.into_inner()
}
};
if let Some(ref mut child) = *guard {
match child.try_wait() {
Ok(Some(_)) => exited = true,
Ok(None) => {} // still running
Err(e) => {
error!("bgbash wait error: {e}");
exited = true;
}
}
} else {
exited = true; // no child process
}
} // lock is dropped here — cancel() can now acquire it
if exited || job_clone.cancelled.load(Ordering::SeqCst) {
break;
}
};
if let Some(ref mut child) = *guard {
let _ = child.wait();
std::thread::sleep(std::time::Duration::from_millis(50));
}
});
@@ -69,8 +89,6 @@ impl BashJob {
let Ok(mut guard) = self.process.lock() else {
return false;
};
guard.as_mut().map_or(false, |c| {
matches!(c.try_wait(), Ok(None))
})
guard.as_mut().is_some_and(|c| matches!(c.try_wait(), Ok(None)))
}
}