Implement scheme cancellation.

This commit is contained in:
4lDO2
2024-03-08 12:22:57 +01:00
parent be6696a81b
commit 55cfb330d2
3 changed files with 67 additions and 55 deletions
Generated
+22 -38
View File
@@ -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",
]
+4 -4
View File
@@ -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"
+41 -13
View File
@@ -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<CallRequest>,
canceling: bool,
}
let mut todo = VecDeque::<Todo>::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),