graphics/fbbootlogd: Remove input events background thread

This commit is contained in:
bjorn3
2025-03-15 16:50:29 +01:00
parent 943cbe3707
commit 56808dbfb1
3 changed files with 79 additions and 64 deletions
+17 -39
View File
@@ -1,12 +1,11 @@
use event::{user_data, EventQueue};
use graphics_ipc::v1::{Damage, V1GraphicsHandle};
use inputd::ConsumerHandle;
use libredox::errno::ESTALE;
use orbclient::Event;
use std::mem;
use std::os::fd::BorrowedFd;
use std::sync::{Arc, Mutex};
use std::{io, os::unix::io::AsRawFd, slice};
use std::os::unix::io::AsRawFd;
use std::{io, slice};
fn read_to_slice<T: Copy>(
file: BorrowedFd,
@@ -24,18 +23,19 @@ fn read_to_slice<T: Copy>(
fn display_fd_map(display_handle: V1GraphicsHandle) -> io::Result<DisplayMap> {
let display_map = display_handle.map_display()?;
Ok(DisplayMap {
display_handle: Arc::new(display_handle),
display_handle,
inner: display_map,
})
}
pub struct DisplayMap {
display_handle: Arc<V1GraphicsHandle>,
display_handle: V1GraphicsHandle,
pub inner: graphics_ipc::v1::DisplayMap,
}
pub struct Display {
pub map: Arc<Mutex<Option<DisplayMap>>>,
pub input_handle: ConsumerHandle,
pub map: Option<DisplayMap>,
}
impl Display {
@@ -45,51 +45,28 @@ impl Display {
let map = match input_handle.open_display() {
Ok(display) => {
let display_handle = V1GraphicsHandle::from_file(display)?;
Arc::new(Mutex::new(Some(
Some(
display_fd_map(display_handle)
.unwrap_or_else(|e| panic!("failed to map display: {e}")),
)))
)
}
Err(err) => {
println!("fbbootlogd: No display present yet: {err}");
Arc::new(Mutex::new(None))
None
}
};
let map_clone = map.clone();
std::thread::spawn(move || {
Self::handle_input_events(map_clone, input_handle);
});
Ok(Self { map })
Ok(Self { input_handle, map })
}
fn handle_input_events(map: Arc<Mutex<Option<DisplayMap>>>, input_handle: ConsumerHandle) {
let event_queue = EventQueue::new().expect("fbbootlogd: failed to create event queue");
user_data! {
enum Source {
Input,
}
}
// FIXME listen for resize events from inputd and handle them
event_queue
.subscribe(
input_handle.inner().as_raw_fd() as usize,
Source::Input,
event::EventFlags::READ,
)
.expect("fbbootlogd: failed to subscribe to scheme events");
pub fn handle_input_events(&mut self) {
let mut events = [Event::new(); 16];
for Source::Input in event_queue.map(|event| event.unwrap().user_data) {
match read_to_slice(input_handle.inner(), &mut events) {
loop {
match read_to_slice(self.input_handle.inner(), &mut events) {
Err(err) if err.errno() == ESTALE => {
eprintln!("fbbootlogd: handoff requested");
let new_display_handle = match input_handle.open_display() {
let new_display_handle = match self.input_handle.open_display() {
Ok(display) => V1GraphicsHandle::from_file(display).unwrap(),
Err(err) => {
println!("fbbootlogd: No display present yet: {err}");
@@ -99,7 +76,7 @@ impl Display {
match display_fd_map(new_display_handle) {
Ok(ok) => {
*map.lock().unwrap() = Some(ok);
self.map = Some(ok);
eprintln!("fbbootlogd: handoff finished");
}
@@ -109,6 +86,7 @@ impl Display {
}
}
Ok(0) => break,
Ok(_count) => {}
Err(err) => {
panic!("fbbootlogd: error while reading events: {err}");
@@ -118,7 +96,7 @@ impl Display {
}
pub fn sync_rects(&mut self, sync_rects: Vec<Damage>) {
if let Some(map) = &*self.map.lock().unwrap() {
if let Some(map) = &self.map {
map.display_handle.sync_rects(&sync_rects).unwrap();
}
}
+60 -21
View File
@@ -7,6 +7,10 @@
//! 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 std::os::fd::AsRawFd;
use event::EventQueue;
use libredox::errno::EAGAIN;
use redox_scheme::{RequestKind, SignalBehavior, Socket};
use crate::scheme::FbbootlogScheme;
@@ -18,41 +22,76 @@ fn main() {
redox_daemon::Daemon::new(|daemon| inner(daemon)).expect("failed to create daemon");
}
fn inner(daemon: redox_daemon::Daemon) -> ! {
let event_queue = EventQueue::new().expect("fbbootlogd: failed to create event queue");
event::user_data! {
enum Source {
Scheme,
Input,
}
}
let socket =
Socket::create("fbbootlog").expect("fbbootlogd: failed to create fbbootlog scheme");
Socket::nonblock("fbbootlog").expect("fbbootlogd: failed to create fbbootlog scheme");
event_queue
.subscribe(
socket.inner().raw(),
Source::Scheme,
event::EventFlags::READ,
)
.expect("fbcond: failed to subscribe to scheme events");
let mut scheme = FbbootlogScheme::new();
event_queue
.subscribe(
scheme.display.input_handle.inner().as_raw_fd() as usize,
Source::Input,
event::EventFlags::READ,
)
.expect("fbbootlogd: failed to subscribe to scheme events");
// This is not possible for now as fbbootlogd needs to open new displays at runtime for graphics
// driver handoff. In the future inputd may directly pass a handle to the display instead.
//libredox::call::setrens(0, 0).expect("fbbootlogd: failed to enter null namespace");
daemon.ready().expect("failed to notify parent");
loop {
let request = match socket
.next_request(SignalBehavior::Restart)
.expect("fbbootlogd: failed to read display scheme")
{
Some(request) => request,
None => {
// Scheme likely got unmounted
std::process::exit(0);
}
};
for event in event_queue {
match event.expect("fbbootlogd: failed to get event").user_data {
Source::Scheme => {
loop {
let request = match socket.next_request(SignalBehavior::Restart) {
Ok(Some(request)) => request,
Ok(None) => {
// Scheme likely got unmounted
std::process::exit(0);
}
Err(err) if err.errno == EAGAIN => break,
Err(err) => panic!("fbbootlogd: failed to read display scheme: {err:?}"),
};
match request.kind() {
RequestKind::Call(call) => {
let response = call.handle_scheme(&mut scheme);
match request.kind() {
RequestKind::Call(call) => {
let response = call.handle_scheme(&mut scheme);
socket
.write_responses(&[response], SignalBehavior::Restart)
.expect("pcid: failed to write next scheme response");
socket
.write_responses(&[response], SignalBehavior::Restart)
.expect("pcid: failed to write next scheme response");
}
RequestKind::OnClose { id } => {
scheme.on_close(id);
}
_ => (),
}
}
}
RequestKind::OnClose { id } => {
scheme.on_close(id);
Source::Input => {
scheme.display.handle_input_events();
}
_ => (),
}
}
std::process::exit(0);
}
+2 -4
View File
@@ -6,7 +6,7 @@ use syscall::{Error, Result, EINVAL, ENOENT};
use crate::display::Display;
pub struct FbbootlogScheme {
display: Display,
pub display: Display,
text_screen: console_draw::TextScreen,
}
@@ -55,8 +55,7 @@ impl Scheme for FbbootlogScheme {
}
fn write(&mut self, _id: usize, buf: &[u8], _offset: u64, _fcntl_flags: u32) -> Result<usize> {
let mut map_guard = self.display.map.lock().unwrap();
if let Some(map) = &mut *map_guard {
if let Some(map) = &mut self.display.map {
let damage = self.text_screen.write(
&mut console_draw::DisplayMap {
offscreen: map.inner.ptr_mut(),
@@ -66,7 +65,6 @@ impl Scheme for FbbootlogScheme {
buf,
&mut VecDeque::new(),
);
drop(map_guard);
self.display.sync_rects(damage);
}