Add lifetime to FutureObj
This commit is contained in:
@@ -66,7 +66,8 @@ use core::marker::{Unpin, Unsize};
|
|||||||
use core::mem::{self, PinMut};
|
use core::mem::{self, PinMut};
|
||||||
use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
|
use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
|
||||||
use core::ptr::{self, NonNull, Unique};
|
use core::ptr::{self, NonNull, Unique};
|
||||||
use core::task::{Context, Poll, UnsafeFutureObj, FutureObj, LocalFutureObj};
|
use core::future::{FutureObj, LocalFutureObj, UnsafeFutureObj};
|
||||||
|
use core::task::{Context, Poll};
|
||||||
use core::convert::From;
|
use core::convert::From;
|
||||||
|
|
||||||
use raw_vec::RawVec;
|
use raw_vec::RawVec;
|
||||||
@@ -915,7 +916,7 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<PinBox<U>> for PinBox<T> {}
|
|||||||
impl<T: ?Sized> Unpin for PinBox<T> {}
|
impl<T: ?Sized> Unpin for PinBox<T> {}
|
||||||
|
|
||||||
#[unstable(feature = "futures_api", issue = "50547")]
|
#[unstable(feature = "futures_api", issue = "50547")]
|
||||||
impl<'a, F: ?Sized + Future + Unpin> Future for Box<F> {
|
impl<F: ?Sized + Future + Unpin> Future for Box<F> {
|
||||||
type Output = F::Output;
|
type Output = F::Output;
|
||||||
|
|
||||||
fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
|
fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||||
@@ -924,7 +925,7 @@ impl<'a, F: ?Sized + Future + Unpin> Future for Box<F> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "futures_api", issue = "50547")]
|
#[unstable(feature = "futures_api", issue = "50547")]
|
||||||
impl<'a, F: ?Sized + Future> Future for PinBox<F> {
|
impl<F: ?Sized + Future> Future for PinBox<F> {
|
||||||
type Output = F::Output;
|
type Output = F::Output;
|
||||||
|
|
||||||
fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
|
fn poll(mut self: PinMut<Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||||
@@ -933,7 +934,7 @@ impl<'a, F: ?Sized + Future> Future for PinBox<F> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "futures_api", issue = "50547")]
|
#[unstable(feature = "futures_api", issue = "50547")]
|
||||||
unsafe impl<T, F: Future<Output = T> + 'static> UnsafeFutureObj<T> for PinBox<F> {
|
unsafe impl<'a, T, F: Future<Output = T> + 'a> UnsafeFutureObj<'a, T> for PinBox<F> {
|
||||||
fn into_raw(self) -> *mut () {
|
fn into_raw(self) -> *mut () {
|
||||||
PinBox::into_raw(self) as *mut ()
|
PinBox::into_raw(self) as *mut ()
|
||||||
}
|
}
|
||||||
@@ -950,28 +951,28 @@ unsafe impl<T, F: Future<Output = T> + 'static> UnsafeFutureObj<T> for PinBox<F>
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "futures_api", issue = "50547")]
|
#[unstable(feature = "futures_api", issue = "50547")]
|
||||||
impl<F: Future<Output = ()> + Send + 'static> From<PinBox<F>> for FutureObj<()> {
|
impl<'a, F: Future<Output = ()> + Send + 'a> From<PinBox<F>> for FutureObj<'a, ()> {
|
||||||
fn from(boxed: PinBox<F>) -> Self {
|
fn from(boxed: PinBox<F>) -> Self {
|
||||||
FutureObj::new(boxed)
|
FutureObj::new(boxed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "futures_api", issue = "50547")]
|
#[unstable(feature = "futures_api", issue = "50547")]
|
||||||
impl<F: Future<Output = ()> + Send + 'static> From<Box<F>> for FutureObj<()> {
|
impl<'a, F: Future<Output = ()> + Send + 'a> From<Box<F>> for FutureObj<'a, ()> {
|
||||||
fn from(boxed: Box<F>) -> Self {
|
fn from(boxed: Box<F>) -> Self {
|
||||||
FutureObj::new(PinBox::from(boxed))
|
FutureObj::new(PinBox::from(boxed))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "futures_api", issue = "50547")]
|
#[unstable(feature = "futures_api", issue = "50547")]
|
||||||
impl<F: Future<Output = ()> + 'static> From<PinBox<F>> for LocalFutureObj<()> {
|
impl<'a, F: Future<Output = ()> + 'a> From<PinBox<F>> for LocalFutureObj<'a, ()> {
|
||||||
fn from(boxed: PinBox<F>) -> Self {
|
fn from(boxed: PinBox<F>) -> Self {
|
||||||
LocalFutureObj::new(boxed)
|
LocalFutureObj::new(boxed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "futures_api", issue = "50547")]
|
#[unstable(feature = "futures_api", issue = "50547")]
|
||||||
impl<F: Future<Output = ()> + 'static> From<Box<F>> for LocalFutureObj<()> {
|
impl<'a, F: Future<Output = ()> + 'a> From<Box<F>> for LocalFutureObj<'a, ()> {
|
||||||
fn from(boxed: Box<F>) -> Self {
|
fn from(boxed: Box<F>) -> Self {
|
||||||
LocalFutureObj::new(PinBox::from(boxed))
|
LocalFutureObj::new(PinBox::from(boxed))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,6 @@
|
|||||||
reason = "futures in libcore are unstable",
|
reason = "futures in libcore are unstable",
|
||||||
issue = "50547")]
|
issue = "50547")]
|
||||||
|
|
||||||
//! Asynchronous values.
|
|
||||||
|
|
||||||
use mem::PinMut;
|
use mem::PinMut;
|
||||||
use marker::Unpin;
|
use marker::Unpin;
|
||||||
use task::{self, Poll};
|
use task::{self, Poll};
|
||||||
@@ -21,22 +21,24 @@ use task::{Context, Poll};
|
|||||||
/// A custom trait object for polling futures, roughly akin to
|
/// A custom trait object for polling futures, roughly akin to
|
||||||
/// `Box<dyn Future<Output = T>>`.
|
/// `Box<dyn Future<Output = T>>`.
|
||||||
/// Contrary to `FutureObj`, `LocalFutureObj` does not have a `Send` bound.
|
/// Contrary to `FutureObj`, `LocalFutureObj` does not have a `Send` bound.
|
||||||
pub struct LocalFutureObj<T> {
|
pub struct LocalFutureObj<'a, T> {
|
||||||
ptr: *mut (),
|
ptr: *mut (),
|
||||||
poll_fn: unsafe fn(*mut (), &mut Context) -> Poll<T>,
|
poll_fn: unsafe fn(*mut (), &mut Context) -> Poll<T>,
|
||||||
drop_fn: unsafe fn(*mut ()),
|
drop_fn: unsafe fn(*mut ()),
|
||||||
_marker: PhantomData<T>,
|
_marker1: PhantomData<T>,
|
||||||
|
_marker2: PhantomData<&'a ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> LocalFutureObj<T> {
|
impl<'a, T> LocalFutureObj<'a, T> {
|
||||||
/// Create a `LocalFutureObj` from a custom trait object representation.
|
/// Create a `LocalFutureObj` from a custom trait object representation.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new<F: UnsafeFutureObj<T>>(f: F) -> LocalFutureObj<T> {
|
pub fn new<F: UnsafeFutureObj<'a, T> + 'a>(f: F) -> LocalFutureObj<'a, T> {
|
||||||
LocalFutureObj {
|
LocalFutureObj {
|
||||||
ptr: f.into_raw(),
|
ptr: f.into_raw(),
|
||||||
poll_fn: F::poll,
|
poll_fn: F::poll,
|
||||||
drop_fn: F::drop,
|
drop_fn: F::drop,
|
||||||
_marker: PhantomData,
|
_marker1: PhantomData,
|
||||||
|
_marker2: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,26 +47,26 @@ impl<T> LocalFutureObj<T> {
|
|||||||
/// instance from which this `LocalFutureObj` was created actually
|
/// instance from which this `LocalFutureObj` was created actually
|
||||||
/// implements `Send`.
|
/// implements `Send`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn as_future_obj(self) -> FutureObj<T> {
|
pub unsafe fn as_future_obj(self) -> FutureObj<'a, T> {
|
||||||
FutureObj(self)
|
FutureObj(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> fmt::Debug for LocalFutureObj<T> {
|
impl<'a, T> fmt::Debug for LocalFutureObj<'a, T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_struct("LocalFutureObj")
|
f.debug_struct("LocalFutureObj")
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> From<FutureObj<T>> for LocalFutureObj<T> {
|
impl<'a, T> From<FutureObj<'a, T>> for LocalFutureObj<'a, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(f: FutureObj<T>) -> LocalFutureObj<T> {
|
fn from(f: FutureObj<'a, T>) -> LocalFutureObj<'a, T> {
|
||||||
f.0
|
f.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Future for LocalFutureObj<T> {
|
impl<'a, T> Future for LocalFutureObj<'a, T> {
|
||||||
type Output = T;
|
type Output = T;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -75,7 +77,7 @@ impl<T> Future for LocalFutureObj<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Drop for LocalFutureObj<T> {
|
impl<'a, T> Drop for LocalFutureObj<'a, T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
(self.drop_fn)(self.ptr)
|
(self.drop_fn)(self.ptr)
|
||||||
@@ -85,26 +87,26 @@ impl<T> Drop for LocalFutureObj<T> {
|
|||||||
|
|
||||||
/// A custom trait object for polling futures, roughly akin to
|
/// A custom trait object for polling futures, roughly akin to
|
||||||
/// `Box<dyn Future<Output = T>> + Send`.
|
/// `Box<dyn Future<Output = T>> + Send`.
|
||||||
pub struct FutureObj<T>(LocalFutureObj<T>);
|
pub struct FutureObj<'a, T>(LocalFutureObj<'a, T>);
|
||||||
|
|
||||||
unsafe impl<T> Send for FutureObj<T> {}
|
unsafe impl<'a, T> Send for FutureObj<'a, T> {}
|
||||||
|
|
||||||
impl<T> FutureObj<T> {
|
impl<'a, T> FutureObj<'a, T> {
|
||||||
/// Create a `FutureObj` from a custom trait object representation.
|
/// Create a `FutureObj` from a custom trait object representation.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new<F: UnsafeFutureObj<T> + Send>(f: F) -> FutureObj<T> {
|
pub fn new<F: UnsafeFutureObj<'a, T> + Send>(f: F) -> FutureObj<'a, T> {
|
||||||
FutureObj(LocalFutureObj::new(f))
|
FutureObj(LocalFutureObj::new(f))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> fmt::Debug for FutureObj<T> {
|
impl<'a, T> fmt::Debug for FutureObj<'a, T> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_struct("FutureObj")
|
f.debug_struct("FutureObj")
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Future for FutureObj<T> {
|
impl<'a, T> Future for FutureObj<'a, T> {
|
||||||
type Output = T;
|
type Output = T;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -123,7 +125,7 @@ impl<T> Future for FutureObj<T> {
|
|||||||
/// The implementor must guarantee that it is safe to call `poll` repeatedly (in
|
/// The implementor must guarantee that it is safe to call `poll` repeatedly (in
|
||||||
/// a non-concurrent fashion) with the result of `into_raw` until `drop` is
|
/// a non-concurrent fashion) with the result of `into_raw` until `drop` is
|
||||||
/// called.
|
/// called.
|
||||||
pub unsafe trait UnsafeFutureObj<T>: 'static {
|
pub unsafe trait UnsafeFutureObj<'a, T>: 'a {
|
||||||
/// Convert a owned instance into a (conceptually owned) void pointer.
|
/// Convert a owned instance into a (conceptually owned) void pointer.
|
||||||
fn into_raw(self) -> *mut ();
|
fn into_raw(self) -> *mut ();
|
||||||
|
|
||||||
21
src/libcore/future/mod.rs
Normal file
21
src/libcore/future/mod.rs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
#![unstable(feature = "futures_api",
|
||||||
|
reason = "futures in libcore are unstable",
|
||||||
|
issue = "50547")]
|
||||||
|
|
||||||
|
//! Asynchronous values.
|
||||||
|
|
||||||
|
mod future;
|
||||||
|
pub use self::future::Future;
|
||||||
|
|
||||||
|
mod future_obj;
|
||||||
|
pub use self::future_obj::{FutureObj, LocalFutureObj, UnsafeFutureObj};
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
issue = "50547")]
|
issue = "50547")]
|
||||||
|
|
||||||
use fmt;
|
use fmt;
|
||||||
use super::{FutureObj, LocalFutureObj};
|
use future::{FutureObj, LocalFutureObj};
|
||||||
|
|
||||||
/// A task executor.
|
/// A task executor.
|
||||||
///
|
///
|
||||||
@@ -29,7 +29,7 @@ pub trait Executor {
|
|||||||
///
|
///
|
||||||
/// The executor may be unable to spawn tasks, either because it has
|
/// The executor may be unable to spawn tasks, either because it has
|
||||||
/// been shut down or is resource-constrained.
|
/// been shut down or is resource-constrained.
|
||||||
fn spawn_obj(&mut self, task: FutureObj<()>) -> Result<(), SpawnObjError>;
|
fn spawn_obj(&mut self, task: FutureObj<'static, ()>) -> Result<(), SpawnObjError>;
|
||||||
|
|
||||||
/// Determine whether the executor is able to spawn new tasks.
|
/// Determine whether the executor is able to spawn new tasks.
|
||||||
///
|
///
|
||||||
@@ -76,7 +76,7 @@ pub struct SpawnObjError {
|
|||||||
pub kind: SpawnErrorKind,
|
pub kind: SpawnErrorKind,
|
||||||
|
|
||||||
/// The task for which spawning was attempted
|
/// The task for which spawning was attempted
|
||||||
pub task: FutureObj<()>,
|
pub task: FutureObj<'static, ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The result of a failed spawn
|
/// The result of a failed spawn
|
||||||
@@ -86,5 +86,5 @@ pub struct SpawnLocalObjError {
|
|||||||
pub kind: SpawnErrorKind,
|
pub kind: SpawnErrorKind,
|
||||||
|
|
||||||
/// The task for which spawning was attempted
|
/// The task for which spawning was attempted
|
||||||
pub task: LocalFutureObj<()>,
|
pub task: LocalFutureObj<'static, ()>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,8 +25,5 @@ pub use self::executor::{
|
|||||||
mod poll;
|
mod poll;
|
||||||
pub use self::poll::Poll;
|
pub use self::poll::Poll;
|
||||||
|
|
||||||
mod future_obj;
|
|
||||||
pub use self::future_obj::{FutureObj, LocalFutureObj, UnsafeFutureObj};
|
|
||||||
|
|
||||||
mod wake;
|
mod wake;
|
||||||
pub use self::wake::{Waker, LocalWaker, UnsafeWake};
|
pub use self::wake::{Waker, LocalWaker, UnsafeWake};
|
||||||
|
|||||||
@@ -19,9 +19,10 @@ use std::sync::{
|
|||||||
Arc,
|
Arc,
|
||||||
atomic::{self, AtomicUsize},
|
atomic::{self, AtomicUsize},
|
||||||
};
|
};
|
||||||
|
use std::future::FutureObj;
|
||||||
use std::task::{
|
use std::task::{
|
||||||
Context, Poll, Wake,
|
Context, Poll, Wake,
|
||||||
Executor, FutureObj, SpawnObjError,
|
Executor, SpawnObjError,
|
||||||
local_waker_from_nonlocal,
|
local_waker_from_nonlocal,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@ impl Wake for Counter {
|
|||||||
|
|
||||||
struct NoopExecutor;
|
struct NoopExecutor;
|
||||||
impl Executor for NoopExecutor {
|
impl Executor for NoopExecutor {
|
||||||
fn spawn_obj(&mut self, _: FutureObj<T>) -> Result<(), SpawnObjError> {
|
fn spawn_obj(&mut self, _: FutureObj<'static, ()>) -> Result<(), SpawnObjError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,10 +19,11 @@ use std::sync::{
|
|||||||
Arc,
|
Arc,
|
||||||
atomic::{self, AtomicUsize},
|
atomic::{self, AtomicUsize},
|
||||||
};
|
};
|
||||||
|
use std::future::FutureObj;
|
||||||
use std::task::{
|
use std::task::{
|
||||||
Context, Poll,
|
Context, Poll,
|
||||||
Wake, Waker, LocalWaker,
|
Wake, Waker, LocalWaker,
|
||||||
Executor, FutureObj, SpawnObjError,
|
Executor, SpawnObjError,
|
||||||
local_waker, local_waker_from_nonlocal,
|
local_waker, local_waker_from_nonlocal,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -44,7 +45,7 @@ impl Wake for Counter {
|
|||||||
struct NoopExecutor;
|
struct NoopExecutor;
|
||||||
|
|
||||||
impl Executor for NoopExecutor {
|
impl Executor for NoopExecutor {
|
||||||
fn spawn_obj(&mut self, _: FutureObj<()>) -> Result<(), SpawnObjError> {
|
fn spawn_obj(&mut self, _: FutureObj<'static, ()>) -> Result<(), SpawnObjError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user