From 55cfb330d272d78f9d07a87423c7feed02ded422 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Fri, 8 Mar 2024 12:22:57 +0100 Subject: [PATCH] Implement scheme cancellation. --- Cargo.lock | 60 ++++++++++++++++++++--------------------------------- Cargo.toml | 8 +++---- src/main.rs | 54 +++++++++++++++++++++++++++++++++++------------ 3 files changed, 67 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7b714e559..1cbc2fced3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,21 +4,15 @@ version = 3 [[package]] name = "bitflags" -version = "1.3.2" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "ipcd" version = "0.1.0" dependencies = [ - "libredox 0.0.3", + "libredox", "redox-daemon", "redox-scheme", "redox_event", @@ -27,67 +21,57 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.150" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libredox" -version = "0.0.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "309ba69985d5170852ebbe8fbb33850d20794d0aed5b210dfea2db798df64e10" dependencies = [ - "bitflags 2.4.1", - "libc", - "redox_syscall", -] - -[[package]] -name = "libredox" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "962b650e6b934f95cec493e1464e0f5cba98dd9ba9ef2b1c42cdfdb7864cab5a" -dependencies = [ - "bitflags 2.4.1", + "bitflags", "libc", "redox_syscall", ] [[package]] name = "redox-daemon" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "353178b5771a301b9d2b318914ab5dfeb21dd6e65930faedde19248cfceca5a7" +checksum = "7fbdeffdb03cf2961b211a2023e683d71f2c225ea93404da5dc34b0dc94f0341" dependencies = [ "libc", - "libredox 0.0.1", + "libredox", ] [[package]] name = "redox-scheme" -version = "0.1.0" -source = "git+https://gitlab.redox-os.org/redox-os/redox-scheme.git#265e056726066f319e47eedd5f20f9549fb4c581" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a4d4161697395d7cc9b182a14a753b2ba0243dcf622e278e644c6e7f74904c1" dependencies = [ - "libredox 0.0.3", + "libredox", "redox_syscall", ] [[package]] name = "redox_event" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b78fedc17aea72caee38ac1208e0f709fa1641af1bbe0205e7d434413a60621d" +checksum = "0fe498288c246de6b2df9be919cffe7d144480b2f1829f3fa987aa3ee067a04a" dependencies = [ - "bitflags 2.4.1", - "libredox 0.0.1", + "bitflags", + "libredox", "redox_syscall", ] [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "13c178f952cc7eac391f3124bd9851d1ac0bdbc4c9de2d892ccd5f0d8b160e96" dependencies = [ - "bitflags 1.3.2", + "bitflags", ] diff --git a/Cargo.toml b/Cargo.toml index 1cec1ae4ac..ae758ca5fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,8 +4,8 @@ name = "ipcd" version = "0.1.0" [dependencies] -libredox = "0.0.3" +libredox = "0.1.2" redox-daemon = "0.1.2" -redox_syscall = "0.4.1" -redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" } -redox_event = "0.2.0" +redox_syscall = "0.5" +redox-scheme = "0.2.0" +redox_event = "0.4.0" diff --git a/src/main.rs b/src/main.rs index d91c06f750..d3c767bb45 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,8 +2,8 @@ use std::collections::VecDeque; use event::{EventQueue, EventFlags}; -use redox_scheme::{SignalBehavior, Response}; -use syscall::{Error, Result, EAGAIN, EWOULDBLOCK, ENODEV}; +use redox_scheme::{CallRequest, RequestKind, Response, SignalBehavior}; +use syscall::{Error, Result, EAGAIN, EWOULDBLOCK, ENODEV, EINTR, KSMSG_CANCEL}; mod chan; mod shm; @@ -41,7 +41,11 @@ fn inner(daemon: redox_daemon::Daemon) -> Result<()> { event_queue.subscribe(chan.socket.inner().raw(), EventSource::ChanSocket, EventFlags::READ)?; event_queue.subscribe(shm.socket.inner().raw(), EventSource::ShmSocket, EventFlags::READ)?; - let mut todo = VecDeque::with_capacity(16); + struct Todo { + req: Option, + canceling: bool, + } + let mut todo = VecDeque::::with_capacity(16); libredox::call::setrens(0, 0)?; @@ -61,23 +65,39 @@ fn inner(daemon: redox_daemon::Daemon) -> Result<()> { let eof = loop { match chan.socket.next_request(SignalBehavior::Restart) { Ok(None) => break true, - Ok(Some(request)) => todo.push_front(Some(request)), + Ok(Some(request)) => match request.kind() { + RequestKind::Call(request) => todo.push_front(Todo { req: Some(request), canceling: false }), + RequestKind::Cancellation(request) => { + if let Some(affected_packet) = todo.iter_mut().find(|t| t.req.as_ref().map_or(false, |r| r.request().request_id() == request.id)) { + affected_packet.canceling = true; + } + } + _ => (), + } Err(Error { errno: EAGAIN | EWOULDBLOCK }) => break false, Err(error) => return Err(error), } }; // Process queue, delete finished items - todo.retain_mut(|request_opt| { - match request_opt.take().unwrap().handle_scheme_block_mut(chan) { + todo.retain_mut(|slot| { + let req = slot.req.take().unwrap(); + + match req.handle_scheme_block_mut(chan) { Ok(res) => { if let Err(err) = chan.socket.write_response(res, SignalBehavior::Restart) { error = Some(err); } - return false; + false + } + Err(req) if slot.canceling => { + if let Err(err) = chan.socket.write_response(Response::new(&req, Err(Error::new(EINTR))), SignalBehavior::Restart) { + error = Some(err); + } + false } Err(req) => { - *request_opt = Some(req); + slot.req = Some(req); true } } @@ -89,8 +109,13 @@ fn inner(daemon: redox_daemon::Daemon) -> Result<()> { }; if unmount && let Some(chan) = chan_opt.take() { - for req in todo.drain(..) { - if let Err(err) = chan.socket.write_response(Response::new(&req.unwrap(), Err(Error::new(ENODEV))), SignalBehavior::Restart) { + for slot in todo.drain(..) { + let res = if slot.canceling { + Err(Error::new(EINTR)) + } else { + Err(Error::new(ENODEV)) + }; + if let Err(err) = chan.socket.write_response(Response::new(&slot.req.unwrap(), res), SignalBehavior::Restart) { error = Some(err); } } @@ -105,9 +130,12 @@ fn inner(daemon: redox_daemon::Daemon) -> Result<()> { let eof = loop { match shm.socket.next_request(SignalBehavior::Restart) { Ok(None) => break true, - Ok(Some(request)) => { - let response = request.handle_scheme_mut(shm); - shm.socket.write_response(response, SignalBehavior::Restart)?; + Ok(Some(request)) => match request.kind() { + RequestKind::Call(request) => { + let response = request.handle_scheme_mut(shm); + shm.socket.write_response(response, SignalBehavior::Restart)?; + } + _ => (), }, Err(Error { errno: EAGAIN | EWOULDBLOCK }) => break false, Err(err) => return Err(err),