From 7565720f34a417d6badf241be1ccb9d09d91ebf3 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sat, 21 Dec 2024 19:24:29 +0100 Subject: [PATCH] vesad: Migrate to redox-scheme --- Cargo.lock | 1 + graphics/vesad/Cargo.toml | 1 + graphics/vesad/src/main.rs | 90 +++++++++++++------------------ graphics/vesad/src/scheme.rs | 102 ++++++++++++++++++++--------------- graphics/vesad/src/screen.rs | 8 +-- 5 files changed, 100 insertions(+), 102 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 27fb0ab0b9..92d3f8964b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1680,6 +1680,7 @@ dependencies = [ "orbclient", "ransid", "redox-daemon", + "redox-scheme", "redox_syscall", ] diff --git a/graphics/vesad/Cargo.toml b/graphics/vesad/Cargo.toml index 87f9083af7..0361c8bf7d 100644 --- a/graphics/vesad/Cargo.toml +++ b/graphics/vesad/Cargo.toml @@ -12,6 +12,7 @@ redox-daemon = "0.1" common = { path = "../../common" } inputd = { path = "../../inputd" } libredox = "0.1.3" +redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" } [features] default = [] diff --git a/graphics/vesad/src/main.rs b/graphics/vesad/src/main.rs index 8245a5c2b5..9b01e97624 100644 --- a/graphics/vesad/src/main.rs +++ b/graphics/vesad/src/main.rs @@ -2,10 +2,10 @@ extern crate orbclient; extern crate syscall; +use redox_scheme::{RequestKind, SignalBehavior, Socket, V2}; use std::env; use std::fs::File; -use std::io::{Read, Write}; -use syscall::{Packet, SchemeMut, EVENT_READ}; +use syscall::EVENT_READ; use crate::{ framebuffer::FrameBuffer, @@ -79,7 +79,8 @@ fn main() { .expect("failed to create daemon"); } fn inner(daemon: redox_daemon::Daemon, framebuffers: Vec, spec: &[()]) -> ! { - let mut socket = File::create(":display.vesa").expect("vesad: failed to create display scheme"); + let socket: Socket = + Socket::create("display.vesa").expect("vesad: failed to create display scheme"); let mut scheme = DisplayScheme::new(framebuffers, &spec); @@ -93,39 +94,37 @@ fn inner(daemon: redox_daemon::Daemon, framebuffers: Vec, spec: &[( let mut blocked = Vec::new(); loop { - let mut packet = Packet::default(); - if socket - .read(&mut packet) + let Some(request) = socket + .next_request(SignalBehavior::Restart) .expect("vesad: failed to read display scheme") - == 0 - { - //TODO: Handle blocked - break; + else { + // Scheme likely got unmounted + std::process::exit(0); + }; + + match request.kind() { + RequestKind::Call(call_request) => { + if let Some(resp) = call_request.handle_scheme_block_mut(&mut scheme) { + socket + .write_response(resp, SignalBehavior::Restart) + .expect("vesad: failed to write display scheme"); + } else { + blocked.push(call_request); + } + } + RequestKind::Cancellation(_cancellation_request) => {} + RequestKind::MsyncMsg | RequestKind::MunmapMsg | RequestKind::MmapMsg => unreachable!(), } - // If it is a read packet, and there is no data, block it. Otherwise, handle packet - if packet.a == syscall::number::SYS_READ - && packet.d > 0 - && scheme.can_read(packet.b).is_none() - { - blocked.push(packet); - } else { - scheme.handle(&mut packet); - socket - .write(&packet) - .expect("vesad: failed to write display scheme"); - } - - // If there are blocked readers, and data is available, handle them + // If there are blocked readers, try to handle them. { let mut i = 0; while i < blocked.len() { - if scheme.can_read(blocked[i].b).is_some() { - let mut packet = blocked.remove(i); - scheme.handle(&mut packet); + if let Some(resp) = blocked[i].handle_scheme_block_mut(&mut scheme) { socket - .write(&packet) + .write_response(resp, SignalBehavior::Restart) .expect("vesad: failed to write display scheme"); + blocked.remove(i); } else { i += 1; } @@ -133,45 +132,28 @@ fn inner(daemon: redox_daemon::Daemon, framebuffers: Vec, spec: &[( } for (handle_id, handle) in scheme.handles.iter_mut() { - if !handle.events.contains(EVENT_READ) { + if handle.notified_read || !handle.events.contains(EVENT_READ) { continue; } - // Can't use scheme.can_read() because we borrow handles as mutable. - // (and because it'd treat O_NONBLOCK sockets differently) - let count = if let HandleKind::Screen(vt_i, screen_i) = handle.kind { + let can_read = if let HandleKind::Screen(vt_i, screen_i) = handle.kind { scheme .vts .get(&vt_i) .and_then(|screens| screens.get(&screen_i)) - .and_then(|screen| screen.can_read()) - .unwrap_or(0) + .map_or(false, |screen| screen.can_read()) } else { - 0 + false }; - if count > 0 { - if !handle.notified_read { - handle.notified_read = true; - let event_packet = Packet { - id: 0, - pid: 0, - uid: 0, - gid: 0, - a: syscall::number::SYS_FEVENT, - b: *handle_id, - c: EVENT_READ.bits(), - d: count, - }; - - socket - .write(&event_packet) - .expect("vesad: failed to write display event"); - } + if can_read { + handle.notified_read = true; + socket + .post_fevent(*handle_id, EVENT_READ.bits()) + .expect("vesad: failed to write display event"); } else { handle.notified_read = false; } } } - std::process::exit(0); } diff --git a/graphics/vesad/src/scheme.rs b/graphics/vesad/src/scheme.rs index 1d4f7cb238..65baf8dace 100644 --- a/graphics/vesad/src/scheme.rs +++ b/graphics/vesad/src/scheme.rs @@ -1,7 +1,8 @@ use std::collections::BTreeMap; use std::str; -use syscall::{Error, EventFlags, MapFlags, Result, SchemeMut, EBADF, EINVAL, ENOENT, O_NONBLOCK}; +use redox_scheme::SchemeBlockMut; +use syscall::{Error, EventFlags, MapFlags, Result, EBADF, EINVAL, ENOENT, O_NONBLOCK}; use crate::{framebuffer::FrameBuffer, screen::GraphicScreen}; @@ -59,26 +60,6 @@ impl DisplayScheme { } } - pub fn can_read(&self, id: usize) -> Option { - if let Some(handle) = self.handles.get(&id) { - if let HandleKind::Screen(vt_i, screen_i) = handle.kind { - if let Some(screens) = self.vts.get(&vt_i) { - if let Some(screen) = screens.get(&screen_i) { - screen - .can_read() - .or(if handle.flags & O_NONBLOCK == O_NONBLOCK { - Some(0) - } else { - None - }); - } - } - } - } - - Some(0) - } - fn resize(&mut self, width: usize, height: usize, stride: usize) { //TODO: support resizing other outputs? let fb_i = 0; @@ -105,8 +86,14 @@ impl DisplayScheme { } } -impl SchemeMut for DisplayScheme { - fn open(&mut self, path_str: &str, flags: usize, _uid: u32, _gid: u32) -> Result { +impl SchemeBlockMut for DisplayScheme { + fn open( + &mut self, + path_str: &str, + flags: usize, + _uid: u32, + _gid: u32, + ) -> Result> { if path_str == "handle" { let id = self.next_id; self.next_id += 1; @@ -119,7 +106,7 @@ impl SchemeMut for DisplayScheme { notified_read: false, }, ); - return Ok(id); + return Ok(Some(id)); } let mut parts = path_str.split('/'); @@ -141,7 +128,7 @@ impl SchemeMut for DisplayScheme { }, ); - Ok(id) + Ok(Some(id)) } else { Err(Error::new(ENOENT)) } @@ -150,7 +137,7 @@ impl SchemeMut for DisplayScheme { } } - fn dup(&mut self, id: usize, buf: &[u8]) -> Result { + fn dup(&mut self, id: usize, buf: &[u8]) -> Result> { if !buf.is_empty() { return Err(Error::new(EINVAL)); } @@ -166,23 +153,27 @@ impl SchemeMut for DisplayScheme { self.handles.insert(new_id, handle.clone()); - Ok(new_id) + Ok(Some(new_id)) } - fn fevent(&mut self, id: usize, flags: syscall::EventFlags) -> Result { + fn fevent( + &mut self, + id: usize, + flags: syscall::EventFlags, + ) -> Result> { let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?; handle.notified_read = false; if let HandleKind::Screen(_vt_i, _screen_i) = handle.kind { handle.events = flags; - Ok(syscall::EventFlags::empty()) + Ok(Some(syscall::EventFlags::empty())) } else { Err(Error::new(EBADF)) } } - fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result { + fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result> { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?; let path_str = match handle.kind { @@ -217,10 +208,10 @@ impl SchemeMut for DisplayScheme { i += 1; } - Ok(i) + Ok(Some(i)) } - fn fsync(&mut self, id: usize) -> Result { + fn fsync(&mut self, id: usize) -> Result> { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?; if let HandleKind::Screen(vt_i, screen_i) = handle.kind { @@ -229,7 +220,7 @@ impl SchemeMut for DisplayScheme { if vt_i == self.active { screen.sync(&mut self.framebuffers[screen_i.0]); } - return Ok(0); + return Ok(Some(0)); } } } @@ -237,13 +228,28 @@ impl SchemeMut for DisplayScheme { Err(Error::new(EBADF)) } - fn read(&mut self, id: usize, buf: &mut [u8]) -> Result { + fn read( + &mut self, + id: usize, + buf: &mut [u8], + _offset: u64, + _fcntl_flags: u32, + ) -> Result> { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?; if let HandleKind::Screen(vt_i, screen_i) = handle.kind { if let Some(screens) = self.vts.get_mut(&vt_i) { if let Some(screen) = screens.get_mut(&screen_i) { - return screen.read(buf); + let nread = screen.read(buf)?; + if nread != 0 { + return Ok(Some(nread)); + } else { + if handle.flags & O_NONBLOCK == O_NONBLOCK { + return Ok(Some(0)); + } else { + return Ok(None); + } + } } } } @@ -251,7 +257,13 @@ impl SchemeMut for DisplayScheme { Err(Error::new(EBADF)) } - fn write(&mut self, id: usize, buf: &[u8]) -> Result { + fn write( + &mut self, + id: usize, + buf: &[u8], + _offset: u64, + _fcntl_flags: u32, + ) -> Result> { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?; match handle.kind { @@ -286,7 +298,7 @@ impl SchemeMut for DisplayScheme { DisplayCommand::Deactivate(_) => {} } - Ok(buf.len()) + Ok(Some(buf.len())) } HandleKind::Screen(vt_i, screen_i) => { @@ -296,7 +308,7 @@ impl SchemeMut for DisplayScheme { if vt_i == self.active { screen.sync(&mut self.framebuffers[screen_i.0]); } - Ok(count) + Ok(Some(count)) } else { Err(Error::new(EBADF)) } @@ -307,18 +319,24 @@ impl SchemeMut for DisplayScheme { } } - fn close(&mut self, id: usize) -> Result { + fn close(&mut self, id: usize) -> Result> { self.handles.remove(&id).ok_or(Error::new(EBADF))?; - Ok(0) + Ok(Some(0)) } - fn mmap_prep(&mut self, id: usize, off: u64, size: usize, _flags: MapFlags) -> Result { + fn mmap_prep( + &mut self, + id: usize, + off: u64, + size: usize, + _flags: MapFlags, + ) -> Result> { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?; if let HandleKind::Screen(vt_i, screen_i) = handle.kind { if let Some(screens) = self.vts.get(&vt_i) { if let Some(screen) = screens.get(&screen_i) { if off as usize + size <= screen.offscreen.len() * 4 { - return Ok(screen.offscreen.as_ptr() as usize + off as usize); + return Ok(Some(screen.offscreen.as_ptr() as usize + off as usize)); } else { return Err(Error::new(EINVAL)); } diff --git a/graphics/vesad/src/screen.rs b/graphics/vesad/src/screen.rs index 50f2f05af2..471340ce86 100644 --- a/graphics/vesad/src/screen.rs +++ b/graphics/vesad/src/screen.rs @@ -110,12 +110,8 @@ impl GraphicScreen { Ok(i * mem::size_of::()) } - pub fn can_read(&self) -> Option { - if self.input.is_empty() { - None - } else { - Some(self.input.len() * mem::size_of::()) - } + pub fn can_read(&self) -> bool { + !self.input.is_empty() } pub fn write(&mut self, buf: &[u8]) -> Result {