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::prelude::*;
use futures::sync::oneshot;
use js_sys::{Atomics, Int32Array, WebAssembly, Function, Promise};
use js_sys::{Function, Promise};
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
macro_rules! console_log {
($($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
/// limitation of wasm currently that's hoped to be fixed one day!
pub fn future_to_promise<F>(future: F) -> Promise
where
F: Future<Item = JsValue, Error = JsValue> + 'static,
where
F: Future<Item = JsValue, Error = JsValue> + 'static,
{
_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 {
fn notify(&self, id: usize) {
fn notify(&self, _id: usize) {
console_log!("Waker notify");
if !self.notified.swap(true, Ordering::SeqCst) {
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 array = Int32Array::new(&memory_buffer);
// Use `Promise.then` on a resolved promise to place our execution
// onto the next turn of the microtask queue, enqueueing our poll
// operation. We don't currently poll immediately as it turns out
// `futures` crate adapters aren't compatible with it and it also
// 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 |_| {
Package::poll(&me);
}) 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`.
pub fn spawn_local<F>(future: F)
where
F: Future<Item = (), Error = ()> + 'static,
where
F: Future<Item = (), Error = ()> + 'static,
{
future_to_promise(
future

View File

@ -102,7 +102,6 @@
//! ```
#![feature(stdsimd)]
#![deny(missing_docs)]
#[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
State::Polling => {
me.notified.set(State::Waiting(me.clone()));
break;
}
State::Waiting(_) => {
panic!("shouldn't see waiting state!")
}
State::Waiting(_) => panic!("shouldn't see waiting state!"),
}
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::{
encode_uri_component, Array, Atomics, Error, Function, Int32Array, JsString, Promise, Reflect,
SharedArrayBuffer,
SharedArrayBuffer, WebAssembly,
};
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
@ -57,6 +57,8 @@ extern "C" {
fn log(s: &str);
}
const DEFAULT_TIMEOUT: f64 = 10.0;
const HELPER_CODE: &'static str = "
onmessage = function (ev) {
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> {
let timeout = 0.1;
wait_async_with_timeout(indexed_array, index, value, timeout)
pub fn wait_async(index: u32, value: i32) -> Result<Promise, JsValue> {
wait_async_with_timeout(index, value, DEFAULT_TIMEOUT)
}
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
// Atomics.wait, or, in the case something went completely wrong, it is
// rejected with an error string.
pub fn wait_async_with_timeout(
indexed_array: Int32Array,
index: u32,
value: i32,
timeout: f64,
) -> Result<Promise, JsValue> {
pub fn wait_async_with_timeout(index: u32, value: i32, timeout: f64) -> Result<Promise, JsValue> {
let memory_buffer = wasm_bindgen::memory()
.dyn_into::<WebAssembly::Memory>()
.expect("Should cast a memory to WebAssembly::Memory")
.buffer();
let indexed_array = Int32Array::new(&memory_buffer);
if !indexed_array.buffer().has_type::<SharedArrayBuffer>() {
console_log!("polyfill, not a SharedArrayBuffer");
return Err(Error::new("Indexed array must be created from SharedArrayBuffer").into());