Introduced dylib extension format, cleared up shutdown sequence
This commit is contained in:
@@ -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) })
|
||||
|
||||
@@ -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(),
|
||||
|
||||
Reference in New Issue
Block a user