]> git.lizzy.rs Git - rust.git/blob - src/test/run-pass/futures-api.rs
Rollup merge of #53110 - Xanewok:save-analysis-remap-path, r=nrc
[rust.git] / src / test / run-pass / futures-api.rs
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.
4 //
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.
10
11 #![feature(arbitrary_self_types, futures_api, pin)]
12 #![allow(unused)]
13
14 use std::boxed::PinBox;
15 use std::future::Future;
16 use std::mem::PinMut;
17 use std::rc::Rc;
18 use std::sync::{
19     Arc,
20     atomic::{self, AtomicUsize},
21 };
22 use std::future::FutureObj;
23 use std::task::{
24     Context, Poll,
25     Wake, Waker, LocalWaker,
26     Spawn, SpawnObjError,
27     local_waker, local_waker_from_nonlocal,
28 };
29
30 struct Counter {
31     local_wakes: AtomicUsize,
32     nonlocal_wakes: AtomicUsize,
33 }
34
35 impl Wake for Counter {
36     fn wake(this: &Arc<Self>) {
37         this.nonlocal_wakes.fetch_add(1, atomic::Ordering::SeqCst);
38     }
39
40     unsafe fn wake_local(this: &Arc<Self>) {
41         this.local_wakes.fetch_add(1, atomic::Ordering::SeqCst);
42     }
43 }
44
45 struct NoopSpawner;
46
47 impl Spawn for NoopSpawner {
48     fn spawn_obj(&mut self, _: FutureObj<'static, ()>) -> Result<(), SpawnObjError> {
49         Ok(())
50     }
51 }
52
53 struct MyFuture;
54
55 impl Future for MyFuture {
56     type Output = ();
57     fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
58         // Ensure all the methods work appropriately
59         cx.waker().wake();
60         cx.waker().wake();
61         cx.local_waker().wake();
62         cx.spawner().spawn_obj(PinBox::new(MyFuture).into()).unwrap();
63         Poll::Ready(())
64     }
65 }
66
67 fn test_local_waker() {
68     let counter = Arc::new(Counter {
69         local_wakes: AtomicUsize::new(0),
70         nonlocal_wakes: AtomicUsize::new(0),
71     });
72     let waker = unsafe { local_waker(counter.clone()) };
73     let spawner = &mut NoopSpawner;
74     let cx = &mut Context::new(&waker, spawner);
75     assert_eq!(Poll::Ready(()), PinMut::new(&mut MyFuture).poll(cx));
76     assert_eq!(1, counter.local_wakes.load(atomic::Ordering::SeqCst));
77     assert_eq!(2, counter.nonlocal_wakes.load(atomic::Ordering::SeqCst));
78 }
79
80 fn test_local_as_nonlocal_waker() {
81     let counter = Arc::new(Counter {
82         local_wakes: AtomicUsize::new(0),
83         nonlocal_wakes: AtomicUsize::new(0),
84     });
85     let waker: LocalWaker = local_waker_from_nonlocal(counter.clone());
86     let spawner = &mut NoopSpawner;
87     let cx = &mut Context::new(&waker, spawner);
88     assert_eq!(Poll::Ready(()), PinMut::new(&mut MyFuture).poll(cx));
89     assert_eq!(0, counter.local_wakes.load(atomic::Ordering::SeqCst));
90     assert_eq!(3, counter.nonlocal_wakes.load(atomic::Ordering::SeqCst));
91 }
92
93 fn main() {
94     test_local_waker();
95     test_local_as_nonlocal_waker();
96 }