mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-04-01 18:01:06 +00:00
Fixing some nits
This commit is contained in:
parent
6c58afda01
commit
c00262f210
@ -140,6 +140,8 @@ where
|
|||||||
struct Task {
|
struct Task {
|
||||||
// This is an Option so that the Future can be immediately dropped when it's finished
|
// This is an Option so that the Future can be immediately dropped when it's finished
|
||||||
future: RefCell<Option<Pin<Box<dyn Future<Output = ()> + 'static>>>>,
|
future: RefCell<Option<Pin<Box<dyn Future<Output = ()> + 'static>>>>,
|
||||||
|
|
||||||
|
// This is used to ensure that the Task will only be queued once
|
||||||
is_queued: Cell<bool>,
|
is_queued: Cell<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,6 +157,7 @@ where
|
|||||||
|
|
||||||
impl ArcWake for Task {
|
impl ArcWake for Task {
|
||||||
fn wake_by_ref(arc_self: &Arc<Self>) {
|
fn wake_by_ref(arc_self: &Arc<Self>) {
|
||||||
|
// This ensures that it's only queued once
|
||||||
if arc_self.is_queued.replace(true) {
|
if arc_self.is_queued.replace(true) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -163,6 +166,7 @@ where
|
|||||||
|
|
||||||
lock.push_back(arc_self.clone());
|
lock.push_back(arc_self.clone());
|
||||||
|
|
||||||
|
// The Task will be polled on the next microtask event tick
|
||||||
EXECUTOR.next_tick.schedule();
|
EXECUTOR.next_tick.schedule();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,6 +179,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl NextTick {
|
impl NextTick {
|
||||||
|
#[inline]
|
||||||
fn new<F>(mut f: F) -> Self where F: FnMut() + 'static {
|
fn new<F>(mut f: F) -> Self where F: FnMut() + 'static {
|
||||||
Self {
|
Self {
|
||||||
is_spinning: Cell::new(false),
|
is_spinning: Cell::new(false),
|
||||||
@ -186,6 +191,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn schedule(&self) {
|
fn schedule(&self) {
|
||||||
|
// This ensures that it's only scheduled once
|
||||||
if self.is_spinning.replace(true) {
|
if self.is_spinning.replace(true) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -201,17 +207,22 @@ where
|
|||||||
|
|
||||||
|
|
||||||
struct Executor {
|
struct Executor {
|
||||||
|
// This is a queue of Tasks which will be polled in order
|
||||||
tasks: RefCell<VecDeque<Arc<Task>>>,
|
tasks: RefCell<VecDeque<Arc<Task>>>,
|
||||||
|
|
||||||
|
// This is used to ensure that Tasks are polled on the next microtask event tick
|
||||||
next_tick: NextTick,
|
next_tick: NextTick,
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is only safe because JS is currently single-threaded
|
// TODO This is only safe because JS is currently single-threaded
|
||||||
unsafe impl Send for Executor {}
|
unsafe impl Send for Executor {}
|
||||||
unsafe impl Sync for Executor {}
|
unsafe impl Sync for Executor {}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref EXECUTOR: Executor = Executor {
|
static ref EXECUTOR: Executor = Executor {
|
||||||
tasks: RefCell::new(VecDeque::new()),
|
tasks: RefCell::new(VecDeque::new()),
|
||||||
|
|
||||||
|
// This closure will only be called on the next microtask event tick
|
||||||
next_tick: NextTick::new(|| {
|
next_tick: NextTick::new(|| {
|
||||||
let tasks = &EXECUTOR.tasks;
|
let tasks = &EXECUTOR.tasks;
|
||||||
|
|
||||||
@ -220,17 +231,18 @@ where
|
|||||||
|
|
||||||
match lock.pop_front() {
|
match lock.pop_front() {
|
||||||
Some(task) => {
|
Some(task) => {
|
||||||
// This is necessary because the polled task might queue more tasks
|
|
||||||
drop(lock);
|
|
||||||
|
|
||||||
let mut future = task.future.borrow_mut();
|
let mut future = task.future.borrow_mut();
|
||||||
|
|
||||||
let poll = {
|
let poll = {
|
||||||
|
// This will only panic if the Future wakes up the Waker after returning Poll::Ready
|
||||||
let mut future = future.as_mut().unwrap_throw();
|
let mut future = future.as_mut().unwrap_throw();
|
||||||
|
|
||||||
// Clear `is_queued` flag so that it will re-queue if poll calls waker.wake()
|
// Clear `is_queued` flag so that it will re-queue if poll calls waker.wake()
|
||||||
task.is_queued.set(false);
|
task.is_queued.set(false);
|
||||||
|
|
||||||
|
// This is necessary because the polled task might queue more tasks
|
||||||
|
drop(lock);
|
||||||
|
|
||||||
// TODO is there some way of saving these so they don't need to be recreated all the time ?
|
// TODO is there some way of saving these so they don't need to be recreated all the time ?
|
||||||
let waker = ArcWake::into_waker(task.clone());
|
let waker = ArcWake::into_waker(task.clone());
|
||||||
let cx = &mut Context::from_waker(&waker);
|
let cx = &mut Context::from_waker(&waker);
|
||||||
@ -238,10 +250,12 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Poll::Ready(_) = poll {
|
if let Poll::Ready(_) = poll {
|
||||||
|
// Cleanup the Future immediately
|
||||||
*future = None;
|
*future = None;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
|
// All of the Tasks have been polled, so it's now possible to schedule the NextTick again
|
||||||
EXECUTOR.next_tick.done();
|
EXECUTOR.next_tick.done();
|
||||||
break;
|
break;
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user