Modernize dependencies
diff --git a/Cargo.toml b/Cargo.toml
index 2db902e..fb3c127 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,6 +17,9 @@
std = []
[dev-dependencies]
+atomic-waker = "1.0.0"
+concurrent-queue = "1.2.2"
crossbeam = "0.7.3"
-futures = "0.3.4"
-lazy_static = "1.4.0"
+easy-parallel = "3.1.0"
+futures-lite = "1.7.0"
+once_cell = "1.4.1"
diff --git a/examples/panic-propagation.rs b/examples/panic-propagation.rs
index 8d9be39..6dd6128 100644
--- a/examples/panic-propagation.rs
+++ b/examples/panic-propagation.rs
@@ -8,9 +8,8 @@
use async_task::Task;
use crossbeam::channel::{unbounded, Sender};
-use futures::executor;
-use futures::future::FutureExt;
-use lazy_static::lazy_static;
+use futures_lite::{future, FutureExt};
+use once_cell::sync::Lazy;
/// Spawns a future on the executor.
fn spawn<F, R>(future: F) -> JoinHandle<R>
@@ -18,22 +17,20 @@
F: Future<Output = R> + Send + 'static,
R: Send + 'static,
{
- lazy_static! {
- // A channel that holds scheduled tasks.
- static ref QUEUE: Sender<Task> = {
- let (sender, receiver) = unbounded::<Task>();
+ // A channel that holds scheduled tasks.
+ static QUEUE: Lazy<Sender<Task>> = Lazy::new(|| {
+ let (sender, receiver) = unbounded::<Task>();
- // Start the executor thread.
- thread::spawn(|| {
- for task in receiver {
- // No need for `catch_unwind()` here because panics are already caught.
- task.run();
- }
- });
+ // Start the executor thread.
+ thread::spawn(|| {
+ for task in receiver {
+ // No need for `catch_unwind()` here because panics are already caught.
+ task.run();
+ }
+ });
- sender
- };
- }
+ sender
+ });
// Create a future that catches panics within itself.
let future = AssertUnwindSafe(future).catch_unwind();
@@ -70,5 +67,5 @@
let handle = spawn(async {
panic!("Ooops!");
});
- executor::block_on(handle);
+ future::block_on(handle);
}
diff --git a/examples/panic-result.rs b/examples/panic-result.rs
index 10da772..09f73b8 100644
--- a/examples/panic-result.rs
+++ b/examples/panic-result.rs
@@ -6,9 +6,8 @@
use async_task::{JoinHandle, Task};
use crossbeam::channel::{unbounded, Sender};
-use futures::executor;
-use futures::future::FutureExt;
-use lazy_static::lazy_static;
+use futures_lite::{future, FutureExt};
+use once_cell::sync::Lazy;
/// Spawns a future on the executor.
fn spawn<F, R>(future: F) -> JoinHandle<thread::Result<R>>
@@ -16,22 +15,20 @@
F: Future<Output = R> + Send + 'static,
R: Send + 'static,
{
- lazy_static! {
- // A channel that holds scheduled tasks.
- static ref QUEUE: Sender<Task> = {
- let (sender, receiver) = unbounded::<Task>();
+ // A channel that holds scheduled tasks.
+ static QUEUE: Lazy<Sender<Task>> = Lazy::new(|| {
+ let (sender, receiver) = unbounded::<Task>();
- // Start the executor thread.
- thread::spawn(|| {
- for task in receiver {
- // No need for `catch_unwind()` here because panics are already caught.
- task.run();
- }
- });
+ // Start the executor thread.
+ thread::spawn(|| {
+ for task in receiver {
+ // No need for `catch_unwind()` here because panics are already caught.
+ task.run();
+ }
+ });
- sender
- };
- }
+ sender
+ });
// Create a future that catches panics within itself.
let future = AssertUnwindSafe(future).catch_unwind();
@@ -53,7 +50,7 @@
});
// Block on the future and report its result.
- match executor::block_on(handle) {
+ match future::block_on(handle) {
None => println!("The task was canceled."),
Some(Ok(val)) => println!("The task completed with {:?}", val),
Some(Err(_)) => println!("The task has panicked"),
@@ -65,7 +62,7 @@
});
// Block on the future and report its result.
- match executor::block_on(handle) {
+ match future::block_on(handle) {
None => println!("The task was canceled."),
Some(Ok(val)) => println!("The task completed with {:?}", val),
Some(Err(_)) => println!("The task has panicked"),
diff --git a/examples/spawn-on-thread.rs b/examples/spawn-on-thread.rs
index 5c6bf9b..7545b53 100644
--- a/examples/spawn-on-thread.rs
+++ b/examples/spawn-on-thread.rs
@@ -6,7 +6,7 @@
use async_task::JoinHandle;
use crossbeam::channel;
-use futures::executor;
+use futures_lite::future;
/// Spawns a future on a new dedicated thread.
///
@@ -48,7 +48,7 @@
fn main() {
// Spawn a future on a dedicated thread.
- executor::block_on(spawn_on_thread(async {
+ future::block_on(spawn_on_thread(async {
println!("Hello, world!");
}));
}
diff --git a/examples/spawn.rs b/examples/spawn.rs
index 54df1c2..9804939 100644
--- a/examples/spawn.rs
+++ b/examples/spawn.rs
@@ -6,8 +6,8 @@
use async_task::{JoinHandle, Task};
use crossbeam::channel::{unbounded, Sender};
-use futures::executor;
-use lazy_static::lazy_static;
+use futures_lite::future;
+use once_cell::sync::Lazy;
/// Spawns a future on the executor.
fn spawn<F, R>(future: F) -> JoinHandle<R>
@@ -15,22 +15,20 @@
F: Future<Output = R> + Send + 'static,
R: Send + 'static,
{
- lazy_static! {
- // A channel that holds scheduled tasks.
- static ref QUEUE: Sender<Task> = {
- let (sender, receiver) = unbounded::<Task>();
+ // A channel that holds scheduled tasks.
+ static QUEUE: Lazy<Sender<Task>> = Lazy::new(|| {
+ let (sender, receiver) = unbounded::<Task>();
- // Start the executor thread.
- thread::spawn(|| {
- for task in receiver {
- // Ignore panics for simplicity.
- let _ignore_panic = catch_unwind(|| task.run());
- }
- });
+ // Start the executor thread.
+ thread::spawn(|| {
+ for task in receiver {
+ // Ignore panics for simplicity.
+ let _ignore_panic = catch_unwind(|| task.run());
+ }
+ });
- sender
- };
- }
+ sender
+ });
// Create a task that is scheduled by sending itself into the channel.
let schedule = |t| QUEUE.send(t).unwrap();
@@ -47,5 +45,5 @@
let handle = spawn(async {
println!("Hello, world!");
});
- executor::block_on(handle);
+ future::block_on(handle);
}
diff --git a/tests/basic.rs b/tests/basic.rs
index 47dd075..5c40fe5 100644
--- a/tests/basic.rs
+++ b/tests/basic.rs
@@ -4,10 +4,8 @@
use std::task::{Context, Poll};
use async_task::Task;
-use crossbeam::atomic::AtomicCell;
use crossbeam::channel;
-use futures::future::{self, FutureExt};
-use lazy_static::lazy_static;
+use futures_lite::future;
// Creates a future with event counters.
//
@@ -18,10 +16,8 @@
// When it gets dropped, `DROP` is incremented.
macro_rules! future {
($name:pat, $poll:ident, $drop:ident) => {
- lazy_static! {
- static ref $poll: AtomicCell<usize> = AtomicCell::new(0);
- static ref $drop: AtomicCell<usize> = AtomicCell::new(0);
- }
+ static $poll: AtomicUsize = AtomicUsize::new(0);
+ static $drop: AtomicUsize = AtomicUsize::new(0);
let $name = {
struct Fut(Box<i32>);
@@ -30,14 +26,14 @@
type Output = Box<i32>;
fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
- $poll.fetch_add(1);
+ $poll.fetch_add(1, Ordering::SeqCst);
Poll::Ready(Box::new(0))
}
}
impl Drop for Fut {
fn drop(&mut self) {
- $drop.fetch_add(1);
+ $drop.fetch_add(1, Ordering::SeqCst);
}
}
@@ -55,51 +51,53 @@
// When it gets dropped, `DROP` is incremented.
macro_rules! schedule {
($name:pat, $sched:ident, $drop:ident) => {
- lazy_static! {
- static ref $sched: AtomicCell<usize> = AtomicCell::new(0);
- static ref $drop: AtomicCell<usize> = AtomicCell::new(0);
- }
+ static $drop: AtomicUsize = AtomicUsize::new(0);
+ static $sched: AtomicUsize = AtomicUsize::new(0);
let $name = {
struct Guard(Box<i32>);
impl Drop for Guard {
fn drop(&mut self) {
- $drop.fetch_add(1);
+ $drop.fetch_add(1, Ordering::SeqCst);
}
}
let guard = Guard(Box::new(0));
move |_task| {
&guard;
- $sched.fetch_add(1);
+ $sched.fetch_add(1, Ordering::SeqCst);
}
};
};
}
+fn try_await<T>(f: impl Future<Output = T>) -> Option<T> {
+ future::block_on(future::poll_once(f))
+}
+
#[test]
fn drop_and_detach() {
future!(f, POLL, DROP_F);
schedule!(s, SCHEDULE, DROP_S);
let (task, handle) = async_task::spawn(f, s);
- assert_eq!(POLL.load(), 0);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 0);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
drop(task);
- assert_eq!(POLL.load(), 0);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 0);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
handle.detach();
- assert_eq!(POLL.load(), 0);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 0);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
}
#[test]
@@ -109,16 +107,16 @@
let (task, handle) = async_task::spawn(f, s);
handle.detach();
- assert_eq!(POLL.load(), 0);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 0);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
drop(task);
- assert_eq!(POLL.load(), 0);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 0);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
}
#[test]
@@ -128,16 +126,16 @@
let (task, handle) = async_task::spawn(f, s);
handle.detach();
- assert_eq!(POLL.load(), 0);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 0);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
task.run();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
}
#[test]
@@ -147,16 +145,16 @@
let (task, handle) = async_task::spawn(f, s);
task.run();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
handle.detach();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
}
#[test]
@@ -166,16 +164,16 @@
let (task, handle) = async_task::spawn(f, s);
drop(handle);
- assert_eq!(POLL.load(), 0);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 0);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
task.run();
- assert_eq!(POLL.load(), 0);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 0);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
}
#[test]
@@ -185,16 +183,16 @@
let (task, handle) = async_task::spawn(f, s);
task.run();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
drop(handle);
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
}
#[test]
@@ -203,29 +201,29 @@
schedule!(s, SCHEDULE, DROP_S);
let (task, mut handle) = async_task::spawn(f, s);
- assert!((&mut handle).now_or_never().is_none());
- assert_eq!(POLL.load(), 0);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ assert!(try_await(&mut handle).is_none());
+ assert_eq!(POLL.load(Ordering::SeqCst), 0);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
task.run();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
- assert!((&mut handle).now_or_never().is_some());
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
+ assert!(try_await(&mut handle).is_some());
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
drop(handle);
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
}
#[test]
diff --git a/tests/join.rs b/tests/join.rs
index ca0ef54..caa39a1 100644
--- a/tests/join.rs
+++ b/tests/join.rs
@@ -1,31 +1,28 @@
use std::cell::Cell;
use std::future::Future;
use std::pin::Pin;
+use std::sync::atomic::{AtomicUsize, Ordering};
use std::task::{Context, Poll};
use std::thread;
use std::time::Duration;
use async_task::Task;
-use crossbeam::atomic::AtomicCell;
-use futures::executor::block_on;
-use futures::future;
-use lazy_static::lazy_static;
+use easy_parallel::Parallel;
+use futures_lite::future;
// Creates a future with event counters.
//
-// Usage: `future!(f, POLL, DROP_F, DROP_O)`
+// Usage: `future!(f, POLL, DROP_F, DROP_T)`
//
// The future `f` outputs `Poll::Ready`.
// When it gets polled, `POLL` is incremented.
// When it gets dropped, `DROP_F` is incremented.
-// When the output gets dropped, `DROP_O` is incremented.
+// When the output gets dropped, `DROP_T` is incremented.
macro_rules! future {
- ($name:pat, $poll:ident, $drop_f:ident, $drop_o:ident) => {
- lazy_static! {
- static ref $poll: AtomicCell<usize> = AtomicCell::new(0);
- static ref $drop_f: AtomicCell<usize> = AtomicCell::new(0);
- static ref $drop_o: AtomicCell<usize> = AtomicCell::new(0);
- }
+ ($name:pat, $poll:ident, $drop_f:ident, $drop_t:ident) => {
+ static $poll: AtomicUsize = AtomicUsize::new(0);
+ static $drop_f: AtomicUsize = AtomicUsize::new(0);
+ static $drop_t: AtomicUsize = AtomicUsize::new(0);
let $name = {
struct Fut(Box<i32>);
@@ -34,14 +31,14 @@
type Output = Out;
fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
- $poll.fetch_add(1);
+ $poll.fetch_add(1, Ordering::SeqCst);
Poll::Ready(Out(Box::new(0)))
}
}
impl Drop for Fut {
fn drop(&mut self) {
- $drop_f.fetch_add(1);
+ $drop_f.fetch_add(1, Ordering::SeqCst);
}
}
@@ -49,7 +46,7 @@
impl Drop for Out {
fn drop(&mut self) {
- $drop_o.fetch_add(1);
+ $drop_t.fetch_add(1, Ordering::SeqCst);
}
}
@@ -67,17 +64,15 @@
// When it gets dropped, `DROP` is incremented.
macro_rules! schedule {
($name:pat, $sched:ident, $drop:ident) => {
- lazy_static! {
- static ref $sched: AtomicCell<usize> = AtomicCell::new(0);
- static ref $drop: AtomicCell<usize> = AtomicCell::new(0);
- }
+ static $drop: AtomicUsize = AtomicUsize::new(0);
+ static $sched: AtomicUsize = AtomicUsize::new(0);
let $name = {
struct Guard(Box<i32>);
impl Drop for Guard {
fn drop(&mut self) {
- $drop.fetch_add(1);
+ $drop.fetch_add(1, Ordering::SeqCst);
}
}
@@ -85,7 +80,7 @@
move |task: Task| {
&guard;
task.schedule();
- $sched.fetch_add(1);
+ $sched.fetch_add(1, Ordering::SeqCst);
}
};
};
@@ -97,258 +92,258 @@
#[test]
fn drop_and_join() {
- future!(f, POLL, DROP_F, DROP_O);
+ future!(f, POLL, DROP_F, DROP_T);
schedule!(s, SCHEDULE, DROP_S);
let (task, handle) = async_task::spawn(f, s);
- assert_eq!(DROP_O.load(), 0);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 0);
drop(task);
- assert_eq!(DROP_O.load(), 0);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 0);
- assert!(block_on(handle).is_none());
- assert_eq!(POLL.load(), 0);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
- assert_eq!(DROP_O.load(), 0);
+ assert!(future::block_on(handle).is_none());
+ assert_eq!(POLL.load(Ordering::SeqCst), 0);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 0);
}
#[test]
fn run_and_join() {
- future!(f, POLL, DROP_F, DROP_O);
+ future!(f, POLL, DROP_F, DROP_T);
schedule!(s, SCHEDULE, DROP_S);
let (task, handle) = async_task::spawn(f, s);
- assert_eq!(DROP_O.load(), 0);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 0);
task.run();
- assert_eq!(DROP_O.load(), 0);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 0);
- assert!(block_on(handle).is_some());
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
- assert_eq!(DROP_O.load(), 1);
+ assert!(future::block_on(handle).is_some());
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 1);
}
#[test]
fn detach_and_run() {
- future!(f, POLL, DROP_F, DROP_O);
+ future!(f, POLL, DROP_F, DROP_T);
schedule!(s, SCHEDULE, DROP_S);
let (task, handle) = async_task::spawn(f, s);
- assert_eq!(DROP_O.load(), 0);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 0);
handle.detach();
- assert_eq!(DROP_O.load(), 0);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 0);
task.run();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
- assert_eq!(DROP_O.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 1);
}
#[test]
fn join_twice() {
- future!(f, POLL, DROP_F, DROP_O);
+ future!(f, POLL, DROP_F, DROP_T);
schedule!(s, SCHEDULE, DROP_S);
let (task, mut handle) = async_task::spawn(f, s);
- assert_eq!(DROP_O.load(), 0);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 0);
task.run();
- assert_eq!(DROP_O.load(), 0);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 0);
- assert!(block_on(&mut handle).is_some());
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(DROP_O.load(), 1);
+ assert!(future::block_on(&mut handle).is_some());
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 1);
- assert!(block_on(&mut handle).is_none());
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(DROP_O.load(), 1);
+ assert!(future::block_on(&mut handle).is_none());
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 1);
handle.detach();
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
}
#[test]
fn join_and_cancel() {
- future!(f, POLL, DROP_F, DROP_O);
+ future!(f, POLL, DROP_F, DROP_T);
schedule!(s, SCHEDULE, DROP_S);
let (task, handle) = async_task::spawn(f, s);
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
thread::sleep(ms(200));
drop(task);
thread::sleep(ms(400));
- assert_eq!(POLL.load(), 0);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_O.load(), 0);
- assert_eq!(DROP_S.load(), 1);
- });
+ assert_eq!(POLL.load(Ordering::SeqCst), 0);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ })
+ .add(|| {
+ assert!(future::block_on(handle).is_none());
+ assert_eq!(POLL.load(Ordering::SeqCst), 0);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
- assert!(block_on(handle).is_none());
- assert_eq!(POLL.load(), 0);
- assert_eq!(SCHEDULE.load(), 0);
-
- thread::sleep(ms(200));
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_O.load(), 0);
- assert_eq!(DROP_S.load(), 1);
- })
- .unwrap();
+ thread::sleep(ms(200));
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ })
+ .run();
}
#[test]
fn join_and_run() {
- future!(f, POLL, DROP_F, DROP_O);
+ future!(f, POLL, DROP_F, DROP_T);
schedule!(s, SCHEDULE, DROP_S);
let (task, handle) = async_task::spawn(f, s);
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
thread::sleep(ms(400));
task.run();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
thread::sleep(ms(200));
- assert_eq!(DROP_S.load(), 1);
- });
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ })
+ .add(|| {
+ assert!(future::block_on(handle).is_some());
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 1);
- assert!(block_on(handle).is_some());
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_O.load(), 1);
-
- thread::sleep(ms(200));
- assert_eq!(DROP_S.load(), 1);
- })
- .unwrap();
+ thread::sleep(ms(200));
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ })
+ .run();
}
#[test]
fn try_join_and_run_and_join() {
- future!(f, POLL, DROP_F, DROP_O);
+ future!(f, POLL, DROP_F, DROP_T);
schedule!(s, SCHEDULE, DROP_S);
let (task, mut handle) = async_task::spawn(f, s);
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
thread::sleep(ms(400));
task.run();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
thread::sleep(ms(200));
- assert_eq!(DROP_S.load(), 1);
- });
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ })
+ .add(|| {
+ future::block_on(future::or(&mut handle, future::ready(Default::default())));
+ assert_eq!(POLL.load(Ordering::SeqCst), 0);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 0);
- block_on(future::select(&mut handle, future::ready(())));
- assert_eq!(POLL.load(), 0);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(DROP_O.load(), 0);
+ assert!(future::block_on(handle).is_some());
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 1);
- assert!(block_on(handle).is_some());
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_O.load(), 1);
-
- thread::sleep(ms(200));
- assert_eq!(DROP_S.load(), 1);
- })
- .unwrap();
+ thread::sleep(ms(200));
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ })
+ .run();
}
#[test]
fn try_join_and_cancel_and_run() {
- future!(f, POLL, DROP_F, DROP_O);
+ future!(f, POLL, DROP_F, DROP_T);
schedule!(s, SCHEDULE, DROP_S);
let (task, mut handle) = async_task::spawn(f, s);
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
thread::sleep(ms(200));
task.run();
- assert_eq!(POLL.load(), 0);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
- });
+ assert_eq!(POLL.load(Ordering::SeqCst), 0);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ })
+ .add(|| {
+ future::block_on(future::or(&mut handle, future::ready(Default::default())));
+ assert_eq!(POLL.load(Ordering::SeqCst), 0);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 0);
- block_on(future::select(&mut handle, future::ready(())));
- assert_eq!(POLL.load(), 0);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(DROP_O.load(), 0);
-
- drop(handle);
- assert_eq!(POLL.load(), 0);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(DROP_O.load(), 0);
- })
- .unwrap();
+ drop(handle);
+ assert_eq!(POLL.load(Ordering::SeqCst), 0);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 0);
+ })
+ .run();
}
#[test]
fn try_join_and_run_and_cancel() {
- future!(f, POLL, DROP_F, DROP_O);
+ future!(f, POLL, DROP_F, DROP_T);
schedule!(s, SCHEDULE, DROP_S);
let (task, mut handle) = async_task::spawn(f, s);
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
thread::sleep(ms(200));
task.run();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
- });
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ })
+ .add(|| {
+ future::block_on(future::or(&mut handle, future::ready(Default::default())));
+ assert_eq!(POLL.load(Ordering::SeqCst), 0);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 0);
- block_on(future::select(&mut handle, future::ready(())));
- assert_eq!(POLL.load(), 0);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(DROP_O.load(), 0);
+ thread::sleep(ms(400));
- thread::sleep(ms(400));
-
- drop(handle);
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
- assert_eq!(DROP_O.load(), 1);
- })
- .unwrap();
+ drop(handle);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 1);
+ })
+ .run();
}
#[test]
@@ -372,16 +367,16 @@
for i in 0..10 {
let (task, handle) = async_task::spawn(Fut::new(i), drop);
task.run();
- assert_eq!(block_on(handle), Some(i));
+ assert_eq!(future::block_on(handle), Some(i));
}
for i in 0..10 {
let (task, handle) = async_task::spawn(Fut::new(vec![7; i]), drop);
task.run();
- assert_eq!(block_on(handle), Some(vec![7; i]));
+ assert_eq!(future::block_on(handle), Some(vec![7; i]));
}
let (task, handle) = async_task::spawn(Fut::new("foo".to_string()), drop);
task.run();
- assert_eq!(block_on(handle), Some("foo".to_string()));
+ assert_eq!(future::block_on(handle), Some("foo".to_string()));
}
diff --git a/tests/panic.rs b/tests/panic.rs
index 6641025..0b3ca6a 100644
--- a/tests/panic.rs
+++ b/tests/panic.rs
@@ -1,15 +1,14 @@
use std::future::Future;
use std::panic::catch_unwind;
use std::pin::Pin;
+use std::sync::atomic::{AtomicUsize, Ordering};
use std::task::{Context, Poll};
use std::thread;
use std::time::Duration;
use async_task::Task;
-use crossbeam::atomic::AtomicCell;
-use futures::executor::block_on;
-use futures::future;
-use lazy_static::lazy_static;
+use easy_parallel::Parallel;
+use futures_lite::future;
// Creates a future with event counters.
//
@@ -20,10 +19,8 @@
// When it gets dropped, `DROP` is incremented.
macro_rules! future {
($name:pat, $poll:ident, $drop:ident) => {
- lazy_static! {
- static ref $poll: AtomicCell<usize> = AtomicCell::new(0);
- static ref $drop: AtomicCell<usize> = AtomicCell::new(0);
- }
+ static $poll: AtomicUsize = AtomicUsize::new(0);
+ static $drop: AtomicUsize = AtomicUsize::new(0);
let $name = {
struct Fut(Box<i32>);
@@ -32,7 +29,7 @@
type Output = ();
fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
- $poll.fetch_add(1);
+ $poll.fetch_add(1, Ordering::SeqCst);
thread::sleep(ms(400));
panic!()
}
@@ -40,7 +37,7 @@
impl Drop for Fut {
fn drop(&mut self) {
- $drop.fetch_add(1);
+ $drop.fetch_add(1, Ordering::SeqCst);
}
}
@@ -58,24 +55,22 @@
// When it gets dropped, `DROP` is incremented.
macro_rules! schedule {
($name:pat, $sched:ident, $drop:ident) => {
- lazy_static! {
- static ref $sched: AtomicCell<usize> = AtomicCell::new(0);
- static ref $drop: AtomicCell<usize> = AtomicCell::new(0);
- }
+ static $drop: AtomicUsize = AtomicUsize::new(0);
+ static $sched: AtomicUsize = AtomicUsize::new(0);
let $name = {
struct Guard(Box<i32>);
impl Drop for Guard {
fn drop(&mut self) {
- $drop.fetch_add(1);
+ $drop.fetch_add(1, Ordering::SeqCst);
}
}
let guard = Guard(Box::new(0));
move |_task: Task| {
&guard;
- $sched.fetch_add(1);
+ $sched.fetch_add(1, Ordering::SeqCst);
}
};
};
@@ -91,24 +86,24 @@
schedule!(s, SCHEDULE, DROP_S);
let (task, handle) = async_task::spawn(f, s);
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
assert!(catch_unwind(|| task.run()).is_err());
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
- });
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ })
+ .add(|| {
+ thread::sleep(ms(200));
- thread::sleep(ms(200));
-
- drop(handle);
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- })
- .unwrap();
+ drop(handle);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ })
+ .run();
}
#[test]
@@ -118,16 +113,16 @@
let (task, handle) = async_task::spawn(f, s);
assert!(catch_unwind(|| task.run()).is_err());
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
- assert!(block_on(handle).is_none());
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert!(future::block_on(handle).is_none());
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
}
#[test]
@@ -136,23 +131,23 @@
schedule!(s, SCHEDULE, DROP_S);
let (task, mut handle) = async_task::spawn(f, s);
- block_on(future::select(&mut handle, future::ready(())));
- assert_eq!(POLL.load(), 0);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ future::block_on(future::or(&mut handle, future::ready(Default::default())));
+ assert_eq!(POLL.load(Ordering::SeqCst), 0);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert!(catch_unwind(|| task.run()).is_err());
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
- assert!(block_on(handle).is_none());
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert!(future::block_on(handle).is_none());
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
}
#[test]
@@ -161,28 +156,28 @@
schedule!(s, SCHEDULE, DROP_S);
let (task, handle) = async_task::spawn(f, s);
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
assert!(catch_unwind(|| task.run()).is_err());
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
thread::sleep(ms(200));
- assert_eq!(DROP_S.load(), 1);
- });
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ })
+ .add(|| {
+ thread::sleep(ms(200));
- thread::sleep(ms(200));
+ assert!(future::block_on(handle).is_none());
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
- assert!(block_on(handle).is_none());
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
-
- thread::sleep(ms(200));
- assert_eq!(DROP_S.load(), 1);
- })
- .unwrap();
+ thread::sleep(ms(200));
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ })
+ .run();
}
#[test]
@@ -191,25 +186,25 @@
schedule!(s, SCHEDULE, DROP_S);
let (task, mut handle) = async_task::spawn(f, s);
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
assert!(catch_unwind(|| task.run()).is_err());
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
- });
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ })
+ .add(|| {
+ thread::sleep(ms(200));
- thread::sleep(ms(200));
-
- block_on(future::select(&mut handle, future::ready(())));
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- drop(handle);
- })
- .unwrap();
+ future::block_on(future::or(&mut handle, future::ready(Default::default())));
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ drop(handle);
+ })
+ .run();
}
#[test]
@@ -218,22 +213,22 @@
schedule!(s, SCHEDULE, DROP_S);
let (task, handle) = async_task::spawn(f, s);
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
assert!(catch_unwind(|| task.run()).is_err());
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
- });
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ })
+ .add(|| {
+ thread::sleep(ms(200));
- thread::sleep(ms(200));
-
- handle.detach();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- })
- .unwrap();
+ handle.detach();
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ })
+ .run();
}
diff --git a/tests/ready.rs b/tests/ready.rs
index 12b3f06..bcf49c0 100644
--- a/tests/ready.rs
+++ b/tests/ready.rs
@@ -1,30 +1,27 @@
use std::future::Future;
use std::pin::Pin;
+use std::sync::atomic::{AtomicUsize, Ordering};
use std::task::{Context, Poll};
use std::thread;
use std::time::Duration;
use async_task::Task;
-use crossbeam::atomic::AtomicCell;
-use futures::executor::block_on;
-use futures::future;
-use lazy_static::lazy_static;
+use easy_parallel::Parallel;
+use futures_lite::future;
// Creates a future with event counters.
//
-// Usage: `future!(f, POLL, DROP_F, DROP_O)`
+// Usage: `future!(f, POLL, DROP_F, DROP_T)`
//
// The future `f` sleeps for 200 ms and outputs `Poll::Ready`.
// When it gets polled, `POLL` is incremented.
// When it gets dropped, `DROP_F` is incremented.
-// When the output gets dropped, `DROP_O` is incremented.
+// When the output gets dropped, `DROP_T` is incremented.
macro_rules! future {
- ($name:pat, $poll:ident, $drop_f:ident, $drop_o:ident) => {
- lazy_static! {
- static ref $poll: AtomicCell<usize> = AtomicCell::new(0);
- static ref $drop_f: AtomicCell<usize> = AtomicCell::new(0);
- static ref $drop_o: AtomicCell<usize> = AtomicCell::new(0);
- }
+ ($name:pat, $poll:ident, $drop_f:ident, $drop_t:ident) => {
+ static $poll: AtomicUsize = AtomicUsize::new(0);
+ static $drop_f: AtomicUsize = AtomicUsize::new(0);
+ static $drop_t: AtomicUsize = AtomicUsize::new(0);
let $name = {
struct Fut(Box<i32>);
@@ -33,7 +30,7 @@
type Output = Out;
fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
- $poll.fetch_add(1);
+ $poll.fetch_add(1, Ordering::SeqCst);
thread::sleep(ms(400));
Poll::Ready(Out(Box::new(0)))
}
@@ -41,7 +38,7 @@
impl Drop for Fut {
fn drop(&mut self) {
- $drop_f.fetch_add(1);
+ $drop_f.fetch_add(1, Ordering::SeqCst);
}
}
@@ -49,7 +46,7 @@
impl Drop for Out {
fn drop(&mut self) {
- $drop_o.fetch_add(1);
+ $drop_t.fetch_add(1, Ordering::SeqCst);
}
}
@@ -67,24 +64,22 @@
// When it gets dropped, `DROP` is incremented.
macro_rules! schedule {
($name:pat, $sched:ident, $drop:ident) => {
- lazy_static! {
- static ref $sched: AtomicCell<usize> = AtomicCell::new(0);
- static ref $drop: AtomicCell<usize> = AtomicCell::new(0);
- }
+ static $drop: AtomicUsize = AtomicUsize::new(0);
+ static $sched: AtomicUsize = AtomicUsize::new(0);
let $name = {
struct Guard(Box<i32>);
impl Drop for Guard {
fn drop(&mut self) {
- $drop.fetch_add(1);
+ $drop.fetch_add(1, Ordering::SeqCst);
}
}
let guard = Guard(Box::new(0));
move |_task: Task| {
&guard;
- $sched.fetch_add(1);
+ $sched.fetch_add(1, Ordering::SeqCst);
}
};
};
@@ -96,132 +91,132 @@
#[test]
fn cancel_during_run() {
- future!(f, POLL, DROP_F, DROP_O);
+ future!(f, POLL, DROP_F, DROP_T);
schedule!(s, SCHEDULE, DROP_S);
let (task, handle) = async_task::spawn(f, s);
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
task.run();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
- assert_eq!(DROP_O.load(), 1);
- });
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 1);
+ })
+ .add(|| {
+ thread::sleep(ms(200));
- thread::sleep(ms(200));
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 0);
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(DROP_O.load(), 0);
+ drop(handle);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 0);
- drop(handle);
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(DROP_O.load(), 0);
+ thread::sleep(ms(400));
- thread::sleep(ms(400));
-
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
- assert_eq!(DROP_O.load(), 1);
- })
- .unwrap();
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 1);
+ })
+ .run();
}
#[test]
fn join_during_run() {
- future!(f, POLL, DROP_F, DROP_O);
+ future!(f, POLL, DROP_F, DROP_T);
schedule!(s, SCHEDULE, DROP_S);
let (task, handle) = async_task::spawn(f, s);
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
task.run();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
thread::sleep(ms(200));
- assert_eq!(DROP_S.load(), 1);
- });
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ })
+ .add(|| {
+ thread::sleep(ms(200));
- thread::sleep(ms(200));
+ assert!(future::block_on(handle).is_some());
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 1);
- assert!(block_on(handle).is_some());
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_O.load(), 1);
+ thread::sleep(ms(200));
- thread::sleep(ms(200));
-
- assert_eq!(DROP_S.load(), 1);
- })
- .unwrap();
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ })
+ .run();
}
#[test]
fn try_join_during_run() {
- future!(f, POLL, DROP_F, DROP_O);
+ future!(f, POLL, DROP_F, DROP_T);
schedule!(s, SCHEDULE, DROP_S);
let (task, mut handle) = async_task::spawn(f, s);
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
task.run();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
- assert_eq!(DROP_O.load(), 1);
- });
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 1);
+ })
+ .add(|| {
+ thread::sleep(ms(200));
- thread::sleep(ms(200));
-
- block_on(future::select(&mut handle, future::ready(())));
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(DROP_O.load(), 0);
- drop(handle);
- })
- .unwrap();
+ future::block_on(future::or(&mut handle, future::ready(Default::default())));
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 0);
+ drop(handle);
+ })
+ .run();
}
#[test]
fn detach_during_run() {
- future!(f, POLL, DROP_F, DROP_O);
+ future!(f, POLL, DROP_F, DROP_T);
schedule!(s, SCHEDULE, DROP_S);
let (task, handle) = async_task::spawn(f, s);
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
task.run();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
- assert_eq!(DROP_O.load(), 1);
- });
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 1);
+ })
+ .add(|| {
+ thread::sleep(ms(200));
- thread::sleep(ms(200));
-
- handle.detach();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(DROP_O.load(), 0);
- })
- .unwrap();
+ handle.detach();
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_T.load(Ordering::SeqCst), 0);
+ })
+ .run();
}
diff --git a/tests/waker_panic.rs b/tests/waker_panic.rs
index 457e69b..3c6c4b3 100644
--- a/tests/waker_panic.rs
+++ b/tests/waker_panic.rs
@@ -2,16 +2,16 @@
use std::future::Future;
use std::panic::catch_unwind;
use std::pin::Pin;
-use std::task::Waker;
+use std::sync::atomic::{AtomicUsize, Ordering};
use std::task::{Context, Poll};
use std::thread;
use std::time::Duration;
use async_task::Task;
-use crossbeam::atomic::AtomicCell;
+use atomic_waker::AtomicWaker;
use crossbeam::channel;
-use futures::future::FutureExt;
-use lazy_static::lazy_static;
+use easy_parallel::Parallel;
+use futures_lite::future;
// Creates a future with event counters.
//
@@ -25,11 +25,9 @@
// This waker can be extracted using the `waker` function.
macro_rules! future {
($name:pat, $waker:pat, $poll:ident, $drop:ident) => {
- lazy_static! {
- static ref $poll: AtomicCell<usize> = AtomicCell::new(0);
- static ref $drop: AtomicCell<usize> = AtomicCell::new(0);
- static ref WAKER: AtomicCell<Option<Waker>> = AtomicCell::new(None);
- }
+ static $poll: AtomicUsize = AtomicUsize::new(0);
+ static $drop: AtomicUsize = AtomicUsize::new(0);
+ static WAKER: AtomicWaker = AtomicWaker::new();
let ($name, $waker) = {
struct Fut(Cell<bool>, Box<i32>);
@@ -38,8 +36,8 @@
type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- WAKER.store(Some(cx.waker().clone()));
- $poll.fetch_add(1);
+ WAKER.register(cx.waker());
+ $poll.fetch_add(1, Ordering::SeqCst);
thread::sleep(ms(400));
if self.0.get() {
@@ -53,13 +51,11 @@
impl Drop for Fut {
fn drop(&mut self) {
- $drop.fetch_add(1);
+ $drop.fetch_add(1, Ordering::SeqCst);
}
}
- (Fut(Cell::new(false), Box::new(0)), || {
- WAKER.swap(None).unwrap()
- })
+ (Fut(Cell::new(false), Box::new(0)), || WAKER.take().unwrap())
};
};
}
@@ -75,10 +71,8 @@
// Receiver `chan` extracts the task when it is scheduled.
macro_rules! schedule {
($name:pat, $chan:pat, $sched:ident, $drop:ident) => {
- lazy_static! {
- static ref $sched: AtomicCell<usize> = AtomicCell::new(0);
- static ref $drop: AtomicCell<usize> = AtomicCell::new(0);
- }
+ static $drop: AtomicUsize = AtomicUsize::new(0);
+ static $sched: AtomicUsize = AtomicUsize::new(0);
let ($name, $chan) = {
let (s, r) = channel::unbounded();
@@ -87,14 +81,14 @@
impl Drop for Guard {
fn drop(&mut self) {
- $drop.fetch_add(1);
+ $drop.fetch_add(1, Ordering::SeqCst);
}
}
let guard = Guard(Box::new(0));
let sched = move |task: Task| {
&guard;
- $sched.fetch_add(1);
+ $sched.fetch_add(1, Ordering::SeqCst);
s.send(task).unwrap();
};
@@ -107,6 +101,10 @@
Duration::from_millis(ms)
}
+fn try_await<T>(f: impl Future<Output = T>) -> Option<T> {
+ future::block_on(future::poll_once(f))
+}
+
#[test]
fn wake_during_run() {
future!(f, waker, POLL, DROP_F);
@@ -118,36 +116,36 @@
w.wake_by_ref();
let task = chan.recv().unwrap();
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
assert!(catch_unwind(|| task.run()).is_err());
drop(waker());
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
assert_eq!(chan.len(), 0);
- });
+ })
+ .add(|| {
+ thread::sleep(ms(200));
- thread::sleep(ms(200));
+ w.wake();
+ handle.detach();
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(chan.len(), 0);
- w.wake();
- handle.detach();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(chan.len(), 0);
+ thread::sleep(ms(400));
- thread::sleep(ms(400));
-
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
- assert_eq!(chan.len(), 0);
- })
- .unwrap();
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ assert_eq!(chan.len(), 0);
+ })
+ .run();
}
#[test]
@@ -161,35 +159,35 @@
w.wake();
let task = chan.recv().unwrap();
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
assert!(catch_unwind(|| task.run()).is_err());
drop(waker());
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
assert_eq!(chan.len(), 0);
- });
+ })
+ .add(|| {
+ thread::sleep(ms(200));
- thread::sleep(ms(200));
+ drop(handle);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(chan.len(), 0);
- drop(handle);
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(chan.len(), 0);
+ thread::sleep(ms(400));
- thread::sleep(ms(400));
-
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
- assert_eq!(chan.len(), 0);
- })
- .unwrap();
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ assert_eq!(chan.len(), 0);
+ })
+ .run();
}
#[test]
@@ -203,42 +201,42 @@
w.wake_by_ref();
let task = chan.recv().unwrap();
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
assert!(catch_unwind(|| task.run()).is_err());
drop(waker());
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
assert_eq!(chan.len(), 0);
- });
+ })
+ .add(|| {
+ thread::sleep(ms(200));
- thread::sleep(ms(200));
+ w.wake();
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(chan.len(), 0);
- w.wake();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(chan.len(), 0);
+ drop(handle);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(chan.len(), 0);
- drop(handle);
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(chan.len(), 0);
+ thread::sleep(ms(400));
- thread::sleep(ms(400));
-
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
- assert_eq!(chan.len(), 0);
- })
- .unwrap();
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ assert_eq!(chan.len(), 0);
+ })
+ .run();
}
#[test]
@@ -252,42 +250,42 @@
w.wake_by_ref();
let task = chan.recv().unwrap();
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
assert!(catch_unwind(|| task.run()).is_err());
drop(waker());
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
assert_eq!(chan.len(), 0);
- });
+ })
+ .add(|| {
+ thread::sleep(ms(200));
- thread::sleep(ms(200));
+ drop(handle);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(chan.len(), 0);
- drop(handle);
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(chan.len(), 0);
+ w.wake();
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(chan.len(), 0);
- w.wake();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(chan.len(), 0);
+ thread::sleep(ms(400));
- thread::sleep(ms(400));
-
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
- assert_eq!(chan.len(), 0);
- })
- .unwrap();
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ assert_eq!(chan.len(), 0);
+ })
+ .run();
}
#[test]
@@ -298,31 +296,31 @@
task.run();
waker().wake();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
let mut handle = handle;
- assert!((&mut handle).now_or_never().is_none());
+ assert!(try_await(&mut handle).is_none());
let task = chan.recv().unwrap();
assert!(catch_unwind(|| task.run()).is_err());
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
- assert!((&mut handle).now_or_never().is_some());
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
+ assert!(try_await(&mut handle).is_some());
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
drop(waker());
drop(handle);
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
}
diff --git a/tests/waker_pending.rs b/tests/waker_pending.rs
index 683e595..e0d5044 100644
--- a/tests/waker_pending.rs
+++ b/tests/waker_pending.rs
@@ -1,14 +1,14 @@
use std::future::Future;
use std::pin::Pin;
-use std::task::Waker;
+use std::sync::atomic::{AtomicUsize, Ordering};
use std::task::{Context, Poll};
use std::thread;
use std::time::Duration;
use async_task::Task;
-use crossbeam::atomic::AtomicCell;
+use atomic_waker::AtomicWaker;
use crossbeam::channel;
-use lazy_static::lazy_static;
+use easy_parallel::Parallel;
// Creates a future with event counters.
//
@@ -22,11 +22,9 @@
// This waker can be extracted using the `waker` function.
macro_rules! future {
($name:pat, $waker:pat, $poll:ident, $drop:ident) => {
- lazy_static! {
- static ref $poll: AtomicCell<usize> = AtomicCell::new(0);
- static ref $drop: AtomicCell<usize> = AtomicCell::new(0);
- static ref WAKER: AtomicCell<Option<Waker>> = AtomicCell::new(None);
- }
+ static $poll: AtomicUsize = AtomicUsize::new(0);
+ static $drop: AtomicUsize = AtomicUsize::new(0);
+ static WAKER: AtomicWaker = AtomicWaker::new();
let ($name, $waker) = {
struct Fut(Box<i32>);
@@ -35,8 +33,8 @@
type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- WAKER.store(Some(cx.waker().clone()));
- $poll.fetch_add(1);
+ WAKER.register(cx.waker());
+ $poll.fetch_add(1, Ordering::SeqCst);
thread::sleep(ms(400));
Poll::Pending
}
@@ -44,11 +42,11 @@
impl Drop for Fut {
fn drop(&mut self) {
- $drop.fetch_add(1);
+ $drop.fetch_add(1, Ordering::SeqCst);
}
}
- (Fut(Box::new(0)), || WAKER.swap(None).unwrap())
+ (Fut(Box::new(0)), || WAKER.take().unwrap())
};
};
}
@@ -64,10 +62,8 @@
// Receiver `chan` extracts the task when it is scheduled.
macro_rules! schedule {
($name:pat, $chan:pat, $sched:ident, $drop:ident) => {
- lazy_static! {
- static ref $sched: AtomicCell<usize> = AtomicCell::new(0);
- static ref $drop: AtomicCell<usize> = AtomicCell::new(0);
- }
+ static $drop: AtomicUsize = AtomicUsize::new(0);
+ static $sched: AtomicUsize = AtomicUsize::new(0);
let ($name, $chan) = {
let (s, r) = channel::unbounded();
@@ -76,14 +72,14 @@
impl Drop for Guard {
fn drop(&mut self) {
- $drop.fetch_add(1);
+ $drop.fetch_add(1, Ordering::SeqCst);
}
}
let guard = Guard(Box::new(0));
let sched = move |task: Task| {
&guard;
- $sched.fetch_add(1);
+ $sched.fetch_add(1, Ordering::SeqCst);
s.send(task).unwrap();
};
@@ -107,34 +103,34 @@
w.wake_by_ref();
let task = chan.recv().unwrap();
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
task.run();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 2);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 2);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert_eq!(chan.len(), 1);
- });
+ })
+ .add(|| {
+ thread::sleep(ms(200));
- thread::sleep(ms(200));
+ w.wake_by_ref();
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(chan.len(), 0);
- w.wake_by_ref();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(chan.len(), 0);
+ thread::sleep(ms(400));
- thread::sleep(ms(400));
-
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 2);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(chan.len(), 1);
- })
- .unwrap();
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 2);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(chan.len(), 1);
+ })
+ .run();
chan.recv().unwrap();
drop(waker());
@@ -151,35 +147,35 @@
w.wake();
let task = chan.recv().unwrap();
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
task.run();
drop(waker());
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
assert_eq!(chan.len(), 0);
- });
+ })
+ .add(|| {
+ thread::sleep(ms(200));
- thread::sleep(ms(200));
+ drop(handle);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(chan.len(), 0);
- drop(handle);
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(chan.len(), 0);
+ thread::sleep(ms(400));
- thread::sleep(ms(400));
-
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
- assert_eq!(chan.len(), 0);
- })
- .unwrap();
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ assert_eq!(chan.len(), 0);
+ })
+ .run();
}
#[test]
@@ -193,42 +189,42 @@
w.wake_by_ref();
let task = chan.recv().unwrap();
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
task.run();
drop(waker());
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
assert_eq!(chan.len(), 0);
- });
+ })
+ .add(|| {
+ thread::sleep(ms(200));
- thread::sleep(ms(200));
+ w.wake();
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(chan.len(), 0);
- w.wake();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(chan.len(), 0);
+ drop(handle);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(chan.len(), 0);
- drop(handle);
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(chan.len(), 0);
+ thread::sleep(ms(400));
- thread::sleep(ms(400));
-
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
- assert_eq!(chan.len(), 0);
- })
- .unwrap();
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ assert_eq!(chan.len(), 0);
+ })
+ .run();
}
#[test]
@@ -242,42 +238,42 @@
w.wake_by_ref();
let task = chan.recv().unwrap();
- crossbeam::scope(|scope| {
- scope.spawn(|_| {
+ Parallel::new()
+ .add(|| {
task.run();
drop(waker());
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
assert_eq!(chan.len(), 0);
- });
+ })
+ .add(|| {
+ thread::sleep(ms(200));
- thread::sleep(ms(200));
+ drop(handle);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(chan.len(), 0);
- drop(handle);
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(chan.len(), 0);
+ w.wake();
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
+ assert_eq!(chan.len(), 0);
- w.wake();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
- assert_eq!(chan.len(), 0);
+ thread::sleep(ms(400));
- thread::sleep(ms(400));
-
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
- assert_eq!(chan.len(), 0);
- })
- .unwrap();
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
+ assert_eq!(chan.len(), 0);
+ })
+ .run();
}
#[test]
@@ -290,24 +286,24 @@
let w = waker();
handle.detach();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert_eq!(chan.len(), 0);
drop(w);
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert_eq!(chan.len(), 1);
chan.recv().unwrap().run();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
assert_eq!(chan.len(), 0);
}
@@ -319,24 +315,24 @@
task.run();
drop(waker());
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert_eq!(chan.len(), 0);
drop(handle);
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert_eq!(chan.len(), 1);
chan.recv().unwrap().run();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
assert_eq!(chan.len(), 0);
}
@@ -348,23 +344,23 @@
task.run();
drop(waker());
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert_eq!(chan.len(), 0);
handle.detach();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert_eq!(chan.len(), 1);
chan.recv().unwrap().run();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
assert_eq!(chan.len(), 0);
}
diff --git a/tests/waker_ready.rs b/tests/waker_ready.rs
index b97425a..bb7e648 100644
--- a/tests/waker_ready.rs
+++ b/tests/waker_ready.rs
@@ -1,15 +1,14 @@
use std::cell::Cell;
use std::future::Future;
use std::pin::Pin;
-use std::task::Waker;
+use std::sync::atomic::{AtomicUsize, Ordering};
use std::task::{Context, Poll};
use std::thread;
use std::time::Duration;
use async_task::Task;
-use crossbeam::atomic::AtomicCell;
+use atomic_waker::AtomicWaker;
use crossbeam::channel;
-use lazy_static::lazy_static;
// Creates a future with event counters.
//
@@ -23,11 +22,9 @@
// This waker can be extracted using the `waker` function.
macro_rules! future {
($name:pat, $waker:pat, $poll:ident, $drop:ident) => {
- lazy_static! {
- static ref $poll: AtomicCell<usize> = AtomicCell::new(0);
- static ref $drop: AtomicCell<usize> = AtomicCell::new(0);
- static ref WAKER: AtomicCell<Option<Waker>> = AtomicCell::new(None);
- }
+ static $poll: AtomicUsize = AtomicUsize::new(0);
+ static $drop: AtomicUsize = AtomicUsize::new(0);
+ static WAKER: AtomicWaker = AtomicWaker::new();
let ($name, $waker) = {
struct Fut(Cell<bool>, Box<i32>);
@@ -36,8 +33,8 @@
type Output = Box<i32>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
- WAKER.store(Some(cx.waker().clone()));
- $poll.fetch_add(1);
+ WAKER.register(cx.waker());
+ $poll.fetch_add(1, Ordering::SeqCst);
thread::sleep(ms(200));
if self.0.get() {
@@ -51,13 +48,11 @@
impl Drop for Fut {
fn drop(&mut self) {
- $drop.fetch_add(1);
+ $drop.fetch_add(1, Ordering::SeqCst);
}
}
- (Fut(Cell::new(false), Box::new(0)), || {
- WAKER.swap(None).unwrap()
- })
+ (Fut(Cell::new(false), Box::new(0)), || WAKER.take().unwrap())
};
};
}
@@ -73,10 +68,8 @@
// Receiver `chan` extracts the task when it is scheduled.
macro_rules! schedule {
($name:pat, $chan:pat, $sched:ident, $drop:ident) => {
- lazy_static! {
- static ref $sched: AtomicCell<usize> = AtomicCell::new(0);
- static ref $drop: AtomicCell<usize> = AtomicCell::new(0);
- }
+ static $drop: AtomicUsize = AtomicUsize::new(0);
+ static $sched: AtomicUsize = AtomicUsize::new(0);
let ($name, $chan) = {
let (s, r) = channel::unbounded();
@@ -85,14 +78,14 @@
impl Drop for Guard {
fn drop(&mut self) {
- $drop.fetch_add(1);
+ $drop.fetch_add(1, Ordering::SeqCst);
}
}
let guard = Guard(Box::new(0));
let sched = move |task: Task| {
&guard;
- $sched.fetch_add(1);
+ $sched.fetch_add(1, Ordering::SeqCst);
s.send(task).unwrap();
};
@@ -115,32 +108,32 @@
assert!(chan.is_empty());
task.run();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert_eq!(chan.len(), 0);
waker().wake();
task = chan.recv().unwrap();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert_eq!(chan.len(), 0);
task.run();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert_eq!(chan.len(), 0);
waker().wake();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
assert_eq!(chan.len(), 0);
}
@@ -154,32 +147,32 @@
assert!(chan.is_empty());
task.run();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert_eq!(chan.len(), 0);
waker().wake_by_ref();
task = chan.recv().unwrap();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert_eq!(chan.len(), 0);
task.run();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert_eq!(chan.len(), 0);
waker().wake_by_ref();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
assert_eq!(chan.len(), 0);
}
@@ -191,10 +184,10 @@
handle.detach();
task.run();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert_eq!(chan.len(), 0);
let w2 = waker().clone();
@@ -204,22 +197,22 @@
task = chan.recv().unwrap();
task.run();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert_eq!(chan.len(), 0);
w3.wake();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert_eq!(chan.len(), 0);
drop(w2);
drop(waker());
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
}
#[test]
@@ -230,27 +223,27 @@
handle.detach();
task.run();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert_eq!(chan.len(), 0);
let w = waker();
w.wake_by_ref();
drop(chan.recv().unwrap());
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert_eq!(chan.len(), 0);
w.wake();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
assert_eq!(chan.len(), 0);
}
@@ -263,24 +256,24 @@
task.run();
let w = waker();
- assert_eq!(POLL.load(), 1);
- assert_eq!(SCHEDULE.load(), 0);
- assert_eq!(DROP_F.load(), 0);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 1);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 0);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert_eq!(chan.len(), 0);
w.wake();
chan.recv().unwrap().run();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 0);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 0);
assert_eq!(chan.len(), 0);
waker().wake();
- assert_eq!(POLL.load(), 2);
- assert_eq!(SCHEDULE.load(), 1);
- assert_eq!(DROP_F.load(), 1);
- assert_eq!(DROP_S.load(), 1);
+ assert_eq!(POLL.load(Ordering::SeqCst), 2);
+ assert_eq!(SCHEDULE.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_F.load(Ordering::SeqCst), 1);
+ assert_eq!(DROP_S.load(Ordering::SeqCst), 1);
assert_eq!(chan.len(), 0);
}