Introduced dylib extension format, cleared up shutdown sequence

This commit is contained in:
2026-01-17 00:23:35 +01:00
parent 1a7230ce9b
commit 6a3c1d5917
18 changed files with 214 additions and 113 deletions

View File

@@ -299,10 +299,15 @@ 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) { self.exit.clone().send(()).await.expect("quit channel dropped"); }
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(())
}
}
/// Establish bidirectional request-notification communication over a duplex
@@ -313,13 +318,14 @@ impl CommCtx {
/// check that the correct message families are sent in the correct directions
/// across the channel.
pub fn io_comm(
o: Rc<Mutex<Pin<Box<dyn AsyncWrite>>>>,
i: Mutex<Pin<Box<dyn AsyncRead>>>,
o: Pin<Box<dyn AsyncWrite>>,
i: Pin<Box<dyn AsyncRead>>,
) -> (impl Client + 'static, CommCtx, IoCommServer) {
let i = Rc::new(i);
let i = Rc::new(Mutex::new(i));
let o = Rc::new(Mutex::new(o));
let (onsub, client) = IoClient::new(o.clone());
let (exit, onexit) = channel(1);
(client, CommCtx { exit }, IoCommServer { o, i, onsub, onexit })
(client, CommCtx { exit, o: o.clone() }, IoCommServer { o, i, onsub, onexit })
}
pub struct IoCommServer {
o: Rc<Mutex<Pin<Box<dyn AsyncWrite>>>>,
@@ -345,15 +351,12 @@ impl IoCommServer {
let mut g = Bound::async_new(i.clone(), async |i| i.lock().await).await;
match u64::decode(g.as_mut()).await {
Ok(id) => h.emit(Event::Input(id, g)).await,
Err(e)
if matches!(
e.kind(),
io::ErrorKind::BrokenPipe
| io::ErrorKind::ConnectionAborted
| io::ErrorKind::UnexpectedEof
) =>
h.emit(Event::Exit).await,
Err(e) => return Err(e),
Err(e) => match e.kind() {
io::ErrorKind::BrokenPipe
| io::ErrorKind::ConnectionAborted
| io::ErrorKind::UnexpectedEof => h.emit(Event::Exit).await,
_ => return Err(e),
},
}
}
});
@@ -419,10 +422,8 @@ impl IoCommServer {
#[cfg(test)]
mod test {
use std::cell::RefCell;
use std::rc::Rc;
use futures::channel::mpsc;
use futures::lock::Mutex;
use futures::{SinkExt, StreamExt, join};
use orchid_api_derive::{Coding, Hierarchy};
use orchid_api_traits::Request;
@@ -444,9 +445,8 @@ mod test {
let (in1, out2) = pipe(1024);
let (in2, out1) = pipe(1024);
let (received, mut on_receive) = mpsc::channel(2);
let (_, recv_ctx, recv_srv) =
io_comm(Rc::new(Mutex::new(Box::pin(in2))), Mutex::new(Box::pin(out2)));
let (sender, ..) = io_comm(Rc::new(Mutex::new(Box::pin(in1))), Mutex::new(Box::pin(out1)));
let (_, recv_ctx, recv_srv) = io_comm(Box::pin(in2), Box::pin(out2));
let (sender, ..) = io_comm(Box::pin(in1), Box::pin(out1));
join!(
async {
recv_srv
@@ -465,7 +465,7 @@ mod test {
assert_eq!(on_receive.next().await, Some(TestNotif(3)));
sender.notify(TestNotif(4)).await.unwrap();
assert_eq!(on_receive.next().await, Some(TestNotif(4)));
recv_ctx.exit().await;
recv_ctx.exit().await.unwrap();
}
);
}))
@@ -484,10 +484,8 @@ mod test {
spin_on(with_logger(logger, async {
let (in1, out2) = pipe(1024);
let (in2, out1) = pipe(1024);
let (_, srv_ctx, srv) =
io_comm(Rc::new(Mutex::new(Box::pin(in2))), Mutex::new(Box::pin(out2)));
let (client, client_ctx, client_srv) =
io_comm(Rc::new(Mutex::new(Box::pin(in1))), Mutex::new(Box::pin(out1)));
let (_, srv_ctx, srv) = io_comm(Box::pin(in2), Box::pin(out2));
let (client, client_ctx, client_srv) = io_comm(Box::pin(in1), Box::pin(out1));
join!(
async {
srv
@@ -513,8 +511,8 @@ mod test {
async {
let response = client.request(DummyRequest(5)).await.unwrap();
assert_eq!(response, 6);
srv_ctx.exit().await;
client_ctx.exit().await;
srv_ctx.exit().await.unwrap();
client_ctx.exit().await.unwrap();
}
);
}))
@@ -527,9 +525,8 @@ mod test {
let (input1, output1) = pipe(1024);
let (input2, output2) = pipe(1024);
let (reply_client, reply_context, reply_server) =
io_comm(Rc::new(Mutex::new(Box::pin(input1))), Mutex::new(Box::pin(output2)));
let (req_client, req_context, req_server) =
io_comm(Rc::new(Mutex::new(Box::pin(input2))), Mutex::new(Box::pin(output1)));
io_comm(Box::pin(input1), Box::pin(output2));
let (req_client, req_context, req_server) = io_comm(Box::pin(input2), Box::pin(output1));
let reply_context = RefCell::new(Some(reply_context));
let (exit, onexit) = futures::channel::oneshot::channel::<()>();
join!(
@@ -539,7 +536,7 @@ mod test {
async |hand| {
let _notif = hand.read::<TestNotif>().await.unwrap();
let context = reply_context.borrow_mut().take().unwrap();
context.exit().await;
context.exit().await?;
Ok(())
},
async |mut hand| {