Unit tests pass

Fixed a nasty deadlock in reqnot
This commit is contained in:
2026-01-19 00:56:03 +01:00
parent 6a3c1d5917
commit 48942b3b2c
15 changed files with 223 additions and 85 deletions

View File

@@ -299,12 +299,10 @@ impl<'a> MsgWriter<'a> for IoNotifWriter {
pub struct CommCtx {
exit: Sender<()>,
o: Rc<Mutex<Pin<Box<dyn AsyncWrite>>>>,
}
impl CommCtx {
pub async fn exit(self) -> io::Result<()> {
self.o.lock().await.as_mut().close().await?;
self.exit.clone().send(()).await.expect("quit channel dropped");
Ok(())
}
@@ -325,7 +323,7 @@ pub fn io_comm(
let o = Rc::new(Mutex::new(o));
let (onsub, client) = IoClient::new(o.clone());
let (exit, onexit) = channel(1);
(client, CommCtx { exit, o: o.clone() }, IoCommServer { o, i, onsub, onexit })
(client, CommCtx { exit }, IoCommServer { o, i, onsub, onexit })
}
pub struct IoCommServer {
o: Rc<Mutex<Pin<Box<dyn AsyncWrite>>>>,
@@ -345,7 +343,6 @@ impl IoCommServer {
Sub(ReplySub),
Exit,
}
let exiting = RefCell::new(false);
let input_stream = try_stream(async |mut h| {
loop {
let mut g = Bound::async_new(i.clone(), async |i| i.lock().await).await;
@@ -361,27 +358,21 @@ impl IoCommServer {
}
});
let (mut add_pending_req, fork_future) = LocalSet::new();
let mut fork_stream = pin!(fork_future.fuse().into_stream());
let mut fork_stream = pin!(fork_future.into_stream());
let mut pending_replies = HashMap::new();
'body: {
let mut shared = pin!(stream_select!(
let mut shared = stream_select! {
pin!(input_stream) as Pin<&mut dyn Stream<Item = io::Result<Event>>>,
onsub.map(|sub| Ok(Event::Sub(sub))),
fork_stream.as_mut().map(|res| {
res.map(|()| panic!("this substream cannot exit while the loop is running"))
res.map(|()| panic!("this substream cannot exit while the loop is running") as Event)
}),
onexit.map(|()| Ok(Event::Exit)),
));
};
while let Some(next) = shared.next().await {
match next {
Err(e) => break 'body Err(e),
Ok(Event::Exit) => {
*exiting.borrow_mut() = true;
let mut out = o.lock().await;
out.as_mut().flush().await?;
out.as_mut().close().await?;
break;
},
Ok(Event::Exit) => break,
Ok(Event::Sub(ReplySub { id, ack, cb })) => {
pending_replies.insert(id, cb);
ack.send(()).unwrap();
@@ -415,6 +406,9 @@ impl IoCommServer {
while let Some(next) = fork_stream.next().await {
next?
}
let mut out = o.lock().await;
out.as_mut().flush().await?;
out.as_mut().close().await?;
Ok(())
}
}
@@ -427,11 +421,9 @@ mod test {
use futures::{SinkExt, StreamExt, join};
use orchid_api_derive::{Coding, Hierarchy};
use orchid_api_traits::Request;
use test_executors::spin_on;
use unsync_pipe::pipe;
use crate::logging::test::TestLogger;
use crate::logging::with_logger;
use crate::future_debug::spin_on;
use crate::reqnot::{ClientExt, MsgReaderExt, ReqReaderExt, io_comm};
#[derive(Clone, Debug, PartialEq, Coding, Hierarchy)]
@@ -440,8 +432,7 @@ mod test {
#[test]
fn notification() {
let logger = TestLogger::new(async |s| eprint!("{s}"));
spin_on(with_logger(logger, async {
spin_on(async {
let (in1, out2) = pipe(1024);
let (in2, out1) = pipe(1024);
let (received, mut on_receive) = mpsc::channel(2);
@@ -468,7 +459,7 @@ mod test {
recv_ctx.exit().await.unwrap();
}
);
}))
})
}
#[derive(Clone, Debug, Coding, Hierarchy)]
@@ -480,8 +471,7 @@ mod test {
#[test]
fn request() {
let logger = TestLogger::new(async |s| eprint!("{s}"));
spin_on(with_logger(logger, async {
spin_on(async {
let (in1, out2) = pipe(1024);
let (in2, out1) = pipe(1024);
let (_, srv_ctx, srv) = io_comm(Box::pin(in2), Box::pin(out2));
@@ -515,13 +505,12 @@ mod test {
client_ctx.exit().await.unwrap();
}
);
}))
})
}
#[test]
fn exit() {
let logger = TestLogger::new(async |s| eprint!("{s}"));
spin_on(with_logger(logger, async {
spin_on(async {
let (input1, output1) = pipe(1024);
let (input2, output2) = pipe(1024);
let (reply_client, reply_context, reply_server) =
@@ -565,6 +554,6 @@ mod test {
onexit.await.unwrap();
}
)
}));
});
}
}