From 400371eaf9bbde0f7240be84b24dde9e44091103 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 15 Mar 2025 16:23:51 +0100 Subject: [PATCH] logd: Don't block receiving log messages on writing previous ones This avoid a deadlock when the process logging things is directly or indirectly involved in receiving them too. Currently there is a workaround for a part of this problem in fbbootlogd, but doing it directly in logd is a lot simpler and catches more cases. --- logd/src/scheme.rs | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/logd/src/scheme.rs b/logd/src/scheme.rs index f50ce41769..5a605c2d3f 100644 --- a/logd/src/scheme.rs +++ b/logd/src/scheme.rs @@ -1,6 +1,8 @@ use std::collections::BTreeMap; use std::fs::File; use std::io::Write; +use std::mem; +use std::sync::mpsc::{self, Sender}; use redox_scheme::SchemeMut; use syscall::error::*; @@ -12,16 +14,27 @@ pub struct LogHandle { pub struct LogScheme { next_id: usize, - files: Vec, + output_tx: Sender>, handles: BTreeMap, pub current_pid: usize, } impl LogScheme { - pub fn new(files: Vec) -> Self { + pub fn new(mut files: Vec) -> Self { + let (output_tx, output_rx) = mpsc::channel::>(); + + std::thread::spawn(move || { + for line in output_rx { + for file in &mut files { + let _ = file.write(&line); + let _ = file.flush(); + } + } + }); + LogScheme { next_id: 0, - files, + output_tx, handles: BTreeMap::new(), current_pid: 0, } @@ -96,12 +109,7 @@ impl SchemeMut for LogScheme { handle_buf.push(b); if b == b'\n' { - for file in self.files.iter_mut() { - let _ = file.write(&handle_buf); - let _ = file.flush(); - } - - handle_buf.clear(); + self.output_tx.send(mem::take(handle_buf)).unwrap(); } i += 1;