graphics/fbbootlogd: Remove workaround that prevents blocking on the graphics driver
Instead logd will no longer block on fbbootlogd to prevent the deadlock that this worked around.
This commit is contained in:
@@ -5,7 +5,6 @@ use libredox::errno::ESTALE;
|
||||
use orbclient::Event;
|
||||
use std::mem;
|
||||
use std::os::fd::BorrowedFd;
|
||||
use std::sync::mpsc::{self, Receiver, Sender};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::{io, os::unix::io::AsRawFd, slice};
|
||||
|
||||
@@ -35,12 +34,7 @@ pub struct DisplayMap {
|
||||
pub inner: graphics_ipc::v1::DisplayMap,
|
||||
}
|
||||
|
||||
enum DisplayCommand {
|
||||
SyncRects(Vec<Damage>),
|
||||
}
|
||||
|
||||
pub struct Display {
|
||||
cmd_tx: Sender<DisplayCommand>,
|
||||
pub map: Arc<Mutex<Option<DisplayMap>>>,
|
||||
}
|
||||
|
||||
@@ -67,13 +61,7 @@ impl Display {
|
||||
Self::handle_input_events(map_clone, input_handle);
|
||||
});
|
||||
|
||||
let (cmd_tx, cmd_rx) = mpsc::channel();
|
||||
let map_clone = map.clone();
|
||||
std::thread::spawn(move || {
|
||||
Self::handle_sync_rect(map_clone, cmd_rx);
|
||||
});
|
||||
|
||||
Ok(Self { cmd_tx, map })
|
||||
Ok(Self { map })
|
||||
}
|
||||
|
||||
fn handle_input_events(map: Arc<Mutex<Option<DisplayMap>>>, input_handle: ConsumerHandle) {
|
||||
@@ -129,26 +117,9 @@ impl Display {
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_sync_rect(map: Arc<Mutex<Option<DisplayMap>>>, cmd_rx: Receiver<DisplayCommand>) {
|
||||
while let Ok(cmd) = cmd_rx.recv() {
|
||||
match cmd {
|
||||
DisplayCommand::SyncRects(sync_rects) => {
|
||||
// We may not hold this lock across the write call to avoid deadlocking if the
|
||||
// graphics driver tries to write to the bootlog.
|
||||
let display_handle = if let Some(map) = &*map.lock().unwrap() {
|
||||
map.display_handle.clone()
|
||||
} else {
|
||||
continue;
|
||||
};
|
||||
display_handle.sync_rects(&sync_rects).unwrap();
|
||||
}
|
||||
}
|
||||
pub fn sync_rects(&mut self, sync_rects: Vec<Damage>) {
|
||||
if let Some(map) = &*self.map.lock().unwrap() {
|
||||
map.display_handle.sync_rects(&sync_rects).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sync_rects(&mut self, sync_rects: Vec<Damage>) {
|
||||
self.cmd_tx
|
||||
.send(DisplayCommand::SyncRects(sync_rects))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
//! Fbbootlogd renders the boot log and presents it on VT1.
|
||||
//!
|
||||
//! While fbbootlogd is superficially similar to fbcond, there are two major differences:
|
||||
//! While fbbootlogd is superficially similar to fbcond, the major difference is:
|
||||
//!
|
||||
//! * Fbbootlogd doesn't accept input coming from the keyboard. It only allows getting written to.
|
||||
//! * Writing to fbbootlogd will never block. Not even on the graphics driver or inputd. This makes
|
||||
//! it safe for graphics drivers and inputd to write to the boot log without risking deadlocks.
|
||||
//! Fbcond will block on the graphics driver during handoff and will continously block on inputd
|
||||
//! to get new input. Fbbootlogd does all blocking operations in background threads such that the
|
||||
//! main thread will always keep accepting new input and writing it to the framebuffer.
|
||||
//!
|
||||
//! In the future fbbootlogd may also pull from logd as opposed to have logd push logs to it. And it
|
||||
//! it could display a boot splash like plymouth instead of a boot log when booting in quiet mode.
|
||||
|
||||
use redox_scheme::{RequestKind, SignalBehavior, Socket};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user