Unit tests pass
Fixed a nasty deadlock in reqnot
This commit is contained in:
@@ -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();
|
||||
}
|
||||
)
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user