1 // Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 #![feature(arbitrary_self_types, futures_api, pin)]
14 use std::future::Future;
19 atomic::{self, AtomicUsize},
21 use std::future::FutureObj;
24 Wake, Waker, LocalWaker,
26 local_waker, local_waker_from_nonlocal,
30 local_wakes: AtomicUsize,
31 nonlocal_wakes: AtomicUsize,
34 impl Wake for Counter {
35 fn wake(this: &Arc<Self>) {
36 this.nonlocal_wakes.fetch_add(1, atomic::Ordering::SeqCst);
39 unsafe fn wake_local(this: &Arc<Self>) {
40 this.local_wakes.fetch_add(1, atomic::Ordering::SeqCst);
46 impl Spawn for NoopSpawner {
47 fn spawn_obj(&mut self, _: FutureObj<'static, ()>) -> Result<(), SpawnObjError> {
54 impl Future for MyFuture {
56 fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
57 // Ensure all the methods work appropriately
60 cx.local_waker().wake();
61 cx.spawner().spawn_obj(Box::pinned(MyFuture).into()).unwrap();
66 fn test_local_waker() {
67 let counter = Arc::new(Counter {
68 local_wakes: AtomicUsize::new(0),
69 nonlocal_wakes: AtomicUsize::new(0),
71 let waker = unsafe { local_waker(counter.clone()) };
72 let spawner = &mut NoopSpawner;
73 let cx = &mut Context::new(&waker, spawner);
74 assert_eq!(Poll::Ready(()), Pin::new(&mut MyFuture).poll(cx));
75 assert_eq!(1, counter.local_wakes.load(atomic::Ordering::SeqCst));
76 assert_eq!(2, counter.nonlocal_wakes.load(atomic::Ordering::SeqCst));
79 fn test_local_as_nonlocal_waker() {
80 let counter = Arc::new(Counter {
81 local_wakes: AtomicUsize::new(0),
82 nonlocal_wakes: AtomicUsize::new(0),
84 let waker: LocalWaker = local_waker_from_nonlocal(counter.clone());
85 let spawner = &mut NoopSpawner;
86 let cx = &mut Context::new(&waker, spawner);
87 assert_eq!(Poll::Ready(()), Pin::new(&mut MyFuture).poll(cx));
88 assert_eq!(0, counter.local_wakes.load(atomic::Ordering::SeqCst));
89 assert_eq!(3, counter.nonlocal_wakes.load(atomic::Ordering::SeqCst));
94 test_local_as_nonlocal_waker();