#![cfg(not(target_arch = "wasm32"))]
use std::path::PathBuf;
use std::sync::mpsc::{Receiver, Sender};
use std::thread::JoinHandle;
use super::native_tier::NativeFn;
pub struct AotRequest {
pub fi: usize,
pub source: String,
pub fn_name: String,
pub cache_dir: PathBuf,
}
pub struct AotResult {
pub fi: usize,
pub nf: Option<Box<dyn NativeFn>>,
}
pub struct BgAotCompiler {
req_tx: Sender<AotRequest>,
res_rx: Receiver<AotResult>,
inflight: usize,
_worker: JoinHandle<()>,
}
impl BgAotCompiler {
pub fn new() -> Self {
let (req_tx, req_rx) = std::sync::mpsc::channel::<AotRequest>();
let (res_tx, res_rx) = std::sync::mpsc::channel::<AotResult>();
let worker = std::thread::spawn(move || {
while let Ok(req) = req_rx.recv() {
let nf = crate::compile::aot_build_function(&req.source, &req.fn_name, &req.cache_dir);
if res_tx.send(AotResult { fi: req.fi, nf }).is_err() {
break; }
}
});
BgAotCompiler { req_tx, res_rx, inflight: 0, _worker: worker }
}
pub fn submit(&mut self, req: AotRequest) {
if self.req_tx.send(req).is_ok() {
self.inflight += 1;
}
}
pub fn try_drain(&mut self) -> Option<AotResult> {
match self.res_rx.try_recv() {
Ok(r) => {
self.inflight = self.inflight.saturating_sub(1);
Some(r)
}
Err(_) => None,
}
}
pub fn is_idle(&self) -> bool {
self.inflight == 0
}
pub fn drain_blocking(&mut self) -> Vec<AotResult> {
let mut out = Vec::with_capacity(self.inflight);
while self.inflight > 0 {
match self.res_rx.recv() {
Ok(r) => {
self.inflight -= 1;
out.push(r);
}
Err(_) => break,
}
}
out
}
}
impl Default for BgAotCompiler {
fn default() -> Self {
Self::new()
}
}