Skip to content

Commit 3d43f82

Browse files
Make custom trait object for Future generic
1 parent a96c88e commit 3d43f82

File tree

6 files changed

+77
-72
lines changed

6 files changed

+77
-72
lines changed

src/liballoc/boxed.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ use core::marker::{Unpin, Unsize};
6666
use core::mem::{self, PinMut};
6767
use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
6868
use core::ptr::{self, NonNull, Unique};
69-
use core::task::{Context, Poll, UnsafeTask, TaskObj, LocalTaskObj};
69+
use core::task::{Context, Poll, UnsafeFutureObj, FutureObj, LocalFutureObj};
7070
use core::convert::From;
7171

7272
use raw_vec::RawVec;
@@ -933,12 +933,12 @@ impl<'a, F: ?Sized + Future> Future for PinBox<F> {
933933
}
934934

935935
#[unstable(feature = "futures_api", issue = "50547")]
936-
unsafe impl<F: Future<Output = ()> + 'static> UnsafeTask for PinBox<F> {
936+
unsafe impl<T, F: Future<Output = T> + 'static> UnsafeFutureObj<T> for PinBox<F> {
937937
fn into_raw(self) -> *mut () {
938938
PinBox::into_raw(self) as *mut ()
939939
}
940940

941-
unsafe fn poll(task: *mut (), cx: &mut Context) -> Poll<()> {
941+
unsafe fn poll(task: *mut (), cx: &mut Context) -> Poll<T> {
942942
let ptr = task as *mut F;
943943
let pin: PinMut<F> = PinMut::new_unchecked(&mut *ptr);
944944
pin.poll(cx)
@@ -950,29 +950,29 @@ unsafe impl<F: Future<Output = ()> + 'static> UnsafeTask for PinBox<F> {
950950
}
951951

952952
#[unstable(feature = "futures_api", issue = "50547")]
953-
impl<F: Future<Output = ()> + Send + 'static> From<PinBox<F>> for TaskObj {
954-
fn from(boxed: PinBox<F>) -> Self {
955-
TaskObj::new(boxed)
953+
impl<T, F: Future<Output = T> + Send + 'static> Into<FutureObj<T>> for PinBox<F> {
954+
fn into(self) -> FutureObj<T> {
955+
FutureObj::new(self)
956956
}
957957
}
958958

959959
#[unstable(feature = "futures_api", issue = "50547")]
960-
impl<F: Future<Output = ()> + Send + 'static> From<Box<F>> for TaskObj {
961-
fn from(boxed: Box<F>) -> Self {
962-
TaskObj::new(PinBox::from(boxed))
960+
impl<T, F: Future<Output = T> + Send + 'static> Into<FutureObj<T>> for Box<F> {
961+
fn into(self) -> FutureObj<T> {
962+
FutureObj::new(PinBox::from(self))
963963
}
964964
}
965965

966966
#[unstable(feature = "futures_api", issue = "50547")]
967-
impl<F: Future<Output = ()> + 'static> From<PinBox<F>> for LocalTaskObj {
968-
fn from(boxed: PinBox<F>) -> Self {
969-
LocalTaskObj::new(boxed)
967+
impl<T, F: Future<Output = T> + 'static> Into<LocalFutureObj<T>> for PinBox<F> {
968+
fn into(self) -> LocalFutureObj<T> {
969+
LocalFutureObj::new(self)
970970
}
971971
}
972972

973973
#[unstable(feature = "futures_api", issue = "50547")]
974-
impl<F: Future<Output = ()> + 'static> From<Box<F>> for LocalTaskObj {
975-
fn from(boxed: Box<F>) -> Self {
976-
LocalTaskObj::new(PinBox::from(boxed))
974+
impl<T, F: Future<Output = T> + 'static> Into<LocalFutureObj<T>> for Box<F> {
975+
fn into(self) -> LocalFutureObj<T> {
976+
LocalFutureObj::new(PinBox::from(self))
977977
}
978978
}

src/libcore/task/executor.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
issue = "50547")]
1414

1515
use fmt;
16-
use super::{TaskObj, LocalTaskObj};
16+
use super::{FutureObj, LocalFutureObj};
1717

1818
/// A task executor.
1919
///
@@ -29,7 +29,7 @@ pub trait Executor {
2929
///
3030
/// The executor may be unable to spawn tasks, either because it has
3131
/// been shut down or is resource-constrained.
32-
fn spawn_obj(&mut self, task: TaskObj) -> Result<(), SpawnObjError>;
32+
fn spawn_obj(&mut self, task: FutureObj<()>) -> Result<(), SpawnObjError>;
3333

3434
/// Determine whether the executor is able to spawn new tasks.
3535
///
@@ -76,7 +76,7 @@ pub struct SpawnObjError {
7676
pub kind: SpawnErrorKind,
7777

7878
/// The task for which spawning was attempted
79-
pub task: TaskObj,
79+
pub task: FutureObj<()>,
8080
}
8181

8282
/// The result of a failed spawn
@@ -86,5 +86,5 @@ pub struct SpawnLocalObjError {
8686
pub kind: SpawnErrorKind,
8787

8888
/// The task for which spawning was attempted
89-
pub task: LocalTaskObj,
89+
pub task: LocalFutureObj<()>,
9090
}

src/libcore/task/task.rs renamed to src/libcore/task/future_obj.rs

Lines changed: 52 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -14,102 +14,107 @@
1414

1515
use fmt;
1616
use future::Future;
17+
use marker::PhantomData;
1718
use mem::PinMut;
18-
use super::{Context, Poll};
19+
use task::{Context, Poll};
1920

20-
/// A custom trait object for polling tasks, roughly akin to
21-
/// `Box<Future<Output = ()>>`.
22-
/// Contrary to `TaskObj`, `LocalTaskObj` does not have a `Send` bound.
23-
pub struct LocalTaskObj {
21+
/// A custom trait object for polling futures, roughly akin to
22+
/// `Box<dyn Future<Output = T>>`.
23+
/// Contrary to `FutureObj`, `LocalFutureObj` does not have a `Send` bound.
24+
pub struct LocalFutureObj<T> {
2425
ptr: *mut (),
25-
poll_fn: unsafe fn(*mut (), &mut Context) -> Poll<()>,
26+
poll_fn: unsafe fn(*mut (), &mut Context) -> Poll<T>,
2627
drop_fn: unsafe fn(*mut ()),
28+
_marker: PhantomData<T>,
2729
}
2830

29-
impl LocalTaskObj {
30-
/// Create a `LocalTaskObj` from a custom trait object representation.
31+
impl<T> LocalFutureObj<T> {
32+
/// Create a `LocalFutureObj` from a custom trait object representation.
3133
#[inline]
32-
pub fn new<T: UnsafeTask>(t: T) -> LocalTaskObj {
33-
LocalTaskObj {
34-
ptr: t.into_raw(),
35-
poll_fn: T::poll,
36-
drop_fn: T::drop,
34+
pub fn new<F: UnsafeFutureObj<T>>(f: F) -> LocalFutureObj<T> {
35+
LocalFutureObj {
36+
ptr: f.into_raw(),
37+
poll_fn: F::poll,
38+
drop_fn: F::drop,
39+
_marker: PhantomData,
3740
}
3841
}
3942

40-
/// Converts the `LocalTaskObj` into a `TaskObj`
41-
/// To make this operation safe one has to ensure that the `UnsafeTask`
42-
/// instance from which this `LocalTaskObj` was created actually implements
43-
/// `Send`.
44-
pub unsafe fn as_task_obj(self) -> TaskObj {
45-
TaskObj(self)
43+
/// Converts the `LocalFutureObj` into a `FutureObj`
44+
/// To make this operation safe one has to ensure that the `UnsafeFutureObj`
45+
/// instance from which this `LocalFutureObj` was created actually
46+
/// implements `Send`.
47+
#[inline]
48+
pub unsafe fn as_future_obj(self) -> FutureObj<T> {
49+
FutureObj(self)
4650
}
4751
}
4852

49-
impl fmt::Debug for LocalTaskObj {
53+
impl<T> fmt::Debug for LocalFutureObj<T> {
5054
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51-
f.debug_struct("LocalTaskObj")
55+
f.debug_struct("LocalFutureObj")
5256
.finish()
5357
}
5458
}
5559

56-
impl From<TaskObj> for LocalTaskObj {
57-
fn from(task: TaskObj) -> LocalTaskObj {
58-
task.0
60+
impl<T> From<FutureObj<T>> for LocalFutureObj<T> {
61+
#[inline]
62+
fn from(f: FutureObj<T>) -> LocalFutureObj<T> {
63+
f.0
5964
}
6065
}
6166

62-
impl Future for LocalTaskObj {
63-
type Output = ();
67+
impl<T> Future for LocalFutureObj<T> {
68+
type Output = T;
6469

6570
#[inline]
66-
fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<()> {
71+
fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<T> {
6772
unsafe {
6873
(self.poll_fn)(self.ptr, cx)
6974
}
7075
}
7176
}
7277

73-
impl Drop for LocalTaskObj {
78+
impl<T> Drop for LocalFutureObj<T> {
7479
fn drop(&mut self) {
7580
unsafe {
7681
(self.drop_fn)(self.ptr)
7782
}
7883
}
7984
}
8085

81-
/// A custom trait object for polling tasks, roughly akin to
82-
/// `Box<Future<Output = ()> + Send>`.
83-
pub struct TaskObj(LocalTaskObj);
86+
/// A custom trait object for polling futures, roughly akin to
87+
/// `Box<dyn Future<Output = T>> + Send`.
88+
pub struct FutureObj<T>(LocalFutureObj<T>);
8489

85-
unsafe impl Send for TaskObj {}
90+
unsafe impl<T> Send for FutureObj<T> {}
8691

87-
impl TaskObj {
88-
/// Create a `TaskObj` from a custom trait object representation.
92+
impl<T> FutureObj<T> {
93+
/// Create a `FutureObj` from a custom trait object representation.
8994
#[inline]
90-
pub fn new<T: UnsafeTask + Send>(t: T) -> TaskObj {
91-
TaskObj(LocalTaskObj::new(t))
95+
pub fn new<F: UnsafeFutureObj<T> + Send>(f: F) -> FutureObj<T> {
96+
FutureObj(LocalFutureObj::new(f))
9297
}
9398
}
9499

95-
impl fmt::Debug for TaskObj {
100+
impl<T> fmt::Debug for FutureObj<T> {
96101
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97-
f.debug_struct("TaskObj")
102+
f.debug_struct("FutureObj")
98103
.finish()
99104
}
100105
}
101106

102-
impl Future for TaskObj {
103-
type Output = ();
107+
impl<T> Future for FutureObj<T> {
108+
type Output = T;
104109

105110
#[inline]
106-
fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<()> {
111+
fn poll(self: PinMut<Self>, cx: &mut Context) -> Poll<T> {
107112
let pinned_field = unsafe { PinMut::map_unchecked(self, |x| &mut x.0) };
108113
pinned_field.poll(cx)
109114
}
110115
}
111116

112-
/// A custom implementation of a task trait object for `TaskObj`, providing
117+
/// A custom implementation of a future trait object for `FutureObj`, providing
113118
/// a hand-rolled vtable.
114119
///
115120
/// This custom representation is typically used only in `no_std` contexts,
@@ -118,25 +123,25 @@ impl Future for TaskObj {
118123
/// The implementor must guarantee that it is safe to call `poll` repeatedly (in
119124
/// a non-concurrent fashion) with the result of `into_raw` until `drop` is
120125
/// called.
121-
pub unsafe trait UnsafeTask: 'static {
126+
pub unsafe trait UnsafeFutureObj<T>: 'static {
122127
/// Convert a owned instance into a (conceptually owned) void pointer.
123128
fn into_raw(self) -> *mut ();
124129

125-
/// Poll the task represented by the given void pointer.
130+
/// Poll the future represented by the given void pointer.
126131
///
127132
/// # Safety
128133
///
129134
/// The trait implementor must guarantee that it is safe to repeatedly call
130135
/// `poll` with the result of `into_raw` until `drop` is called; such calls
131136
/// are not, however, allowed to race with each other or with calls to `drop`.
132-
unsafe fn poll(task: *mut (), cx: &mut Context) -> Poll<()>;
137+
unsafe fn poll(future: *mut (), cx: &mut Context) -> Poll<T>;
133138

134-
/// Drops the task represented by the given void pointer.
139+
/// Drops the future represented by the given void pointer.
135140
///
136141
/// # Safety
137142
///
138143
/// The trait implementor must guarantee that it is safe to call this
139144
/// function once per `into_raw` invocation; that call cannot race with
140145
/// other calls to `drop` or `poll`.
141-
unsafe fn drop(task: *mut ());
146+
unsafe fn drop(future: *mut ());
142147
}

src/libcore/task/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ pub use self::executor::{
2525
mod poll;
2626
pub use self::poll::Poll;
2727

28-
mod task;
29-
pub use self::task::{TaskObj, LocalTaskObj, UnsafeTask};
28+
mod future_obj;
29+
pub use self::future_obj::{FutureObj, LocalFutureObj, UnsafeFutureObj};
3030

3131
mod wake;
3232
pub use self::wake::{Waker, LocalWaker, UnsafeWake};

src/test/run-pass/async-await.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::sync::{
2121
};
2222
use std::task::{
2323
Context, Poll, Wake,
24-
Executor, TaskObj, SpawnObjError,
24+
Executor, FutureObj, SpawnObjError,
2525
local_waker_from_nonlocal,
2626
};
2727

@@ -37,7 +37,7 @@ impl Wake for Counter {
3737

3838
struct NoopExecutor;
3939
impl Executor for NoopExecutor {
40-
fn spawn_obj(&mut self, _: TaskObj) -> Result<(), SpawnObjError> {
40+
fn spawn_obj(&mut self, _: FutureObj<T>) -> Result<(), SpawnObjError> {
4141
Ok(())
4242
}
4343
}

src/test/run-pass/futures-api.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use std::sync::{
2222
use std::task::{
2323
Context, Poll,
2424
Wake, Waker, LocalWaker,
25-
Executor, TaskObj, SpawnObjError,
25+
Executor, FutureObj, SpawnObjError,
2626
local_waker, local_waker_from_nonlocal,
2727
};
2828

@@ -44,7 +44,7 @@ impl Wake for Counter {
4444
struct NoopExecutor;
4545

4646
impl Executor for NoopExecutor {
47-
fn spawn_obj(&mut self, _: TaskObj) -> Result<(), SpawnObjError> {
47+
fn spawn_obj(&mut self, _: FutureObj<()>) -> Result<(), SpawnObjError> {
4848
Ok(())
4949
}
5050
}

0 commit comments

Comments
 (0)