about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-06-06 19:42:19 +0000
committerbors <bors@rust-lang.org>2018-06-06 19:42:19 +0000
commit19d0b539aa295468a3fde57a02413244f03ab6f6 (patch)
tree040ec289e4fb6f623fc645eca86a3bc749cfc6a7 /src/test
parentcb8ab33ed29544973da866bdc3eff509b3c3e789 (diff)
parenta6055c885917093faf37bcb834350df7b6ddca82 (diff)
downloadrust-19d0b539aa295468a3fde57a02413244f03ab6f6.tar.gz
rust-19d0b539aa295468a3fde57a02413244f03ab6f6.zip
Auto merge of #51263 - cramertj:futures-in-core, r=aturon
Add Future and task system to the standard library

This adds preliminary versions of the `std::future` and `std::task` modules in order to unblock development of async/await (https://github.com/rust-lang/rust/issues/50547). These shouldn't be considered as final forms of these libraries-- design questions about the libraries should be left on https://github.com/rust-lang/rfcs/pull/2418. Once that RFC (or a successor) is merged, these APIs will be adjusted as necessary.

r? @aturon
Diffstat (limited to 'src/test')
-rw-r--r--src/test/run-pass/futures-api.rs95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/test/run-pass/futures-api.rs b/src/test/run-pass/futures-api.rs
new file mode 100644
index 00000000000..3b5a1725b66
--- /dev/null
+++ b/src/test/run-pass/futures-api.rs
@@ -0,0 +1,95 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(arbitrary_self_types, futures_api, pin)]
+#![allow(unused)]
+
+use std::boxed::PinBox;
+use std::future::Future;
+use std::mem::PinMut;
+use std::rc::Rc;
+use std::sync::{
+    Arc,
+    atomic::{self, AtomicUsize},
+};
+use std::task::{
+    Context, Poll,
+    Wake, Waker, LocalWaker,
+    Executor, TaskObj, SpawnObjError,
+    local_waker, local_waker_from_nonlocal,
+};
+
+struct Counter {
+    local_wakes: AtomicUsize,
+    nonlocal_wakes: AtomicUsize,
+}
+
+impl Wake for Counter {
+    fn wake(this: &Arc<Self>) {
+        this.nonlocal_wakes.fetch_add(1, atomic::Ordering::SeqCst);
+    }
+
+    unsafe fn wake_local(this: &Arc<Self>) {
+        this.local_wakes.fetch_add(1, atomic::Ordering::SeqCst);
+    }
+}
+
+struct NoopExecutor;
+
+impl Executor for NoopExecutor {
+    fn spawn_obj(&mut self, _: TaskObj) -> Result<(), SpawnObjError> {
+        Ok(())
+    }
+}
+
+struct MyFuture;
+
+impl Future for MyFuture {
+    type Output = ();
+    fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
+        // Ensure all the methods work appropriately
+        cx.waker().wake();
+        cx.waker().wake();
+        cx.local_waker().wake();
+        cx.executor().spawn_obj(PinBox::new(MyFuture).into()).unwrap();
+        Poll::Ready(())
+    }
+}
+
+fn test_local_waker() {
+    let counter = Arc::new(Counter {
+        local_wakes: AtomicUsize::new(0),
+        nonlocal_wakes: AtomicUsize::new(0),
+    });
+    let waker = unsafe { local_waker(counter.clone()) };
+    let executor = &mut NoopExecutor;
+    let cx = &mut Context::new(&waker, executor);
+    assert_eq!(Poll::Ready(()), PinMut::new(&mut MyFuture).poll(cx));
+    assert_eq!(1, counter.local_wakes.load(atomic::Ordering::SeqCst));
+    assert_eq!(2, counter.nonlocal_wakes.load(atomic::Ordering::SeqCst));
+}
+
+fn test_local_as_nonlocal_waker() {
+    let counter = Arc::new(Counter {
+        local_wakes: AtomicUsize::new(0),
+        nonlocal_wakes: AtomicUsize::new(0),
+    });
+    let waker: LocalWaker = local_waker_from_nonlocal(counter.clone());
+    let executor = &mut NoopExecutor;
+    let cx = &mut Context::new(&waker, executor);
+    assert_eq!(Poll::Ready(()), PinMut::new(&mut MyFuture).poll(cx));
+    assert_eq!(0, counter.local_wakes.load(atomic::Ordering::SeqCst));
+    assert_eq!(3, counter.nonlocal_wakes.load(atomic::Ordering::SeqCst));
+}
+
+fn main() {
+    test_local_waker();
+    test_local_as_nonlocal_waker();
+}