Add waker_fn (#18)

* Add waker_fn

* Add a waker_fn test

* Double sleep times

* More benches

* Prohibit recursive block_on calls

* Reformat code
diff --git a/tests/join.rs b/tests/join.rs
index e572062..8e17b34 100644
--- a/tests/join.rs
+++ b/tests/join.rs
@@ -223,12 +223,12 @@
 
     crossbeam::scope(|scope| {
         scope.spawn(|_| {
-            thread::sleep(ms(100));
+            thread::sleep(ms(200));
 
             task.cancel();
             drop(task);
 
-            thread::sleep(ms(200));
+            thread::sleep(ms(400));
             assert_eq!(POLL.load(), 0);
             assert_eq!(SCHEDULE.load(), 0);
             assert_eq!(DROP_F.load(), 1);
@@ -241,7 +241,7 @@
         assert_eq!(POLL.load(), 0);
         assert_eq!(SCHEDULE.load(), 0);
 
-        thread::sleep(ms(100));
+        thread::sleep(ms(200));
         assert_eq!(DROP_F.load(), 1);
         assert_eq!(DROP_O.load(), 0);
         assert_eq!(DROP_S.load(), 1);
@@ -258,14 +258,14 @@
 
     crossbeam::scope(|scope| {
         scope.spawn(|_| {
-            thread::sleep(ms(200));
+            thread::sleep(ms(400));
 
             task.run();
             assert_eq!(POLL.load(), 1);
             assert_eq!(SCHEDULE.load(), 0);
             assert_eq!(DROP_F.load(), 1);
 
-            thread::sleep(ms(100));
+            thread::sleep(ms(200));
             assert_eq!(DROP_S.load(), 1);
             assert_eq!(DROP_T.load(), 1);
         });
@@ -276,7 +276,7 @@
         assert_eq!(DROP_F.load(), 1);
         assert_eq!(DROP_O.load(), 1);
 
-        thread::sleep(ms(100));
+        thread::sleep(ms(200));
         assert_eq!(DROP_S.load(), 1);
         assert_eq!(DROP_T.load(), 1);
     })
@@ -291,14 +291,14 @@
 
     crossbeam::scope(|scope| {
         scope.spawn(|_| {
-            thread::sleep(ms(200));
+            thread::sleep(ms(400));
 
             task.run();
             assert_eq!(POLL.load(), 1);
             assert_eq!(SCHEDULE.load(), 0);
             assert_eq!(DROP_F.load(), 1);
 
-            thread::sleep(ms(100));
+            thread::sleep(ms(200));
             assert_eq!(DROP_S.load(), 1);
             assert_eq!(DROP_T.load(), 1);
         });
@@ -317,7 +317,7 @@
         assert_eq!(DROP_F.load(), 1);
         assert_eq!(DROP_O.load(), 1);
 
-        thread::sleep(ms(100));
+        thread::sleep(ms(200));
         assert_eq!(DROP_S.load(), 1);
         assert_eq!(DROP_T.load(), 1);
     })
@@ -332,7 +332,7 @@
 
     crossbeam::scope(|scope| {
         scope.spawn(|_| {
-            thread::sleep(ms(200));
+            thread::sleep(ms(400));
 
             task.run();
             assert_eq!(POLL.load(), 0);
diff --git a/tests/panic.rs b/tests/panic.rs
index 7b7d1b5..80a8f1b 100644
--- a/tests/panic.rs
+++ b/tests/panic.rs
@@ -33,7 +33,7 @@
 
                 fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
                     $poll.fetch_add(1);
-                    thread::sleep(ms(200));
+                    thread::sleep(ms(400));
                     panic!()
                 }
             }
@@ -128,7 +128,7 @@
             assert_eq!(DROP_T.load(), 1);
         });
 
-        thread::sleep(ms(100));
+        thread::sleep(ms(200));
 
         handle.cancel();
         assert_eq!(POLL.load(), 1);
@@ -209,19 +209,19 @@
             assert_eq!(SCHEDULE.load(), 0);
             assert_eq!(DROP_F.load(), 1);
 
-            thread::sleep(ms(100));
+            thread::sleep(ms(200));
             assert_eq!(DROP_S.load(), 1);
             assert_eq!(DROP_T.load(), 1);
         });
 
-        thread::sleep(ms(100));
+        thread::sleep(ms(200));
 
         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(100));
+        thread::sleep(ms(200));
         assert_eq!(DROP_S.load(), 1);
         assert_eq!(DROP_T.load(), 1);
     })
@@ -244,7 +244,7 @@
             assert_eq!(DROP_T.load(), 1);
         });
 
-        thread::sleep(ms(100));
+        thread::sleep(ms(200));
 
         block_on(future::select(&mut handle, future::ready(())));
         assert_eq!(POLL.load(), 1);
@@ -273,7 +273,7 @@
             assert_eq!(DROP_T.load(), 1);
         });
 
-        thread::sleep(ms(100));
+        thread::sleep(ms(200));
 
         drop(handle);
         assert_eq!(POLL.load(), 1);
diff --git a/tests/ready.rs b/tests/ready.rs
index 05b266b..a966760 100644
--- a/tests/ready.rs
+++ b/tests/ready.rs
@@ -34,7 +34,7 @@
 
                 fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
                     $poll.fetch_add(1);
-                    thread::sleep(ms(200));
+                    thread::sleep(ms(400));
                     Poll::Ready(Out(Box::new(0)))
                 }
             }
@@ -138,7 +138,7 @@
             assert_eq!(DROP_O.load(), 1);
         });
 
-        thread::sleep(ms(100));
+        thread::sleep(ms(200));
 
         handle.cancel();
         assert_eq!(POLL.load(), 1);
@@ -148,7 +148,7 @@
         assert_eq!(DROP_T.load(), 0);
         assert_eq!(DROP_O.load(), 0);
 
-        thread::sleep(ms(200));
+        thread::sleep(ms(400));
 
         assert_eq!(POLL.load(), 1);
         assert_eq!(SCHEDULE.load(), 0);
@@ -181,12 +181,12 @@
             assert_eq!(SCHEDULE.load(), 0);
             assert_eq!(DROP_F.load(), 1);
 
-            thread::sleep(ms(100));
+            thread::sleep(ms(200));
             assert_eq!(DROP_S.load(), 1);
             assert_eq!(DROP_T.load(), 1);
         });
 
-        thread::sleep(ms(100));
+        thread::sleep(ms(200));
 
         assert!(block_on(handle).is_some());
         assert_eq!(POLL.load(), 1);
@@ -194,7 +194,7 @@
         assert_eq!(DROP_F.load(), 1);
         assert_eq!(DROP_O.load(), 1);
 
-        thread::sleep(ms(100));
+        thread::sleep(ms(200));
         assert_eq!(DROP_S.load(), 1);
         assert_eq!(DROP_T.load(), 1);
     })
@@ -218,7 +218,7 @@
             assert_eq!(DROP_O.load(), 1);
         });
 
-        thread::sleep(ms(100));
+        thread::sleep(ms(200));
 
         block_on(future::select(&mut handle, future::ready(())));
         assert_eq!(POLL.load(), 1);
@@ -249,7 +249,7 @@
             assert_eq!(DROP_O.load(), 1);
         });
 
-        thread::sleep(ms(100));
+        thread::sleep(ms(200));
 
         drop(handle);
         assert_eq!(POLL.load(), 1);
diff --git a/tests/waker_fn.rs b/tests/waker_fn.rs
new file mode 100644
index 0000000..fdad34c
--- /dev/null
+++ b/tests/waker_fn.rs
@@ -0,0 +1,29 @@
+use std::sync::atomic::{AtomicUsize, Ordering};
+use std::sync::Arc;
+
+#[test]
+fn wake() {
+    let a = Arc::new(AtomicUsize::new(0));
+    let w = async_task::waker_fn({
+        let a = a.clone();
+        move || {
+            a.fetch_add(1, Ordering::SeqCst);
+        }
+    });
+
+    assert_eq!(a.load(Ordering::SeqCst), 0);
+    w.wake_by_ref();
+    assert_eq!(a.load(Ordering::SeqCst), 1);
+
+    let w2 = w.clone();
+    assert_eq!(a.load(Ordering::SeqCst), 1);
+    w2.wake_by_ref();
+    assert_eq!(a.load(Ordering::SeqCst), 2);
+    drop(w2);
+    assert_eq!(a.load(Ordering::SeqCst), 2);
+
+    let w3 = w.clone();
+    assert_eq!(a.load(Ordering::SeqCst), 2);
+    w3.wake();
+    assert_eq!(a.load(Ordering::SeqCst), 3);
+}
diff --git a/tests/waker_panic.rs b/tests/waker_panic.rs
index bacdef6..eb77912 100644
--- a/tests/waker_panic.rs
+++ b/tests/waker_panic.rs
@@ -39,7 +39,7 @@
                 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
                     WAKER.store(Some(cx.waker().clone()));
                     $poll.fetch_add(1);
-                    thread::sleep(ms(200));
+                    thread::sleep(ms(400));
 
                     if self.0.get() {
                         panic!()
@@ -156,7 +156,7 @@
             assert_eq!(chan.len(), 0);
         });
 
-        thread::sleep(ms(100));
+        thread::sleep(ms(200));
 
         w.wake();
         drop(handle);
@@ -167,7 +167,7 @@
         assert_eq!(DROP_T.load(), 0);
         assert_eq!(chan.len(), 0);
 
-        thread::sleep(ms(200));
+        thread::sleep(ms(400));
 
         assert_eq!(POLL.load(), 2);
         assert_eq!(SCHEDULE.load(), 1);
@@ -202,7 +202,7 @@
             assert_eq!(chan.len(), 0);
         });
 
-        thread::sleep(ms(100));
+        thread::sleep(ms(200));
 
         handle.cancel();
         assert_eq!(POLL.load(), 2);
@@ -220,7 +220,7 @@
         assert_eq!(DROP_T.load(), 0);
         assert_eq!(chan.len(), 0);
 
-        thread::sleep(ms(200));
+        thread::sleep(ms(400));
 
         assert_eq!(POLL.load(), 2);
         assert_eq!(SCHEDULE.load(), 1);
@@ -255,7 +255,7 @@
             assert_eq!(chan.len(), 0);
         });
 
-        thread::sleep(ms(100));
+        thread::sleep(ms(200));
 
         w.wake();
         assert_eq!(POLL.load(), 2);
@@ -281,7 +281,7 @@
         assert_eq!(DROP_T.load(), 0);
         assert_eq!(chan.len(), 0);
 
-        thread::sleep(ms(200));
+        thread::sleep(ms(400));
 
         assert_eq!(POLL.load(), 2);
         assert_eq!(SCHEDULE.load(), 1);
@@ -316,7 +316,7 @@
             assert_eq!(chan.len(), 0);
         });
 
-        thread::sleep(ms(100));
+        thread::sleep(ms(200));
 
         handle.cancel();
         assert_eq!(POLL.load(), 2);
@@ -342,7 +342,7 @@
         assert_eq!(DROP_T.load(), 0);
         assert_eq!(chan.len(), 0);
 
-        thread::sleep(ms(200));
+        thread::sleep(ms(400));
 
         assert_eq!(POLL.load(), 2);
         assert_eq!(SCHEDULE.load(), 1);
diff --git a/tests/waker_pending.rs b/tests/waker_pending.rs
index d2c939b..1374c4a 100644
--- a/tests/waker_pending.rs
+++ b/tests/waker_pending.rs
@@ -37,7 +37,7 @@
                 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
                     WAKER.store(Some(cx.waker().clone()));
                     $poll.fetch_add(1);
-                    thread::sleep(ms(200));
+                    thread::sleep(ms(400));
                     Poll::Pending
                 }
             }
@@ -145,7 +145,7 @@
             assert_eq!(chan.len(), 1);
         });
 
-        thread::sleep(ms(100));
+        thread::sleep(ms(200));
 
         w.wake_by_ref();
         assert_eq!(POLL.load(), 2);
@@ -155,7 +155,7 @@
         assert_eq!(DROP_T.load(), 0);
         assert_eq!(chan.len(), 0);
 
-        thread::sleep(ms(200));
+        thread::sleep(ms(400));
 
         assert_eq!(POLL.load(), 2);
         assert_eq!(SCHEDULE.load(), 2);
@@ -193,7 +193,7 @@
             assert_eq!(chan.len(), 0);
         });
 
-        thread::sleep(ms(100));
+        thread::sleep(ms(200));
 
         handle.cancel();
         assert_eq!(POLL.load(), 2);
@@ -211,7 +211,7 @@
         assert_eq!(DROP_T.load(), 0);
         assert_eq!(chan.len(), 0);
 
-        thread::sleep(ms(200));
+        thread::sleep(ms(400));
 
         assert_eq!(POLL.load(), 2);
         assert_eq!(SCHEDULE.load(), 1);
@@ -246,7 +246,7 @@
             assert_eq!(chan.len(), 0);
         });
 
-        thread::sleep(ms(100));
+        thread::sleep(ms(200));
 
         w.wake();
         assert_eq!(POLL.load(), 2);
@@ -272,7 +272,7 @@
         assert_eq!(DROP_T.load(), 0);
         assert_eq!(chan.len(), 0);
 
-        thread::sleep(ms(200));
+        thread::sleep(ms(400));
 
         assert_eq!(POLL.load(), 2);
         assert_eq!(SCHEDULE.load(), 1);
@@ -307,7 +307,7 @@
             assert_eq!(chan.len(), 0);
         });
 
-        thread::sleep(ms(100));
+        thread::sleep(ms(200));
 
         handle.cancel();
         assert_eq!(POLL.load(), 2);
@@ -333,7 +333,7 @@
         assert_eq!(DROP_T.load(), 0);
         assert_eq!(chan.len(), 0);
 
-        thread::sleep(ms(200));
+        thread::sleep(ms(400));
 
         assert_eq!(POLL.load(), 2);
         assert_eq!(SCHEDULE.load(), 1);