Promises, promises
This commit is contained in:
parent
17fdee51e6
commit
a2dafeea12
6 changed files with 303 additions and 102 deletions
97
src/script/io.rs
Normal file
97
src/script/io.rs
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
use oden_js::{module::native::NativeModuleBuilder, ContextRef, ValueResult};
|
||||
use std::sync::mpsc::{channel, Receiver, Sender};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
|
||||
type Job = Box<dyn FnOnce() + Send + 'static>;
|
||||
|
||||
struct ThreadPoolWorker {
|
||||
_thread: thread::JoinHandle<()>,
|
||||
}
|
||||
|
||||
impl ThreadPoolWorker {
|
||||
fn new(queue: Arc<Mutex<Receiver<Job>>>) -> Self {
|
||||
let thread = thread::spawn(move || loop {
|
||||
let r = {
|
||||
let locked = queue.lock();
|
||||
locked.expect("Should not be orphaning the lock").recv()
|
||||
};
|
||||
if let Ok(item) = r {
|
||||
item();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
});
|
||||
ThreadPoolWorker { _thread: thread }
|
||||
}
|
||||
}
|
||||
|
||||
struct ThreadPool {
|
||||
_workers: Vec<ThreadPoolWorker>,
|
||||
sender: Sender<Job>,
|
||||
}
|
||||
|
||||
impl ThreadPool {
|
||||
fn new(size: usize) -> Self {
|
||||
let (sender, receiver) = channel();
|
||||
|
||||
let receiver = Arc::new(Mutex::new(receiver));
|
||||
|
||||
let mut workers = vec![];
|
||||
for _ in 0..size {
|
||||
workers.push(ThreadPoolWorker::new(receiver.clone()));
|
||||
}
|
||||
|
||||
ThreadPool {
|
||||
_workers: workers,
|
||||
sender,
|
||||
}
|
||||
}
|
||||
|
||||
fn execute(&self, job: Job) {
|
||||
let _ = self.sender.send(job);
|
||||
}
|
||||
}
|
||||
|
||||
struct IoImpl {
|
||||
thread_pool: ThreadPool,
|
||||
}
|
||||
|
||||
impl IoImpl {
|
||||
fn new() -> Self {
|
||||
IoImpl {
|
||||
thread_pool: ThreadPool::new(4),
|
||||
}
|
||||
}
|
||||
|
||||
fn load(&self, context: &ContextRef, path: &str) -> ValueResult {
|
||||
let (value, promise) = context.new_promise()?;
|
||||
|
||||
let path = path.to_string();
|
||||
self.thread_pool.execute(Box::new(move || {
|
||||
// TODO: Actually read the path.
|
||||
let path = path;
|
||||
promise.resolve(move |ctx: &ContextRef| ctx.new_string(&path));
|
||||
}));
|
||||
|
||||
Ok(value)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct IoAPI {}
|
||||
|
||||
impl IoAPI {
|
||||
pub fn define(ctx: &ContextRef) -> oden_js::Result<Self> {
|
||||
let io = Arc::new(IoImpl::new());
|
||||
let mut builder = NativeModuleBuilder::new(ctx);
|
||||
{
|
||||
let io = io.clone();
|
||||
builder.export(
|
||||
"load",
|
||||
ctx.new_fn(move |ctx: &ContextRef, p: String| io.load(ctx, &p))?,
|
||||
)?;
|
||||
}
|
||||
builder.build("io-core")?;
|
||||
Ok(IoAPI {})
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue