4 // aux-build:arc_wake.rs
6 #![feature(async_await)]
11 use std
::future
::Future
;
14 atomic
::{self, AtomicUsize}
,
16 use std
::task
::{Context, Poll}
;
17 use arc_wake
::ArcWake
;
23 impl ArcWake
for Counter
{
24 fn wake(self: Arc
<Self>) {
25 Self::wake_by_ref(&self)
27 fn wake_by_ref(arc_self
: &Arc
<Self>) {
28 arc_self
.wakes
.fetch_add(1, atomic
::Ordering
::SeqCst
);
32 struct WakeOnceThenComplete(bool
);
34 fn wake_and_yield_once() -> WakeOnceThenComplete { WakeOnceThenComplete(false) }
36 impl Future
for WakeOnceThenComplete
{
38 fn poll(mut self: Pin
<&mut Self>, cx
: &mut Context
<'_
>) -> Poll
<()> {
42 cx
.waker().wake_by_ref();
49 fn async_block(x
: u8) -> impl Future
<Output
= u8> {
51 wake_and_yield_once().await
;
56 fn async_block_with_borrow_named_lifetime
<'a
>(x
: &'a
u8) -> impl Future
<Output
= u8> + 'a
{
58 wake_and_yield_once().await
;
63 fn async_nonmove_block(x
: u8) -> impl Future
<Output
= u8> {
66 wake_and_yield_once().await
;
73 fn async_closure(x
: u8) -> impl Future
<Output
= u8> {
74 (async
move |x
: u8| -> u8 {
75 wake_and_yield_once().await
;
80 async
fn async_fn(x
: u8) -> u8 {
81 wake_and_yield_once().await
;
85 async
fn generic_async_fn
<T
>(x
: T
) -> T
{
86 wake_and_yield_once().await
;
90 async
fn async_fn_with_borrow(x
: &u8) -> u8 {
91 wake_and_yield_once().await
;
95 async
fn async_fn_with_borrow_named_lifetime
<'a
>(x
: &'a
u8) -> u8 {
96 wake_and_yield_once().await
;
100 fn async_fn_with_impl_future_named_lifetime
<'a
>(x
: &'a
u8) -> impl Future
<Output
= u8> + 'a
{
102 wake_and_yield_once().await
;
107 /* FIXME(cramertj) support when `existential type T<'a, 'b>:;` works
108 async fn async_fn_multiple_args(x: &u8, _y: &u8) -> u8 {
109 await!(wake_and_yield_once());
114 async
fn async_fn_multiple_args_named_lifetime
<'a
>(x
: &'a
u8, _y
: &'a
u8) -> u8 {
115 wake_and_yield_once().await
;
119 fn async_fn_with_internal_borrow(y
: u8) -> impl Future
<Output
= u8> {
121 async_fn_with_borrow_named_lifetime(&y
).await
125 async
unsafe fn unsafe_async_fn(x
: u8) -> u8 {
126 wake_and_yield_once().await
;
137 async
fn async_assoc_item(x
: u8) -> u8 {
139 unsafe_async_fn(x
).await
143 async
unsafe fn async_unsafe_assoc_item(x
: u8) -> u8 {
144 unsafe_async_fn(x
).await
148 fn test_future_yields_once_then_returns
<F
, Fut
>(f
: F
)
150 F
: FnOnce(u8) -> Fut
,
151 Fut
: Future
<Output
= u8>,
153 let mut fut
= Box
::pin(f(9));
154 let counter
= Arc
::new(Counter { wakes: AtomicUsize::new(0) }
);
155 let waker
= ArcWake
::into_waker(counter
.clone());
156 let mut cx
= Context
::from_waker(&waker
);
157 assert_eq
!(0, counter
.wakes
.load(atomic
::Ordering
::SeqCst
));
158 assert_eq
!(Poll
::Pending
, fut
.as_mut().poll(&mut cx
));
159 assert_eq
!(1, counter
.wakes
.load(atomic
::Ordering
::SeqCst
));
160 assert_eq
!(Poll
::Ready(9), fut
.as_mut().poll(&mut cx
));
165 ($
($fn_name
:expr
,)*) => { $
(
166 test_future_yields_once_then_returns($fn_name
);
170 macro_rules
! test_with_borrow
{
171 ($
($fn_name
:expr
,)*) => { $
(
172 test_future_yields_once_then_returns(|x
| {
186 async_fn_with_internal_borrow
,
187 Foo
::async_assoc_item
,
190 unsafe { unsafe_async_fn(x).await }
195 unsafe { Foo::async_unsafe_assoc_item(x).await }
200 async_block_with_borrow_named_lifetime
,
201 async_fn_with_borrow
,
202 async_fn_with_borrow_named_lifetime
,
203 async_fn_with_impl_future_named_lifetime
,
206 async_fn_multiple_args_named_lifetime(x
, x
).await