Implement scheme cancellation.
This commit is contained in:
Generated
+22
-38
@@ -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
@@ -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
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user