updated default timeout and wait_async signature in wasm-bindgen-futures

This commit is contained in:
ibaryshnikov
2019-06-17 21:08:06 +03:00
parent 06c783d5e3
commit 221dc732af
3 changed files with 28 additions and 30 deletions

View File

@ -7,9 +7,8 @@ use futures::executor::{self, Notify, Spawn};
use futures::future; use futures::future;
use futures::prelude::*; use futures::prelude::*;
use futures::sync::oneshot; use futures::sync::oneshot;
use js_sys::{Atomics, Int32Array, WebAssembly, Function, Promise}; use js_sys::{Function, Promise};
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
macro_rules! console_log { macro_rules! console_log {
($($t:tt)*) => (log(&format_args!($($t)*).to_string())) ($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
@ -112,8 +111,8 @@ impl Future for JsFuture {
/// resolve**. Instead it will be a leaked promise. This is an unfortunate /// resolve**. Instead it will be a leaked promise. This is an unfortunate
/// limitation of wasm currently that's hoped to be fixed one day! /// limitation of wasm currently that's hoped to be fixed one day!
pub fn future_to_promise<F>(future: F) -> Promise pub fn future_to_promise<F>(future: F) -> Promise
where where
F: Future<Item = JsValue, Error = JsValue> + 'static, F: Future<Item = JsValue, Error = JsValue> + 'static,
{ {
_future_to_promise(Box::new(future)) _future_to_promise(Box::new(future))
} }
@ -210,11 +209,16 @@ fn _future_to_promise(future: Box<dyn Future<Item = JsValue, Error = JsValue>>)
} }
impl Notify for Waker { impl Notify for Waker {
fn notify(&self, id: usize) { fn notify(&self, _id: usize) {
console_log!("Waker notify"); console_log!("Waker notify");
if !self.notified.swap(true, Ordering::SeqCst) { if !self.notified.swap(true, Ordering::SeqCst) {
console_log!("Waker, inside if"); console_log!("Waker, inside if");
let _ = unsafe { core::arch::wasm32::atomic_notify(&self.value as *const AtomicI32 as *mut i32, 0) }; let _ = unsafe {
core::arch::wasm32::atomic_notify(
&self.value as *const AtomicI32 as *mut i32,
0,
)
};
} }
} }
} }
@ -249,20 +253,15 @@ fn _future_to_promise(future: Box<dyn Future<Item = JsValue, Error = JsValue>>)
} }
}; };
let memory_buffer = wasm_bindgen::memory()
.dyn_into::<WebAssembly::Memory>()
.expect("Should cast a memory to WebAssembly::Memory")
.buffer();
let value_location = &package.waker.value as *const AtomicI32 as u32 / 4; let value_location = &package.waker.value as *const AtomicI32 as u32 / 4;
let array = Int32Array::new(&memory_buffer);
// Use `Promise.then` on a resolved promise to place our execution // Use `Promise.then` on a resolved promise to place our execution
// onto the next turn of the microtask queue, enqueueing our poll // onto the next turn of the microtask queue, enqueueing our poll
// operation. We don't currently poll immediately as it turns out // operation. We don't currently poll immediately as it turns out
// `futures` crate adapters aren't compatible with it and it also // `futures` crate adapters aren't compatible with it and it also
// helps avoid blowing the stack by accident. // helps avoid blowing the stack by accident.
let promise = crate::polyfill::wait_async(array, value_location, 0).expect("Should create a Promise"); let promise =
crate::polyfill::wait_async(value_location, 0).expect("Should create a Promise");
let closure = Closure::once(Box::new(move |_| { let closure = Closure::once(Box::new(move |_| {
Package::poll(&me); Package::poll(&me);
}) as Box<dyn FnMut(JsValue)>); }) as Box<dyn FnMut(JsValue)>);
@ -340,8 +339,8 @@ fn _future_to_promise(future: Box<dyn Future<Item = JsValue, Error = JsValue>>)
/// ///
/// This function has the same panic behavior as `future_to_promise`. /// This function has the same panic behavior as `future_to_promise`.
pub fn spawn_local<F>(future: F) pub fn spawn_local<F>(future: F)
where where
F: Future<Item = (), Error = ()> + 'static, F: Future<Item = (), Error = ()> + 'static,
{ {
future_to_promise( future_to_promise(
future future

View File

@ -102,7 +102,6 @@
//! ``` //! ```
#![feature(stdsimd)] #![feature(stdsimd)]
#![deny(missing_docs)] #![deny(missing_docs)]
#[cfg(feature = "futures_0_3")] #[cfg(feature = "futures_0_3")]
@ -341,13 +340,10 @@ fn _future_to_promise(future: Box<dyn Future<Item = JsValue, Error = JsValue>>)
// our `Waiting` state, and resume the polling process // our `Waiting` state, and resume the polling process
State::Polling => { State::Polling => {
me.notified.set(State::Waiting(me.clone())); me.notified.set(State::Waiting(me.clone()));
break; break;
} }
State::Waiting(_) => { State::Waiting(_) => panic!("shouldn't see waiting state!"),
panic!("shouldn't see waiting state!")
}
} }
let (val, f) = match me.spawn.borrow_mut().poll_future_notify(me, 0) { let (val, f) = match me.spawn.borrow_mut().poll_future_notify(me, 0) {

View File

@ -41,7 +41,7 @@ use std::rc::Rc;
use js_sys::{ use js_sys::{
encode_uri_component, Array, Atomics, Error, Function, Int32Array, JsString, Promise, Reflect, encode_uri_component, Array, Atomics, Error, Function, Int32Array, JsString, Promise, Reflect,
SharedArrayBuffer, SharedArrayBuffer, WebAssembly,
}; };
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast; use wasm_bindgen::JsCast;
@ -57,6 +57,8 @@ extern "C" {
fn log(s: &str); fn log(s: &str);
} }
const DEFAULT_TIMEOUT: f64 = 10.0;
const HELPER_CODE: &'static str = " const HELPER_CODE: &'static str = "
onmessage = function (ev) { onmessage = function (ev) {
try { try {
@ -103,9 +105,8 @@ fn free_helper(helper: &Rc<Worker>) {
}); });
} }
pub fn wait_async(indexed_array: Int32Array, index: u32, value: i32) -> Result<Promise, JsValue> { pub fn wait_async(index: u32, value: i32) -> Result<Promise, JsValue> {
let timeout = 0.1; wait_async_with_timeout(index, value, DEFAULT_TIMEOUT)
wait_async_with_timeout(indexed_array, index, value, timeout)
} }
fn get_array_item(array: &JsValue, index: u32) -> JsValue { fn get_array_item(array: &JsValue, index: u32) -> JsValue {
@ -117,12 +118,14 @@ fn get_array_item(array: &JsValue, index: u32) -> JsValue {
// for parameter validation. The promise is resolved with a string as from // for parameter validation. The promise is resolved with a string as from
// Atomics.wait, or, in the case something went completely wrong, it is // Atomics.wait, or, in the case something went completely wrong, it is
// rejected with an error string. // rejected with an error string.
pub fn wait_async_with_timeout( pub fn wait_async_with_timeout(index: u32, value: i32, timeout: f64) -> Result<Promise, JsValue> {
indexed_array: Int32Array, let memory_buffer = wasm_bindgen::memory()
index: u32, .dyn_into::<WebAssembly::Memory>()
value: i32, .expect("Should cast a memory to WebAssembly::Memory")
timeout: f64, .buffer();
) -> Result<Promise, JsValue> {
let indexed_array = Int32Array::new(&memory_buffer);
if !indexed_array.buffer().has_type::<SharedArrayBuffer>() { if !indexed_array.buffer().has_type::<SharedArrayBuffer>() {
console_log!("polyfill, not a SharedArrayBuffer"); console_log!("polyfill, not a SharedArrayBuffer");
return Err(Error::new("Indexed array must be created from SharedArrayBuffer").into()); return Err(Error::new("Indexed array must be created from SharedArrayBuffer").into());