mirror of
https://github.com/async-rs/async-std.git
synced 2025-01-29 16:55:34 +00:00
feat: add basic wasm support
This commit is contained in:
parent
2cd2ba3530
commit
e4df1405c1
37 changed files with 301 additions and 64 deletions
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
|
@ -58,6 +58,14 @@ jobs:
|
|||
with:
|
||||
command: check
|
||||
args: --features unstable --all --bins --examples --tests
|
||||
|
||||
- name: check wasm
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: check
|
||||
target: wasm32-unknown-unknown
|
||||
override: true
|
||||
args: --features unstable --all --bins --tests
|
||||
|
||||
- name: check bench
|
||||
uses: actions-rs/cargo@v1
|
||||
|
|
11
Cargo.toml
11
Cargo.toml
|
@ -63,14 +63,25 @@ once_cell = { version = "1.3.1", optional = true }
|
|||
pin-project-lite = { version = "0.1.4", optional = true }
|
||||
pin-utils = { version = "0.1.0-alpha.4", optional = true }
|
||||
slab = { version = "0.4.2", optional = true }
|
||||
|
||||
[target.'cfg(not(target_os = "unknown"))'.dependencies]
|
||||
smol = { path = "../smol", optional = true }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
wasm-timer = "0.2.4"
|
||||
wasm-bindgen-futures = "0.4.10"
|
||||
futures-channel = "0.3.4"
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
|
||||
wasm-bindgen-test = "0.3.10"
|
||||
|
||||
[dev-dependencies]
|
||||
femme = "1.3.0"
|
||||
rand = "0.7.3"
|
||||
surf = "1.0.3"
|
||||
tempdir = "0.3.7"
|
||||
futures = "0.3.4"
|
||||
rand_xorshift = "0.2.0"
|
||||
|
||||
[[test]]
|
||||
name = "stream"
|
||||
|
|
|
@ -3,9 +3,9 @@ use std::pin::Pin;
|
|||
use std::time::Duration;
|
||||
|
||||
use pin_project_lite::pin_project;
|
||||
use smol::Timer;
|
||||
|
||||
use crate::task::{Context, Poll};
|
||||
use crate::utils::Timer;
|
||||
|
||||
pin_project! {
|
||||
#[doc(hidden)]
|
||||
|
|
|
@ -5,9 +5,9 @@ use std::pin::Pin;
|
|||
use std::time::Duration;
|
||||
|
||||
use pin_project_lite::pin_project;
|
||||
use smol::Timer;
|
||||
|
||||
use crate::task::{Context, Poll};
|
||||
use crate::utils::Timer;
|
||||
|
||||
/// Awaits a future or times out after a duration of time.
|
||||
///
|
||||
|
|
|
@ -307,22 +307,33 @@ cfg_std! {
|
|||
cfg_default! {
|
||||
// For use in the print macros.
|
||||
#[doc(hidden)]
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub use stdio::{_eprint, _print};
|
||||
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub use stderr::{stderr, Stderr};
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub use stdin::{stdin, Stdin};
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub use stdout::{stdout, Stdout};
|
||||
pub use timeout::timeout;
|
||||
|
||||
mod timeout;
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
mod stderr;
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
mod stdin;
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
mod stdio;
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
mod stdout;
|
||||
}
|
||||
|
||||
cfg_unstable_default! {
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub use stderr::StderrLock;
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub use stdin::StdinLock;
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub use stdout::StdoutLock;
|
||||
}
|
||||
|
|
|
@ -17,9 +17,9 @@ use std::mem;
|
|||
|
||||
use crate::io::IoSliceMut;
|
||||
|
||||
pub use take::Take;
|
||||
pub use bytes::Bytes;
|
||||
pub use chain::Chain;
|
||||
pub use take::Take;
|
||||
|
||||
extension_trait! {
|
||||
use std::pin::Pin;
|
||||
|
@ -483,7 +483,7 @@ mod tests {
|
|||
use crate::prelude::*;
|
||||
|
||||
#[test]
|
||||
fn test_read_by_ref() -> io::Result<()> {
|
||||
fn test_read_by_ref() {
|
||||
crate::task::block_on(async {
|
||||
let mut f = io::Cursor::new(vec![0u8, 1, 2, 3, 4, 5, 6, 7, 8]);
|
||||
let mut buffer = Vec::new();
|
||||
|
@ -493,14 +493,13 @@ mod tests {
|
|||
let reference = f.by_ref();
|
||||
|
||||
// read at most 5 bytes
|
||||
assert_eq!(reference.take(5).read_to_end(&mut buffer).await?, 5);
|
||||
assert_eq!(reference.take(5).read_to_end(&mut buffer).await.unwrap(), 5);
|
||||
assert_eq!(&buffer, &[0, 1, 2, 3, 4])
|
||||
} // drop our &mut reference so we can use f again
|
||||
|
||||
// original file still usable, read the rest
|
||||
assert_eq!(f.read_to_end(&mut other_buffer).await?, 4);
|
||||
assert_eq!(f.read_to_end(&mut other_buffer).await.unwrap(), 4);
|
||||
assert_eq!(&other_buffer, &[5, 6, 7, 8]);
|
||||
Ok(())
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -218,7 +218,7 @@ impl<T: BufRead> BufRead for Take<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(all(test, not(target_os = "unknown")))]
|
||||
mod tests {
|
||||
use crate::io;
|
||||
use crate::prelude::*;
|
||||
|
|
|
@ -4,9 +4,9 @@ use std::task::{Context, Poll};
|
|||
use std::time::Duration;
|
||||
|
||||
use pin_project_lite::pin_project;
|
||||
use smol::Timer;
|
||||
|
||||
use crate::io;
|
||||
use crate::utils::Timer;
|
||||
|
||||
/// Awaits an I/O future or times out after a duration of time.
|
||||
///
|
||||
|
|
|
@ -267,14 +267,17 @@ cfg_std! {
|
|||
}
|
||||
|
||||
cfg_default! {
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub mod fs;
|
||||
pub mod path;
|
||||
pub mod net;
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub(crate) mod rt;
|
||||
}
|
||||
|
||||
cfg_unstable! {
|
||||
pub mod pin;
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub mod process;
|
||||
|
||||
mod unit;
|
||||
|
|
|
@ -61,10 +61,16 @@ pub use std::net::Shutdown;
|
|||
pub use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
pub use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6};
|
||||
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub use addr::ToSocketAddrs;
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub use tcp::{Incoming, TcpListener, TcpStream};
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub use udp::UdpSocket;
|
||||
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
mod addr;
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
mod tcp;
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
mod udp;
|
||||
|
|
|
@ -4,9 +4,9 @@ use std::ffi::{OsStr, OsString};
|
|||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::fs;
|
||||
use crate::io;
|
||||
use crate::path::{Ancestors, Components, Display, Iter, PathBuf, StripPrefixError};
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
use crate::{fs, io};
|
||||
|
||||
/// A slice of a path.
|
||||
///
|
||||
|
@ -584,6 +584,7 @@ impl Path {
|
|||
/// #
|
||||
/// # Ok(()) }) }
|
||||
/// ```
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub async fn metadata(&self) -> io::Result<fs::Metadata> {
|
||||
fs::metadata(self).await
|
||||
}
|
||||
|
@ -607,6 +608,7 @@ impl Path {
|
|||
/// #
|
||||
/// # Ok(()) }) }
|
||||
/// ```
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub async fn symlink_metadata(&self) -> io::Result<fs::Metadata> {
|
||||
fs::symlink_metadata(self).await
|
||||
}
|
||||
|
@ -632,6 +634,7 @@ impl Path {
|
|||
/// #
|
||||
/// # Ok(()) }) }
|
||||
/// ```
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub async fn canonicalize(&self) -> io::Result<PathBuf> {
|
||||
fs::canonicalize(self).await
|
||||
}
|
||||
|
@ -654,6 +657,7 @@ impl Path {
|
|||
/// #
|
||||
/// # Ok(()) }) }
|
||||
/// ```
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub async fn read_link(&self) -> io::Result<PathBuf> {
|
||||
fs::read_link(self).await
|
||||
}
|
||||
|
@ -688,6 +692,7 @@ impl Path {
|
|||
/// #
|
||||
/// # Ok(()) }) }
|
||||
/// ```
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub async fn read_dir(&self) -> io::Result<fs::ReadDir> {
|
||||
fs::read_dir(self).await
|
||||
}
|
||||
|
@ -717,6 +722,7 @@ impl Path {
|
|||
/// check errors, call [fs::metadata].
|
||||
///
|
||||
/// [fs::metadata]: ../fs/fn.metadata.html
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub async fn exists(&self) -> bool {
|
||||
fs::metadata(self).await.is_ok()
|
||||
}
|
||||
|
@ -749,6 +755,7 @@ impl Path {
|
|||
///
|
||||
/// [fs::metadata]: ../fs/fn.metadata.html
|
||||
/// [fs::Metadata::is_file]: ../fs/struct.Metadata.html#method.is_file
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub async fn is_file(&self) -> bool {
|
||||
fs::metadata(self)
|
||||
.await
|
||||
|
@ -785,6 +792,7 @@ impl Path {
|
|||
///
|
||||
/// [fs::metadata]: ../fs/fn.metadata.html
|
||||
/// [fs::Metadata::is_dir]: ../fs/struct.Metadata.html#method.is_dir
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub async fn is_dir(&self) -> bool {
|
||||
fs::metadata(self)
|
||||
.await
|
||||
|
|
|
@ -4,7 +4,7 @@ use std::task::{Context, Poll};
|
|||
use std::time::Duration;
|
||||
|
||||
use crate::stream::Stream;
|
||||
use smol::Timer;
|
||||
use crate::utils::Timer;
|
||||
|
||||
/// Creates a new stream that yields at a set interval.
|
||||
///
|
||||
|
|
|
@ -3,10 +3,10 @@ use core::pin::Pin;
|
|||
use core::time::Duration;
|
||||
|
||||
use pin_project_lite::pin_project;
|
||||
use smol::Timer;
|
||||
|
||||
use crate::stream::Stream;
|
||||
use crate::task::{Context, Poll};
|
||||
use crate::utils::Timer;
|
||||
|
||||
pin_project! {
|
||||
#[doc(hidden)]
|
||||
|
|
|
@ -3,10 +3,10 @@ use std::pin::Pin;
|
|||
use std::time::Duration;
|
||||
|
||||
use pin_project_lite::pin_project;
|
||||
use smol::Timer;
|
||||
|
||||
use crate::stream::Stream;
|
||||
use crate::task::{Context, Poll};
|
||||
use crate::utils::Timer;
|
||||
|
||||
pin_project! {
|
||||
/// A stream that only yields one element once every `duration`.
|
||||
|
|
|
@ -5,10 +5,10 @@ use std::pin::Pin;
|
|||
use std::time::Duration;
|
||||
|
||||
use pin_project_lite::pin_project;
|
||||
use smol::Timer;
|
||||
|
||||
use crate::stream::Stream;
|
||||
use crate::task::{Context, Poll};
|
||||
use crate::utils::Timer;
|
||||
|
||||
pin_project! {
|
||||
/// A stream with timeout time set
|
||||
|
|
|
@ -202,7 +202,7 @@ impl BarrierWaitResult {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(all(test, not(target_os = "unknown")))]
|
||||
mod test {
|
||||
use futures::channel::mpsc::unbounded;
|
||||
use futures::sink::SinkExt;
|
||||
|
|
|
@ -25,9 +25,20 @@ use crate::task::Builder;
|
|||
/// })
|
||||
/// }
|
||||
/// ```
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub fn block_on<F, T>(future: F) -> T
|
||||
where
|
||||
F: Future<Output = T>,
|
||||
{
|
||||
Builder::new().blocking(future)
|
||||
}
|
||||
|
||||
/// Spawns a task and waits for it to finish.
|
||||
#[cfg(target_os = "unknown")]
|
||||
pub fn block_on<F, T>(future: F)
|
||||
where
|
||||
F: Future<Output = T> + 'static,
|
||||
T: 'static,
|
||||
{
|
||||
Builder::new().local(future).unwrap();
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ use std::pin::Pin;
|
|||
use std::sync::Arc;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use kv_log_macro::trace;
|
||||
use pin_project_lite::pin_project;
|
||||
|
||||
use crate::io;
|
||||
|
@ -38,15 +37,16 @@ impl Builder {
|
|||
// Create a new task handle.
|
||||
let task = Task::new(name);
|
||||
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
once_cell::sync::Lazy::force(&crate::rt::RUNTIME);
|
||||
|
||||
let tag = TaskLocalsWrapper::new(task.clone());
|
||||
|
||||
// FIXME: do not require all futures to be boxed.
|
||||
SupportTaskLocals { tag, future }
|
||||
}
|
||||
|
||||
/// Spawns a task with the configured settings.
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub fn spawn<F, T>(self, future: F) -> io::Result<JoinHandle<T>>
|
||||
where
|
||||
F: Future<Output = T> + Send + 'static,
|
||||
|
@ -61,6 +61,7 @@ impl Builder {
|
|||
}
|
||||
|
||||
/// Spawns a task locally with the configured settings.
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub fn local<F, T>(self, future: F) -> io::Result<JoinHandle<T>>
|
||||
where
|
||||
F: Future<Output = T> + 'static,
|
||||
|
@ -74,7 +75,29 @@ impl Builder {
|
|||
Ok(JoinHandle::new(smol_task, task))
|
||||
}
|
||||
|
||||
/// Spawns a task locally with the configured settings.
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub fn local<F, T>(self, future: F) -> io::Result<JoinHandle<T>>
|
||||
where
|
||||
F: Future<Output = T> + 'static,
|
||||
T: 'static,
|
||||
{
|
||||
use futures_channel::oneshot::channel;
|
||||
let (sender, receiver) = channel();
|
||||
|
||||
let wrapped = self.build(async move {
|
||||
let res = future.await;
|
||||
let _ = sender.send(res);
|
||||
});
|
||||
|
||||
let task = wrapped.tag.task().clone();
|
||||
wasm_bindgen_futures::spawn_local(wrapped);
|
||||
|
||||
Ok(JoinHandle::new(receiver, task))
|
||||
}
|
||||
|
||||
/// Spawns a task with the configured settings, blocking on its execution.
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub fn blocking<F, T>(self, future: F) -> T
|
||||
where
|
||||
F: Future<Output = T>,
|
||||
|
@ -82,7 +105,7 @@ impl Builder {
|
|||
let wrapped = self.build(future);
|
||||
|
||||
// Log this `block_on` operation.
|
||||
trace!("block_on", {
|
||||
kv_log_macro::trace!("block_on", {
|
||||
task_id: wrapped.tag.id().0,
|
||||
parent_task_id: TaskLocalsWrapper::get_current(|t| t.id().0).unwrap_or(0),
|
||||
});
|
||||
|
|
|
@ -13,13 +13,18 @@ use crate::task::{Context, Poll, Task};
|
|||
/// [spawned]: fn.spawn.html
|
||||
#[derive(Debug)]
|
||||
pub struct JoinHandle<T> {
|
||||
handle: Option<async_task::JoinHandle<T, ()>>,
|
||||
handle: Option<InnerHandle<T>>,
|
||||
task: Task,
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
type InnerHandle<T> = async_task::JoinHandle<T, ()>;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
type InnerHandle<T> = futures_channel::oneshot::Receiver<T>;
|
||||
|
||||
impl<T> JoinHandle<T> {
|
||||
/// Creates a new `JoinHandle`.
|
||||
pub(crate) fn new(inner: async_task::JoinHandle<T, ()>, task: Task) -> JoinHandle<T> {
|
||||
pub(crate) fn new(inner: InnerHandle<T>, task: Task) -> JoinHandle<T> {
|
||||
JoinHandle {
|
||||
handle: Some(inner),
|
||||
task,
|
||||
|
@ -46,11 +51,20 @@ impl<T> JoinHandle<T> {
|
|||
}
|
||||
|
||||
/// Cancel this task.
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub async fn cancel(mut self) -> Option<T> {
|
||||
let handle = self.handle.take().unwrap();
|
||||
handle.cancel();
|
||||
handle.await
|
||||
}
|
||||
|
||||
/// Cancel this task.
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub async fn cancel(mut self) -> Option<T> {
|
||||
let mut handle = self.handle.take().unwrap();
|
||||
handle.close();
|
||||
handle.await.ok()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Future for JoinHandle<T> {
|
||||
|
|
|
@ -138,6 +138,7 @@ cfg_default! {
|
|||
pub use task_id::TaskId;
|
||||
pub use join_handle::JoinHandle;
|
||||
pub use sleep::sleep;
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub use spawn::spawn;
|
||||
pub use spawn_local::spawn_local;
|
||||
pub use task_local::{AccessError, LocalKey};
|
||||
|
@ -150,7 +151,9 @@ cfg_default! {
|
|||
mod current;
|
||||
mod join_handle;
|
||||
mod sleep;
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
mod spawn;
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
mod spawn_blocking;
|
||||
mod spawn_local;
|
||||
mod task;
|
||||
|
@ -158,8 +161,10 @@ cfg_default! {
|
|||
mod task_local;
|
||||
mod task_locals_wrapper;
|
||||
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
#[cfg(any(feature = "unstable", test))]
|
||||
pub use spawn_blocking::spawn_blocking;
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
#[cfg(not(any(feature = "unstable", test)))]
|
||||
pub(crate) use spawn_blocking::spawn_blocking;
|
||||
}
|
||||
|
|
31
src/utils.rs
31
src/utils.rs
|
@ -59,6 +59,37 @@ pub(crate) trait Context {
|
|||
fn context(self, message: impl Fn() -> String) -> Self;
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
pub(crate) type Timer = smol::Timer;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Timer(wasm_timer::Delay);
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
impl Timer {
|
||||
pub(crate) fn after(dur: std::time::Duration) -> Self {
|
||||
Timer(wasm_timer::Delay::new(dur))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use std::pin::Pin;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use std::task::Poll;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
impl std::future::Future for Timer {
|
||||
type Output = ();
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll<Self::Output> {
|
||||
match Pin::new(&mut self.0).poll(cx) {
|
||||
Poll::Pending => Poll::Pending,
|
||||
Poll::Ready(_) => Poll::Ready(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Defers evaluation of a block of code until the end of the scope.
|
||||
#[cfg(feature = "default")]
|
||||
#[doc(hidden)]
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![cfg(not(target_os = "unknown"))]
|
||||
|
||||
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
|
||||
|
||||
use async_std::net::ToSocketAddrs;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![cfg(not(target_os = "unknown"))]
|
||||
|
||||
use async_std::task;
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -2,15 +2,19 @@ use async_std::io::{self, BufWriter, SeekFrom};
|
|||
use async_std::prelude::*;
|
||||
use async_std::task;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn test_buffered_writer() {
|
||||
#![allow(clippy::cognitive_complexity)]
|
||||
task::block_on(async {
|
||||
let inner = Vec::new();
|
||||
let mut writer = BufWriter::with_capacity(2, inner);
|
||||
let inner: Vec<u8> = Vec::new();
|
||||
let mut writer = BufWriter::<Vec<u8>>::with_capacity(2, inner);
|
||||
|
||||
writer.write(&[0, 1]).await.unwrap();
|
||||
assert_eq!(writer.buffer(), []);
|
||||
assert!(writer.buffer().is_empty());
|
||||
assert_eq!(*writer.get_ref(), [0, 1]);
|
||||
|
||||
writer.write(&[2]).await.unwrap();
|
||||
|
@ -22,7 +26,7 @@ fn test_buffered_writer() {
|
|||
assert_eq!(*writer.get_ref(), [0, 1]);
|
||||
|
||||
writer.flush().await.unwrap();
|
||||
assert_eq!(writer.buffer(), []);
|
||||
assert!(writer.buffer().is_empty());
|
||||
assert_eq!(*writer.get_ref(), [0, 1, 2, 3]);
|
||||
|
||||
writer.write(&[4]).await.unwrap();
|
||||
|
@ -35,31 +39,33 @@ fn test_buffered_writer() {
|
|||
assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5]);
|
||||
|
||||
writer.write(&[7, 8]).await.unwrap();
|
||||
assert_eq!(writer.buffer(), []);
|
||||
assert!(writer.buffer().is_empty());
|
||||
assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8]);
|
||||
|
||||
writer.write(&[9, 10, 11]).await.unwrap();
|
||||
assert_eq!(writer.buffer(), []);
|
||||
assert!(writer.buffer().is_empty());
|
||||
assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
|
||||
|
||||
writer.flush().await.unwrap();
|
||||
assert_eq!(writer.buffer(), []);
|
||||
assert!(writer.buffer().is_empty());
|
||||
assert_eq!(*writer.get_ref(), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn test_buffered_writer_inner_into_inner_flushes() {
|
||||
task::block_on(async {
|
||||
let mut w = BufWriter::with_capacity(3, Vec::new());
|
||||
let mut w = BufWriter::with_capacity(3, Vec::<u8>::new());
|
||||
w.write(&[0, 1]).await.unwrap();
|
||||
assert_eq!(*w.get_ref(), []);
|
||||
assert!(w.get_ref().is_empty());
|
||||
let w = w.into_inner().await.unwrap();
|
||||
assert_eq!(w, [0, 1]);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn test_buffered_writer_seek() {
|
||||
task::block_on(async {
|
||||
let mut w = BufWriter::with_capacity(3, io::Cursor::new(Vec::new()));
|
||||
|
|
|
@ -6,13 +6,22 @@ use std::time::Duration;
|
|||
|
||||
use async_std::sync::channel;
|
||||
use async_std::task;
|
||||
use rand::{thread_rng, Rng};
|
||||
use rand::{Rng, SeedableRng};
|
||||
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
use async_std::task::spawn;
|
||||
#[cfg(target_os = "unknown")]
|
||||
use async_std::task::spawn_local as spawn;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
fn ms(ms: u64) -> Duration {
|
||||
Duration::from_millis(ms)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn smoke() {
|
||||
task::block_on(async {
|
||||
let (s, r) = channel(1);
|
||||
|
@ -35,6 +44,7 @@ fn smoke() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn capacity() {
|
||||
for i in 1..10 {
|
||||
let (s, r) = channel::<()>(i);
|
||||
|
@ -44,6 +54,7 @@ fn capacity() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn len_empty_full() {
|
||||
#![allow(clippy::cognitive_complexity)]
|
||||
task::block_on(async {
|
||||
|
@ -86,11 +97,12 @@ fn len_empty_full() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn recv() {
|
||||
task::block_on(async {
|
||||
let (s, r) = channel(100);
|
||||
|
||||
task::spawn(async move {
|
||||
spawn(async move {
|
||||
assert_eq!(r.recv().await.unwrap(), 7);
|
||||
task::sleep(ms(1000)).await;
|
||||
assert_eq!(r.recv().await.unwrap(), 8);
|
||||
|
@ -107,11 +119,12 @@ fn recv() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn send() {
|
||||
task::block_on(async {
|
||||
let (s, r) = channel(1);
|
||||
|
||||
task::spawn(async move {
|
||||
spawn(async move {
|
||||
s.send(7).await;
|
||||
task::sleep(ms(1000)).await;
|
||||
s.send(8).await;
|
||||
|
@ -129,6 +142,7 @@ fn send() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn recv_after_disconnect() {
|
||||
task::block_on(async {
|
||||
let (s, r) = channel(100);
|
||||
|
@ -147,6 +161,7 @@ fn recv_after_disconnect() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn len() {
|
||||
const COUNT: usize = 25_000;
|
||||
const CAP: usize = 1000;
|
||||
|
@ -184,7 +199,7 @@ fn len() {
|
|||
assert_eq!(s.len(), 0);
|
||||
assert_eq!(r.len(), 0);
|
||||
|
||||
let child = task::spawn({
|
||||
let child = spawn({
|
||||
let r = r.clone();
|
||||
async move {
|
||||
for i in 0..COUNT {
|
||||
|
@ -209,11 +224,12 @@ fn len() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn disconnect_wakes_receiver() {
|
||||
task::block_on(async {
|
||||
let (s, r) = channel::<()>(1);
|
||||
|
||||
let child = task::spawn(async move {
|
||||
let child = spawn(async move {
|
||||
assert!(r.recv().await.is_err());
|
||||
});
|
||||
|
||||
|
@ -225,13 +241,14 @@ fn disconnect_wakes_receiver() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn spsc() {
|
||||
const COUNT: usize = 100_000;
|
||||
|
||||
task::block_on(async {
|
||||
let (s, r) = channel(3);
|
||||
|
||||
let child = task::spawn(async move {
|
||||
let child = spawn(async move {
|
||||
for i in 0..COUNT {
|
||||
assert_eq!(r.recv().await.unwrap(), i);
|
||||
}
|
||||
|
@ -248,6 +265,7 @@ fn spsc() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn mpmc() {
|
||||
const COUNT: usize = 25_000;
|
||||
const TASKS: usize = 4;
|
||||
|
@ -262,7 +280,7 @@ fn mpmc() {
|
|||
for _ in 0..TASKS {
|
||||
let r = r.clone();
|
||||
let v = v.clone();
|
||||
tasks.push(task::spawn(async move {
|
||||
tasks.push(spawn(async move {
|
||||
for _ in 0..COUNT {
|
||||
let n = r.recv().await.unwrap();
|
||||
v[n].fetch_add(1, Ordering::SeqCst);
|
||||
|
@ -272,7 +290,7 @@ fn mpmc() {
|
|||
|
||||
for _ in 0..TASKS {
|
||||
let s = s.clone();
|
||||
tasks.push(task::spawn(async move {
|
||||
tasks.push(spawn(async move {
|
||||
for i in 0..COUNT {
|
||||
s.send(i).await;
|
||||
}
|
||||
|
@ -290,6 +308,7 @@ fn mpmc() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn oneshot() {
|
||||
const COUNT: usize = 10_000;
|
||||
|
||||
|
@ -297,8 +316,8 @@ fn oneshot() {
|
|||
for _ in 0..COUNT {
|
||||
let (s, r) = channel(1);
|
||||
|
||||
let c1 = task::spawn(async move { r.recv().await.unwrap() });
|
||||
let c2 = task::spawn(async move { s.send(0).await });
|
||||
let c1 = spawn(async move { r.recv().await.unwrap() });
|
||||
let c2 = spawn(async move { s.send(0).await });
|
||||
|
||||
c1.await;
|
||||
c2.await;
|
||||
|
@ -307,6 +326,7 @@ fn oneshot() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn drops() {
|
||||
const RUNS: usize = 100;
|
||||
|
||||
|
@ -321,17 +341,16 @@ fn drops() {
|
|||
}
|
||||
}
|
||||
|
||||
let mut rng = thread_rng();
|
||||
|
||||
for _ in 0..RUNS {
|
||||
task::block_on(async {
|
||||
let mut rng = rand_xorshift::XorShiftRng::seed_from_u64(0);
|
||||
task::block_on(async move {
|
||||
let steps = rng.gen_range(0, 10_000);
|
||||
let additional = rng.gen_range(0, 50);
|
||||
|
||||
DROPS.store(0, Ordering::SeqCst);
|
||||
let (s, r) = channel::<DropCounter>(50);
|
||||
|
||||
let child = task::spawn({
|
||||
let child = spawn({
|
||||
let r = r.clone();
|
||||
async move {
|
||||
for _ in 0..steps {
|
||||
|
|
|
@ -5,13 +5,22 @@ use std::time::Duration;
|
|||
use async_std::sync::{Condvar, Mutex};
|
||||
use async_std::task::{self, JoinHandle};
|
||||
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
use async_std::task::spawn;
|
||||
#[cfg(target_os = "unknown")]
|
||||
use async_std::task::spawn_local as spawn;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn wait_timeout_with_lock() {
|
||||
task::block_on(async {
|
||||
let pair = Arc::new((Mutex::new(false), Condvar::new()));
|
||||
let pair2 = pair.clone();
|
||||
|
||||
task::spawn(async move {
|
||||
spawn(async move {
|
||||
let (m, c) = &*pair2;
|
||||
let _g = m.lock().await;
|
||||
task::sleep(Duration::from_millis(20)).await;
|
||||
|
@ -27,6 +36,7 @@ fn wait_timeout_with_lock() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn wait_timeout_without_lock() {
|
||||
task::block_on(async {
|
||||
let m = Mutex::new(false);
|
||||
|
@ -40,6 +50,7 @@ fn wait_timeout_without_lock() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn wait_timeout_until_timed_out() {
|
||||
task::block_on(async {
|
||||
let m = Mutex::new(false);
|
||||
|
@ -55,6 +66,7 @@ fn wait_timeout_until_timed_out() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn notify_all() {
|
||||
task::block_on(async {
|
||||
let mut tasks: Vec<JoinHandle<()>> = Vec::new();
|
||||
|
@ -62,7 +74,7 @@ fn notify_all() {
|
|||
|
||||
for _ in 0..10 {
|
||||
let pair = pair.clone();
|
||||
tasks.push(task::spawn(async move {
|
||||
tasks.push(spawn(async move {
|
||||
let (m, c) = &*pair;
|
||||
let mut count = m.lock().await;
|
||||
while *count == 0 {
|
||||
|
|
|
@ -5,6 +5,7 @@ use async_std::task;
|
|||
|
||||
#[test]
|
||||
#[should_panic(expected = "timed out")]
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
fn io_timeout_timedout() {
|
||||
task::block_on(async {
|
||||
io::timeout(Duration::from_secs(1), async {
|
||||
|
|
|
@ -5,7 +5,16 @@ use async_std::sync::Mutex;
|
|||
use async_std::task;
|
||||
use futures::channel::mpsc;
|
||||
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
use async_std::task::spawn;
|
||||
#[cfg(target_os = "unknown")]
|
||||
use async_std::task::spawn_local as spawn;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn smoke() {
|
||||
task::block_on(async {
|
||||
let m = Mutex::new(());
|
||||
|
@ -15,18 +24,21 @@ fn smoke() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn try_lock() {
|
||||
let m = Mutex::new(());
|
||||
*m.try_lock().unwrap() = ();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn into_inner() {
|
||||
let m = Mutex::new(10);
|
||||
assert_eq!(m.into_inner(), 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn get_mut() {
|
||||
let mut m = Mutex::new(10);
|
||||
*m.get_mut() = 20;
|
||||
|
@ -34,21 +46,21 @@ fn get_mut() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn contention() {
|
||||
task::block_on(async {
|
||||
let (tx, mut rx) = mpsc::unbounded();
|
||||
|
||||
let tx = Arc::new(tx);
|
||||
let mutex = Arc::new(Mutex::new(0));
|
||||
let num_tasks = 10; //000;
|
||||
let num_tasks = 10000;
|
||||
|
||||
let mut handles = Vec::new();
|
||||
for _ in 0..num_tasks {
|
||||
let tx = tx.clone();
|
||||
let mutex = mutex.clone();
|
||||
|
||||
dbg!("spawn");
|
||||
handles.push(task::spawn(async move {
|
||||
handles.push(spawn(async move {
|
||||
let mut lock = mutex.lock().await;
|
||||
*lock += 1;
|
||||
tx.unbounded_send(()).unwrap();
|
||||
|
@ -56,8 +68,7 @@ fn contention() {
|
|||
}));
|
||||
}
|
||||
|
||||
for i in 0..num_tasks {
|
||||
dbg!(i);
|
||||
for _ in 0..num_tasks {
|
||||
rx.next().await.unwrap();
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,14 @@ use async_std::sync::RwLock;
|
|||
use async_std::task;
|
||||
use futures::channel::mpsc;
|
||||
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
use async_std::task::spawn;
|
||||
#[cfg(target_os = "unknown")]
|
||||
use async_std::task::spawn_local as spawn;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
/// Generates a random number in `0..n`.
|
||||
pub fn random(n: u32) -> u32 {
|
||||
thread_local! {
|
||||
|
@ -35,6 +43,7 @@ pub fn random(n: u32) -> u32 {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn smoke() {
|
||||
task::block_on(async {
|
||||
let lock = RwLock::new(());
|
||||
|
@ -46,6 +55,7 @@ fn smoke() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn try_write() {
|
||||
task::block_on(async {
|
||||
let lock = RwLock::new(0isize);
|
||||
|
@ -56,12 +66,14 @@ fn try_write() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn into_inner() {
|
||||
let lock = RwLock::new(10);
|
||||
assert_eq!(lock.into_inner(), 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn into_inner_and_drop() {
|
||||
struct Counter(Arc<AtomicUsize>);
|
||||
|
||||
|
@ -84,6 +96,7 @@ fn into_inner_and_drop() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn get_mut() {
|
||||
let mut lock = RwLock::new(10);
|
||||
*lock.get_mut() = 20;
|
||||
|
@ -91,6 +104,7 @@ fn get_mut() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn contention() {
|
||||
const N: u32 = 10;
|
||||
const M: usize = 1000;
|
||||
|
@ -104,7 +118,7 @@ fn contention() {
|
|||
let tx = tx.clone();
|
||||
let rw = rw.clone();
|
||||
|
||||
task::spawn(async move {
|
||||
spawn(async move {
|
||||
for _ in 0..M {
|
||||
if random(N) == 0 {
|
||||
drop(rw.write().await);
|
||||
|
@ -116,7 +130,7 @@ fn contention() {
|
|||
});
|
||||
}
|
||||
|
||||
task::block_on(async {
|
||||
task::block_on(async move {
|
||||
for _ in 0..N {
|
||||
rx.next().await.unwrap();
|
||||
}
|
||||
|
@ -124,6 +138,7 @@ fn contention() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn writer_and_readers() {
|
||||
#[derive(Default)]
|
||||
struct Yield(Cell<bool>);
|
||||
|
@ -146,7 +161,7 @@ fn writer_and_readers() {
|
|||
let (tx, mut rx) = mpsc::unbounded();
|
||||
|
||||
// Spawn a writer task.
|
||||
task::spawn({
|
||||
spawn({
|
||||
let lock = lock.clone();
|
||||
async move {
|
||||
let mut lock = lock.write().await;
|
||||
|
@ -164,13 +179,13 @@ fn writer_and_readers() {
|
|||
let mut readers = Vec::new();
|
||||
for _ in 0..5 {
|
||||
let lock = lock.clone();
|
||||
readers.push(task::spawn(async move {
|
||||
readers.push(spawn(async move {
|
||||
let lock = lock.read().await;
|
||||
assert!(*lock >= 0);
|
||||
}));
|
||||
}
|
||||
|
||||
task::block_on(async {
|
||||
task::block_on(async move {
|
||||
// Wait for readers to pass their asserts.
|
||||
for r in readers {
|
||||
r.await;
|
||||
|
|
|
@ -8,14 +8,23 @@ use async_std::stream;
|
|||
use async_std::sync::channel;
|
||||
use async_std::task;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
use async_std::task::spawn;
|
||||
#[cfg(target_os = "unknown")]
|
||||
use async_std::task::spawn_local as spawn;
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
/// Checks that streams are merged fully even if one of the components
|
||||
/// experiences delay.
|
||||
fn merging_delayed_streams_work() {
|
||||
let (sender, receiver) = channel::<i32>(10);
|
||||
|
||||
let mut s = receiver.merge(stream::empty());
|
||||
let t = task::spawn(async move {
|
||||
let t = spawn(async move {
|
||||
let mut xs = Vec::new();
|
||||
while let Some(x) = s.next().await {
|
||||
xs.push(x);
|
||||
|
@ -34,7 +43,7 @@ fn merging_delayed_streams_work() {
|
|||
let (sender, receiver) = channel::<i32>(10);
|
||||
|
||||
let mut s = stream::empty().merge(receiver);
|
||||
let t = task::spawn(async move {
|
||||
let t = spawn(async move {
|
||||
let mut xs = Vec::new();
|
||||
while let Some(x) = s.next().await {
|
||||
xs.push(x);
|
||||
|
@ -85,16 +94,17 @@ fn explode<S: Stream>(s: S) -> Explode<S> {
|
|||
}
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn merge_works_with_unfused_streams() {
|
||||
let s1 = explode(stream::once(92));
|
||||
let s2 = explode(stream::once(92));
|
||||
let mut s = s1.merge(s2);
|
||||
let xs = task::block_on(async move {
|
||||
|
||||
task::block_on(async move {
|
||||
let mut xs = Vec::new();
|
||||
while let Some(x) = s.next().await {
|
||||
xs.push(x)
|
||||
}
|
||||
xs
|
||||
assert_eq!(xs, vec![92, 92]);
|
||||
});
|
||||
assert_eq!(xs, vec![92, 92]);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,16 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
|||
use async_std::task;
|
||||
use async_std::task_local;
|
||||
|
||||
#[cfg(not(target_os = "unknown"))]
|
||||
use async_std::task::spawn;
|
||||
#[cfg(target_os = "unknown")]
|
||||
use async_std::task::spawn_local as spawn;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn drop_local() {
|
||||
static DROP_LOCAL: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
|
@ -20,7 +29,7 @@ fn drop_local() {
|
|||
}
|
||||
|
||||
// Spawn a task that just touches its task-local.
|
||||
let handle = task::spawn(async {
|
||||
let handle = spawn(async {
|
||||
LOCAL.with(|_| ());
|
||||
});
|
||||
let task = handle.task().clone();
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![cfg(not(target_os = "unknown"))]
|
||||
|
||||
use async_std::io;
|
||||
use async_std::net::{TcpListener, TcpStream};
|
||||
use async_std::prelude::*;
|
||||
|
|
|
@ -3,7 +3,11 @@ use std::time::Duration;
|
|||
use async_std::future::timeout;
|
||||
use async_std::task;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
|
||||
|
||||
#[test]
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
|
||||
fn timeout_future_many() {
|
||||
task::block_on(async {
|
||||
let futures = (0..100)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![cfg(not(target_os = "unknown"))]
|
||||
|
||||
use async_std::io;
|
||||
use async_std::net::UdpSocket;
|
||||
use async_std::task;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#![cfg(unix)]
|
||||
#![cfg(all(unix, not(target_os = "unknown")))]
|
||||
|
||||
use async_std::io;
|
||||
use async_std::os::unix::net::{UnixDatagram, UnixListener, UnixStream};
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![cfg(not(target_os = "unknown"))]
|
||||
|
||||
use async_std::{fs, io, net::ToSocketAddrs, task};
|
||||
|
||||
#[test]
|
||||
|
|
10
wasm-test.sh
Executable file
10
wasm-test.sh
Executable file
|
@ -0,0 +1,10 @@
|
|||
#!/bin/sh
|
||||
|
||||
wasm-pack test --chrome --headless -- --features unstable --test buf_writer
|
||||
wasm-pack test --chrome --headless -- --features unstable --test channel
|
||||
wasm-pack test --chrome --headless -- --features unstable --test condvar
|
||||
wasm-pack test --chrome --headless -- --features unstable --test mutex
|
||||
wasm-pack test --chrome --headless -- --features unstable --test rwlock
|
||||
wasm-pack test --chrome --headless -- --features unstable --test stream
|
||||
wasm-pack test --chrome --headless -- --features unstable --test task_local
|
||||
wasm-pack test --chrome --headless -- --features unstable --test timeout
|
Loading…
Reference in a new issue