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

@@ -1,3 +1,4 @@
use std::io;
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};
@@ -37,7 +38,13 @@ pub async fn ext_dylib(path: &Path, ctx: Ctx) -> Result<ExtPort, libloading::Err
use orchid_base::logging::log;
let mut lines = BufReader::new(read_log).lines();
while let Some(line) = lines.next().await {
writeln!(log("stderr"), "{log_path} err> {}", line.expect("Readline implies this")).await;
match line {
Ok(line) => writeln!(log("stderr"), "{log_path} err> {line}").await,
Err(e) => match e.kind() {
io::ErrorKind::BrokenPipe | io::ErrorKind::UnexpectedEof => break,
_ => panic!("Error while reading stderr {e}"),
},
}
}
});
let library = load_dylib(path)?;
@@ -45,10 +52,10 @@ pub async fn ext_dylib(path: &Path, ctx: Ctx) -> Result<ExtPort, libloading::Err
unsafe { library.get("orchid_extension_main") }?;
let data = Box::into_raw(Box::new(ctx)) as *const ();
extern "C" fn drop(data: *const ()) { std::mem::drop(unsafe { Box::from_raw(data as *mut Ctx) }) }
extern "C" fn spawn(data: *const (), vt: api::binary::FutureVT) {
extern "C" fn spawn(data: *const (), vt: api::binary::FutureBin) {
let _ = unsafe { (data as *mut Ctx).as_mut().unwrap().spawn(vt_to_future(vt)) };
}
let spawner = api::binary::Spawner { data, drop, spawn };
let spawner = api::binary::SpawnerBin { data, drop, spawn };
let cx = api::binary::ExtensionContext { input, output, log, spawner };
unsafe { (entrypoint)(cx) };
Ok(ExtPort { input: Box::pin(write_input), output: Box::pin(read_output) })

View File

@@ -19,7 +19,9 @@ use orchid_base::interner::{IStr, IStrv, es, ev, is, iv};
use orchid_base::location::Pos;
use orchid_base::logging::log;
use orchid_base::name::Sym;
use orchid_base::reqnot::{Client, ClientExt, MsgReaderExt, ReqHandleExt, ReqReaderExt, io_comm};
use orchid_base::reqnot::{
Client, ClientExt, CommCtx, MsgReaderExt, ReqHandleExt, ReqReaderExt, io_comm,
};
use orchid_base::stash::{stash, with_stash};
use orchid_base::tree::AtomRepr;
@@ -46,6 +48,7 @@ pub struct ReqPair<R: Request>(R, Sender<R::Response>);
pub struct ExtensionData {
name: String,
ctx: Ctx,
comm_cx: Option<CommCtx>,
join_ext: Option<Box<dyn JoinHandle>>,
client: Rc<dyn Client>,
systems: Vec<SystemCtor>,
@@ -58,8 +61,10 @@ impl Drop for ExtensionData {
fn drop(&mut self) {
let client = self.client.clone();
let join_ext = self.join_ext.take().expect("Only called once in Drop");
let comm_cx = self.comm_cx.take().expect("Only used here");
stash(async move {
client.notify(api::HostExtNotif::Exit).await.unwrap();
comm_cx.exit().await.unwrap();
join_ext.join().await;
})
}
@@ -76,7 +81,7 @@ impl Extension {
let header2 = header.clone();
Ok(Self(Rc::new_cyclic(|weak: &Weak<ExtensionData>| {
// context not needed because exit is extension-initiated
let (client, _, comm) = io_comm(Rc::new(Mutex::new(init.input)), Mutex::new(init.output));
let (client, comm_cx, comm) = io_comm(init.input, init.output);
let weak2 = weak;
let weak = weak.clone();
let ctx2 = ctx.clone();
@@ -274,6 +279,7 @@ impl Extension {
ExtensionData {
name: header2.name.clone(),
ctx: ctx2,
comm_cx: Some(comm_cx),
systems: (header.systems.iter().cloned())
.map(|decl| SystemCtor { decl, ext: WeakExtension(weak2.clone()) })
.collect(),